MongoDB 分片鍵的選擇與案例

2021-09-07 18:33:06 字數 3947 閱讀 7663

mongodb版本:3.6 

公升序片鍵例如:日期時間字段、自增字段。

隨機分發片鍵例如:使用者名稱、郵件名、uuid、md5值或者是其它的一些沒有規律的值的列。

建立分片時,只在主分片上建立了乙個塊 } -->> } on : rs-a timestamp(1, 0)。

至少得3個不同的值才會進行塊切分,相同的值只會在乙個分片塊中。比如對乙個name欄位進行範圍分割槽,如果一直往name欄位插入"a",那麼它會一直儲存主分片的 } -->> }中,直到name出現三個不同的值,比如「a」,「b」,「c」這個時候就會進行分片。當然這只是測試,現實中不會對這種粗粒度的字段單獨做分片。

建立分片時,預設在每個分片上建立了兩個資料塊。但是當前每個塊上面是沒有資料的。

組合分片是比較好的一種分片的選擇,好的組合分片可以同時解決熱點和隨機讀io問題。例如:

sh.shardcollection("

test.bbbb

",);

比如對於一些日誌非查詢文件,可以通過標籤將其只插入到某個分片中。例如

sh.addtagrange("

test.log

", }, },"

tag_rs-a

");

可以在config庫中的tag文件中檢視設定的標籤資訊。

use config

db.tags.find();

可以通過標籤將特定範圍的資料在指定的分片中。

將 -->> 範圍的資料儲存到rs-a的分片上,這部分資料跨越了兩個資料塊。

資料 -->> 已經被移動到了rs-a分片上。

分片策略沒有絕對的好壞,針對不同的業務場景選擇不同的分片策略。

1.所有的分片讀寫都均勻。

2.資料訪問均勻,而不是隨機性的訪問;由於新資料都是先在記憶體中建立,盡量避免需要從磁碟訪問新資料。

3.盡量避免由於資料塊的資料移動導致資料從磁碟載入到記憶體中從而導致熱資料被清理出記憶體。

4.組合字段分片可能會是理想的分片方案。

分片鍵公式:

coarselocality:應該是乙個大粒度的區域性字段。比如month月份公升序字段。

search:是乙個經常用來查詢的字段。

案例1.使用日期字段、自增字段、時間戳分片的問題

有乙個**瀏覽記錄表,表中有乙個createtime欄位用來記錄每天記錄的插入時間。

對於這類文件不太適合使用createtime字段作為分片字段,因為讀寫可能都會集中在最新的分片上。使用自增字段也存在同樣的問題

案例2.大粒度字段分片問題

有乙個五大洲的使用者文件表,表中有乙個continent字段儲存使用者所在洲。

如果使用continent作為分片欄位會存在以下幾個問題:

1.分片的粒度太大了,會導致最後每乙個分片的資料都非常的大而且沒有再分的可能。而且也有可能會導致磁碟空間不夠的情況。

2.可能會導致某個分片在某個時間點的訪問量遠遠大於其他分片。

案例3:使用月份和使用者名稱進行組合分片

有乙個使用者操作記錄集合,業務需要查詢使用者最近乙個月操作記錄。集合有month,username鍵

使用分片情景如下:

month保證熱資料優於記憶體。

username:保證資料的隨機性,避免集中過熱問題。

存在的問題:對於新文件由於很多月份還不存在,會導致新資料都是往最後乙個分片上面插入資料,存在熱讀寫問題,最後通過均衡器對資料塊進行移動。

資料測試

sh.shardcollection("test.news",);

----插入1月資料10萬記錄

----插入2月資料10萬記錄

for(var i=100000;i<200000;i++))}
新資料往一直往最末尾的分片(rs-a)上插,因為這個時候"month":2在最大的分片上。 -->> , "username" : } on : rs-a timestamp(3, 1)

資料插入完之後均衡器將rs-c上的乙個塊分給了rs-a

----插入全部月份資料。

保證每個月的資料都均勻的分布到不同的分片上,並且隨著時間的推移舊的資料可能就不會被使用也不會被移動。

注意:這個案例比較特殊,因為對於日誌集合比較舊的資料基本上是不會被查詢的,所以借助了month鍵作為了分片鍵保證了熱資料優先儲存於記憶體,對於整張表都是熱資料比如登入使用者集合就不適合這種分片方式,hashed會更適合。

案例4:使用佇列

佇列不僅在容災中非常的有用,而且在常規的突發流量下也非常的有用。佇列可以吸收短時間內爆發的大量請求。也可以把佇列反過來用,即快取mongodb返回的結果。

比如:rabbitmq

案例5:使用使用者名稱和建立時間進行組合分片

使用者名稱:保證資料的隨機性,避免熱點問題

1.集合的鍵數量應該是固定的,包括巢狀文件的數量都應該提前規劃好。

2.盡量都是做原子更新,而不是某個鍵的值受其它鍵值更新的影響。比如num1,num2,total如果num鍵的值是經常會被更新的那麼這種設計就不好,因為total也要對應跟著變,而mongodb本身計算能力就很弱。

備註:pursuer.chen

部落格:《歡迎交流討論》

MongoDB集群分片及片鍵的選擇

1 因為專案所需,此處有六張表,分別是czgx ljgx qjjd sj wl wnjd這六張表,所用的片鍵選擇為 czgx 承載關係編號,時間,id qjjd 全域性節點編號,時間,id sj 網路層級,事件開始時間,id wl 網路編號,時間,id wnjd 網內節點編號,時間,id 2 在集群...

MongoDB的分片測試

分片結構埠分布如下 shard server 1 27020 shard server 2 27021 shard server 3 27022 shard server 4 27023 config server 27100 route process 40000 1.正確安裝mongodb 2....

mongodb 分片集群的坑

一 config的時候不 配置檔案中configsvr一定要 如果啟動失敗,看看是不是安裝config的時候是直接複製的正在執行的mongodb例項 二 route伺服器啟動 直接.mongos命令 config伺服器的副本集名稱 rscfg 一定要記得 否則報 沒有副本的錯 這時候db.runco...