一 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