MongoDB中的Primary Shard詳解
什么是Primary Shard
在MongoDB的Sharding架構(gòu)中,每個(gè)database中都可以存儲(chǔ)兩種類型的集合,一種是未分片的集合,一種是通過(guò)分片鍵,被打散的集合。被分片鍵打散的集合數(shù)據(jù)可以均勻的分布在各個(gè)分片上;而對(duì)于未分片的集合,則只會(huì)存儲(chǔ)在所在的database的Primary Shard中,每個(gè)database有且只有一個(gè)Primary Shard。簡(jiǎn)單來(lái)說(shuō)就是,Primary Shard存儲(chǔ)了當(dāng)前數(shù)據(jù)庫(kù)未分片的集合。示意圖如下:
其中Collection I為分片集合,數(shù)據(jù)被打散到不同的分片上。Collection 2作為未分片集合所有的所有都只存儲(chǔ)在Primary Shard中,這里它的Primary Shard為Shard A。
Primary Shard的選擇及問(wèn)題
當(dāng)我們通過(guò)mongos創(chuàng)建一個(gè)database時(shí),mongos會(huì)根據(jù)當(dāng)前每個(gè)分片中存儲(chǔ)的數(shù)據(jù)量來(lái)決定哪個(gè)分片為當(dāng)前數(shù)據(jù)庫(kù)的Primary Shard,存儲(chǔ)數(shù)據(jù)量最少的作為當(dāng)前數(shù)據(jù)庫(kù)的主分片。數(shù)據(jù)量判斷依據(jù)為listDatabases命令中的totalSize的值。
比如我們新建一個(gè)test1庫(kù),并在里面創(chuàng)建一個(gè)未分片的集合,mongos為它挑選的Primary Shard為shard2:
[direct: mongos] test> use test1; switched to db test1 [direct: mongos] test1> db.foo.insertOne({"name":"aaa"}); { acknowledged: true, insertedId: ObjectId("66c6f060b47ae218b4ef12aa") } [direct: mongos] test1> sh.status() ... { database: { _id: 'test1', primary: 'shard2', partitioned: false, version: { uuid: new UUID("a419673b-944b-4cdd-8d11-f3074bbf43fb"), timestamp: Timestamp({ t: 1724313695, i: 1 }), lastMod: 1 } }, collections: {} }
Primary Shard自動(dòng)選擇存在的問(wèn)題
問(wèn)題一
假設(shè)有如下需求:有兩個(gè)專門存儲(chǔ)配置集合的database,由于是配置集合,所有數(shù)據(jù)量比較小,不需要再將其數(shù)據(jù)打散,但是為了方面管理,需要將這兩個(gè)配置庫(kù)存放在同一個(gè)分片中。換句話說(shuō)就是這兩個(gè)配置庫(kù)的Primary Shard需要為同一個(gè)。
我們知道,mongos在選擇Primary Shard的時(shí)候是根據(jù)當(dāng)前各個(gè)分片現(xiàn)有的數(shù)據(jù)量來(lái)決定的,但是如果當(dāng)前各個(gè)分片的數(shù)據(jù)量都比較均衡,當(dāng)我們的業(yè)務(wù)數(shù)據(jù)在持續(xù)變動(dòng)的過(guò)程中,mongos在選擇Primary Shard的時(shí)候就會(huì)表現(xiàn)出隨機(jī)性--先后創(chuàng)建的database的Primary Shard極有可能會(huì)是不同的分片。
問(wèn)題二
假設(shè)目前需要有一個(gè)日志庫(kù),然后每個(gè)月都會(huì)以月份為后綴進(jìn)行切庫(kù),就是說(shuō)6月份的話我會(huì)創(chuàng)建一個(gè)叫DB_202406的庫(kù),7月份的話會(huì)創(chuàng)建一個(gè)叫做DB_202407的庫(kù),集合的月增量為1個(gè)T。由于增量比較大,后面肯定是需要不斷加機(jī)器擴(kuò)容的,當(dāng)單臺(tái)服務(wù)器的磁盤IO能力不是瓶頸的情況下,為了后期加機(jī)器擴(kuò)容時(shí)不需要進(jìn)行歷史數(shù)據(jù)的均衡,所以日志集合的選擇了未分片。那么當(dāng)我進(jìn)行月底切庫(kù),即創(chuàng)建新庫(kù)的時(shí)候,mongos就會(huì)判斷各個(gè)分片上的現(xiàn)有數(shù)據(jù)量,然后找一個(gè)數(shù)據(jù)量相對(duì)較小的分片作為Primary Shard,此時(shí),如果各個(gè)分片的服務(wù)器磁盤并不是相同大小的,比如說(shuō)A分片的磁盤大小為10T,B分片磁盤的大小為5T,但是A分片存儲(chǔ)的數(shù)據(jù)為4.8T,B分片存儲(chǔ)的數(shù)據(jù)為4.5T,這時(shí)候由于B分片上存儲(chǔ)的數(shù)據(jù)少,mongos會(huì)將B分片選為新庫(kù)的Primary Shard,但是實(shí)際情況是B分片所在的主機(jī)空閑空間已經(jīng)完全不足以支持本月的月增數(shù)據(jù)量了,后面就只能臨時(shí)擴(kuò)容本機(jī)或刪數(shù)據(jù)或?qū)?shù)據(jù)在線同步遷移到有足夠空間的新機(jī)器上,并進(jìn)行應(yīng)用切換。
如何解決
針對(duì)上面存在的兩個(gè)問(wèn)題,根本原因還是由于在新建庫(kù)后,mongs自動(dòng)為當(dāng)前庫(kù)選擇的Primary Shard可能會(huì)出現(xiàn)不合理性,所以我們?cè)谶M(jìn)行建庫(kù)的時(shí)候,最好的辦法是直接指定新庫(kù)的Primary Shard,這樣就可以規(guī)避掉上面兩個(gè)問(wèn)題。而且針對(duì)第二個(gè)問(wèn)題,還需要做的是當(dāng)業(yè)務(wù)上線前需要做好的架構(gòu)規(guī)劃和容量規(guī)劃等。
建庫(kù)后指定當(dāng)前庫(kù)的Primary Shard:
[direct: mongos] test> use DB1 switched to db DB1 [direct: mongos] DB1> sh.enableSharding("DB1","shard1") { ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1724317769, i: 3 }), signature: { hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0), keyId: Long("0") } }, operationTime: Timestamp({ t: 1724317769, i: 1 }) } [direct: mongos] DB1> sh.status() ... { database: { _id: 'DB1', primary: 'shard1', partitioned: false, version: { uuid: new UUID("ec0e50b8-3029-4333-887b-9ca0b54c4e20"), timestamp: Timestamp({ t: 1724317768, i: 1 }), lastMod: 1 } }, collections: {} }
只能在use新庫(kù)之后,立即指定新庫(kù)的Primary Shard,不能等創(chuàng)建過(guò)集合并寫入數(shù)據(jù)之后再指定,因?yàn)槟菚r(shí)mongos已經(jīng)為新庫(kù)選好了Primary Shard,就不支持再次修改了
[direct: mongos] DB1> sh.enableSharding("DB1","shard3") MongoServerError: Database DB1 could not be created :: caused by :: database already created on a primary which is different from shard1
到此這篇關(guān)于MongoDB中的Primary Shard的文章就介紹到這了,更多相關(guān)MongoDB Primary Shard內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MongoDB安裝及接入springboot的詳細(xì)過(guò)程
MongoDB是一個(gè)開(kāi)源、高性能、無(wú)模式(模式自由)的文檔(Bson)型數(shù)據(jù)庫(kù),這篇文章主要介紹了MongoDB安裝及接入springboot,需要的朋友可以參考下2024-05-05Mongodb數(shù)據(jù)庫(kù)兩種啟動(dòng)方法小結(jié)
MongoDB是一種開(kāi)源的服務(wù)器端NoSQL數(shù)據(jù)庫(kù)管理系統(tǒng),它提供了一種靈活的框架,可以快速地存儲(chǔ)、處理和管理大量的數(shù)據(jù),這篇文章主要給大家介紹了關(guān)于Mongodb數(shù)據(jù)庫(kù)兩種啟動(dòng)方法的相關(guān)資料,需要的朋友可以參考下2023-12-12mongodb中根據(jù)時(shí)間過(guò)濾進(jìn)行查詢的操作方法
這篇文章主要介紹了mongodb中簡(jiǎn)單的根據(jù)時(shí)間過(guò)濾進(jìn)行查詢,文末補(bǔ)充介紹了如何根據(jù)日期過(guò)濾/查找MongoDB中的記錄,結(jié)合實(shí)例給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05MongoDB數(shù)據(jù)去重與保存最新數(shù)據(jù)操作指南
在 MongoDB 數(shù)據(jù)庫(kù)中,我們經(jīng)常需要進(jìn)行數(shù)據(jù)去重并保留最新的數(shù)據(jù),本文將介紹如何使用 MongoDB 聚合操作完成這一任務(wù),并將結(jié)果保存到新的集合或者覆蓋原有的集合,感興趣的小伙伴跟著小編一起來(lái)看看吧2024-01-01解決net start MongoDB 報(bào)錯(cuò)之服務(wù)名無(wú)效的問(wèn)題
這篇文章主要介紹了解決net start MongoDB 報(bào)錯(cuò)之服務(wù)名無(wú)效的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12MongoDB進(jìn)階之動(dòng)態(tài)字段設(shè)計(jì)詳解
這篇文章主要給大家介紹了MongoDB進(jìn)階之動(dòng)態(tài)字段設(shè)計(jì)的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。2017-06-06