一 MongoDB分片介紹
1.1 分片
Mongodb另一種集群,就是分片技術,可以滿足MongoDB數據量大量增長的需求。
當MongoDB存儲海量的數據時,一台機器可能不足以存儲數據,也可能不足以提供可接受的讀寫吞吐量。這時,可通過在多台機器上分割數據,使得數據庫系統能存儲和處理更多的數據。即通過分片進行水平擴展。
延伸:
復制與分片的區別:復制時讓多台服務器都擁有同樣的數據副本,每一台服務器都是其他服務器的鏡像,而每一個分片都和其他分片擁有不同的數據子集。
1.2 為什么使用分片
- 復制所有的寫入操作到主節點
- 延遲的敏感數據會在主節點查詢
- 單個副本集限制在12個節點
- 當請求量巨大時會出現內存不足。
- 本地磁盤不足
- 垂直擴展價格昂貴
1.3 分片的優勢
分片為應對高吞吐量與大數據量提夠了方法:
- 使用分片減少了每個分片需要處理的請求數:通過水平擴展,群集可以提高自己的存儲容量。比如,當插入一條數據時,應用只需要訪問存儲這條數據的分片。
- 使用分片減少了每個分片存儲的數據:分片的優勢在於提供類似線性增長的架構,提高數據可用性,提高大型數據庫查詢服務器的性能。當MongoDB單點數據庫服務器存儲成為瓶頸、單點數據庫服務器的性能成為瓶頸或需要部署大型應用以充分利用內存時,可以使用分片技術。
二 MongoDB分片架構
2.1 主要組件
Shard:用於存儲實際的數據塊,實際生產環境中一個shard server角色可由幾台機器組個一個replica set承擔,防止主機單點故障。
Config Server:mongod實例,存儲了整個 ClusterMetadata,其中包括 chunk信息。
Query Routers:前端路由,客戶端由此接入,且讓整個集群看上去像單一數據庫,前端應用可以透明使用。
數據划分
MongoDB的數據划分,是以集合級別為標准。分片通過shard key來划分集合數據。
2.2 shard key
在集合中分發文檔,MongoDB使用shard key對進行進行分片。shard key既可以是集合的每個文檔的索引字段也可以是集合中每個文檔都有的組合索引字段。
MongoDB將shard keys值按照塊(chunks)划分,並且均勻的將這些chunks分配到各個分片上。MongoDB使用基於范圍划分或基於散列划分來划分chunks的。
注意:確定shard key時需要謹慎,以確保集群性能和效率。分片后不能更改shard key,也不能取消分片。
2.3 分片集和非分片集
數據庫可以混合使用分片和非分片集合。分片集合在集群中的分片上進行分區和分布,非分片集合存儲在主分片上,每個數據庫都有自己的主分片。
2.4 分片集連接
可以使用與連接到單個mongos相同的方式連接分片集mongod,如通過mongoshell或MongoDB 驅動程序。但必須連接到mongos路由器,才能與分片集群中的任何集合進行交互。這包括分片和非分片集合,客戶端永遠不應連接到單個分片以執行讀取或寫入操作。
三 分片策略
3.1 基於范圍划分
MongoDB通過shard key值將數據集划分到不同的范圍就稱為基於范圍划分。
對於數值型的shard key:可以虛構一條從負無窮到正無窮的直線(理解為x軸),每個shard key 值都落在這條直線的某個點上,然后MongoDB把這條線划分為許多更小的沒有重復的范圍成為塊(chunks),一個chunk就是某些最小值到最大值的范圍。
3.2 基於散列划分
MongoDB計算每個字段的hash值,然后用這些hash值建立chunks。基於散列值的數據分布有助於更均勻的數據分布,尤其是在shard key單調變化的數據集中。
但是,散列分布意味着對shard key的基於范圍的查詢不太可能以單個分片為目標,從而導致更多群集范圍的廣播操作。
基於范圍和基於散列划分的性能比較:
基於范圍划分對於范圍查詢比較高效。假設在shard key上進行范圍查詢,查詢路由很容易能夠知道哪些塊與這個范圍重疊,然后把相關查詢按照這個路線發送到僅僅包含這些chunks的分片。
但是基於范圍划分很容易導致數據不均勻分布,這樣會削弱分片集群的功能。例如當shard key是個成直線上升的字段,如時間。那么,所有在給定時間范圍內的請求都會映射到相同的chunk,也就是相同的分片上。這種情況下,小部分的分片將會承受大多數的請求,那么系統整體擴展並不理想。
相反的,基於散列划分是以犧牲高效范圍查詢為代價,它能夠均勻的分布數據,散列值能夠保證數據隨機分布到各個分片上。
3.3 自定義標簽划分
MongoDB支持通過自定義標簽標記分片的方式直接平衡數據分布策略,可以創建標簽並且將它們與shard key值的范圍進行關聯,然后分配這些標簽到各個分片上,最終平衡器轉移帶有標簽標記的數據到對應的分片上,確保集群總是按標簽描述的那樣進行數據分布。標簽是控制平衡器行為及集群中塊分布的主要方法。
四 數據均衡
新加入的數據及服務器都會導致集群數據分布不平衡,MongoDB采用兩種方式確保數據分布的平衡:
4.1 拆分
拆分是一個后台進程,防止塊變得太大。當一個塊增長到指定塊大小的時候,拆分進程就會塊一分為二,整個拆分過程是高效的。不會涉及到數據的遷移等操作。
4.2 平衡
平衡器是一個后台進程,管理塊的遷移。平衡器能夠運行在集群任何的mongd實例上。當集群中數據分布不均勻時,平衡器就會將某個分片中比較多的塊遷移到擁有塊較少的分片中,直到數據分片平衡為止。
舉個例子:如果集合users有100個塊在分片1里,50個塊在分片2中,那么平衡器就會將分片1中的塊遷移到分片2中,直到維持平衡。
分片采用后台操作的方式管理着源分片和目標分片之間塊的遷移。在遷移的過程中,源分片中的塊會將所有文檔發送到目標分片中,然后目標分片會獲取並應用這些變化。最后,更新配置服務器上關於塊位置元數據。
4.3 從集群中增加和刪除分片
添加新分片到集群中會產生數據不平衡,因為新分片中沒有塊,當MongoDB開始遷移數據到新分片中時,等到數據分片平衡需要一定時間。
當刪除一個分片時,平衡器將會把分片中所有塊遷移到另一個分片中,在完成這些遷移並更新元數據后,才可安全的刪除分片了。
更多分片參考官方:https://docs.mongodb.com/manual/sharding/#sharding-strategy
相關參考:
https://blog.51cto.com/13643643/2148825
https://www.cnblogs.com/Jtianlin/p/5128977.html
https://www.jianshu.com/p/cb55bb333e2d