3 回答

TA貢獻1852條經驗 獲得超1個贊
Mongodb中一個被分片的Collection的所有數據都存放在眾多的Chunk中。一個Chunk存放分片字段的一個區間范圍的數據。選擇一個好的分片字段非常重要,否則就會遭遇到不能被拆分的大Chunk。
用上述的日志為例,如果選擇{server:1}來作為一個分片Key的話,一個server上的所有數據都是在同一個Chunk中,很容易想到一個Server上的日志數據會超過200MB(默認Chunk大?。?。如果分片Key是{server:1,time:1},那么能夠將一個Server上的日志信息進行分片,直至毫秒級別,絕對不會存在不可被拆分的Chunk。
將Chunk的規模維持在一

TA貢獻1811條經驗 獲得超6個贊
分片是MongoDB提供的一種機制,其可以將大型的集合分割保存到不同的服務器上。與其他的分區方案相比,MongoDB幾乎能自動為我們完成所有事情。只要我們進行簡單的配置,并告訴MongoDB要分配的數據,它就可以自動維護數據在不同服務器之間的平衡。同時根據需要增減服務器,MongoDB也會自動移動平移已有數據。
分片機制提供了如下三種優勢
1. 對集群進行抽象,讓集群“不可見”。
MongoDB自帶了一個叫做mongos的專有路由進程。mongos就是掌握統一路口的路由器,其會將客戶端發來的請求準確無誤的路由到集群中的一個或者一組服務器上,同時會把接收到的響應拼裝起來發回到客戶端。
2.保證集群總是可讀寫。
MongoDB通過多種途徑來確保集群的可用性和可靠性。將MongoDB的分片和復制功能結合使用,在確保數據分片到多臺服務器的同時,也確保了每分數據都有相應的備份,這樣就可以確保有服務器換掉時,其他的副本可以立即接替壞掉的部分繼續工作。
3.使集群易于擴展。
當系統需要更多的空間和資源的時候,MongoDB使我們可以按需方便的擴充系統容量。
實現數據分割
分片(shard)是集群中存儲集合數據子集的一臺或者多臺服務器。在生產環境中一個分片通常是一個副本集(replica set)。
片鍵(key),MongoDB以其作為依據來確定需要在不同分片服務器之間移動的數據。例如我們可以選擇用戶名(username)字段作為分片鍵,現有一用戶名區間[“p”,”z”],那么wufengtinghai是屬于這一區間的,那么數據最終會保存到與此區間對應的分片服務器上。
分配數據到分片服務器
分配數據到分片服務器可以使用不同的方式,了解不同的方式可以加深我們對MongoDB使用方式的理解。
一分片一區間
分配數據到分片最簡單的方式莫過于一個區間一個分片。假設我們有四個分片存儲用戶的相關信息,則我們可能會得到如下的分片和區間的對應關系。
這種分片方式非常簡單易懂,但是在一個大型繁忙的系統中卻會帶來許多的不便。假如大量的用戶使用首字母在【“a”,”f”)中的名字來注冊,這將會導致分片1比較大,因此需要將其一部分文檔移動到分片2上,我們可以調整分片1對應區間【”a”,”c”),使分片2的區間變成【”c”,”n”)。
如果移動數據后,分片2因此過載怎么辦?假設分片1和分片2各有500G數據,而分片3和分片4各自有300G數據。那么按照這個方案,最終需要一連串的復制,總共算下來需要移動400G數據,考慮到需要在集群的服務器之間移動這些數據,可見移動數據量之大。
如果需要新加分片服務器進行水平擴展呢?假設此時每個分片上都有了500G數據,那么我們現在需要將分片4上的400G數據移動到分片5,將分片3的300G數據移動到分片4,將分片2的200G數據移動到分片3,將分片1的100G數據移動到分片2,整整移動了1T的數據!
隨著分片數量和數據量的增長,這種噩夢將會持續下去,因此MongoDB不會采用這種方式。
一分片多區間
如果我們采用一分片多區間的方式,我們可以將分片1上的數據劃分為兩個區間,【”a”,”d”)包含400G數據,【”d”,”f”)包含100G數據,同樣我們也可以對分片2做類似的處理,得到區間【”f”,”j”)和【“j”,”n”)。現在我們只需要將分片1上的【”d”,”f”)數據移動到分片4,將分片2的【“j”,”n”)的數據移動到分片3。這樣我們僅僅只需要移動200G數據。
如果要添加新分片,可以從每個分片頂端取100G數據并將其移動到新的分片上,這樣僅僅只需要移動400G數據即可。
MongoDB就是利用這種方式,當一個分片的數據越來越大時,其會自動分割片鍵區間,并將分片的數據進行分割并移動到其他分片。
- 3 回答
- 0 關注
- 887 瀏覽
添加回答
舉報