MongoDB有三大核心優(yōu)勢(shì):【靈活模式】+【高可用性】+【可擴(kuò)展性】,通過(guò)JSON文檔來(lái)實(shí)現(xiàn)靈活模式,通過(guò)復(fù)制集(replica set)保證高可用,通過(guò)sharded cluster來(lái)保證可擴(kuò)展性。下面我們就來(lái)詳細(xì)說(shuō)一下mongodb sharded cluster。
-
為什么需要shard cluster?
當(dāng)MondoDB復(fù)制集遇到下面的業(yè)務(wù)場(chǎng)景時(shí),就需要考慮使用sharded Cluster:- 存儲(chǔ)容量需求超過(guò)單機(jī)的磁盤(pán)容量
- 讀寫(xiě)能力受單機(jī)限制(讀能力也可以在復(fù)制集里加 secondary 節(jié)點(diǎn)來(lái)擴(kuò)展),可能是 CPU、內(nèi)存或者網(wǎng)卡等資源遭遇瓶頸,導(dǎo)致讀寫(xiě)能力無(wú)法擴(kuò)展。
sharded Cluster使得集合的數(shù)據(jù)分散到多個(gè)shard(復(fù)制集或者單個(gè)mongodb節(jié)點(diǎn))存儲(chǔ),使得mongodb具備了橫向擴(kuò)展的能力。如下圖:

-
具體的mongodb sharded cluster的架構(gòu)如下圖:
mongodb sharded cluster.png- [shard] : 每個(gè)shard是已經(jīng)分片的數(shù)據(jù)的子集。從3.6版本開(kāi)始,每個(gè)shard必須部署成復(fù)制集(replica set,不能是單個(gè)mongodb節(jié)點(diǎn))。
- [mongos-router] : mongos是一個(gè)查詢路由器的角色, 提供了mongo client訪問(wèn)sharded cluster的接口,為了支持高可用性,可以部署多個(gè)mongos,常見(jiàn)的是一臺(tái)應(yīng)用服務(wù)器上部署一個(gè)mongos,這樣可以減少client到router之間的網(wǎng)絡(luò)延時(shí)。
- [config servers] : config server存儲(chǔ)了cluster的元數(shù)據(jù)以及配置數(shù)據(jù),從3.4版本開(kāi)始config server也必須部署為復(fù)制集(replica set)。
-
數(shù)據(jù)分布策略
Sharded cluster支持將單個(gè)集合的數(shù)據(jù)分散存儲(chǔ)在多個(gè)shard上,用戶可以指定根據(jù)集合內(nèi)文檔的某個(gè)字段即shard key來(lái)分布數(shù)據(jù),目前主要支持2種數(shù)據(jù)分布的策略,范圍分片(Range based sharding)或hash分片(Hash based sharding)。-
范圍分片:能夠很好的支持基于shard key的范圍查詢。
范圍分片
如上圖所示使用x字段進(jìn)行范圍分片,將整個(gè)取值范圍劃分為多個(gè)chunk,每個(gè)chunk(通常配置為64M,一個(gè)chunk只會(huì)存在于一個(gè)shard上,每個(gè)chunk的配置信息保存在config server中,當(dāng)查詢或者保存的時(shí)候,mongos會(huì)根據(jù)shard key的計(jì)算出應(yīng)該到那個(gè)shard上查詢或者保存數(shù)據(jù)。)包含一小段數(shù)據(jù)。
-
hash分片:通常能夠?qū)?xiě)入均衡的分布到各個(gè)shard。
hash分片是根據(jù)shard key計(jì)算hash 值(64bit整型),根據(jù)hash值按照【范圍分片】的策略將文檔分布到不同的chunk。
hash分片
Hash分片與范圍分片互補(bǔ),能將文檔隨機(jī)的分散到各個(gè)chunk,充分的擴(kuò)展寫(xiě)能力,彌補(bǔ)了范圍分片的不足,但不能高效的服務(wù)范圍查詢,所有的范圍查詢要分發(fā)到后端所有的Shard才能找出滿足條件的文檔。
-
-
選擇shard key時(shí)要注意下面幾個(gè)問(wèn)題:
- shard key取值范圍太小,比較GPS位置的表中車牌號(hào)作為shard key會(huì)導(dǎo)致分片的效果不佳,因?yàn)檐嚺铺?hào)范圍太小,不夠分散。
- shard key 某個(gè)值的文檔特別多,這樣導(dǎo)致單個(gè) chunk 特別大(即jumbo chunk),會(huì)影響chunk 遷移及負(fù)載均衡。就如第一個(gè)問(wèn)題中所說(shuō)的使用車票號(hào)作為shard key進(jìn)行范圍分片,就會(huì)導(dǎo)致單個(gè)chunk特別大,同一個(gè) 車牌號(hào)對(duì)應(yīng)的數(shù)據(jù)無(wú)法進(jìn)一步細(xì)分,只能分散到同一個(gè) chunk,會(huì)造成 jumbo chunk
- 根據(jù)非 shard key 進(jìn)行查詢、更新操作都會(huì)變成 scatter-gather 查詢,影響效率。因此要使用業(yè)務(wù)中常用的查詢field作為shard key。


