用Pre-Splitting提升MongoDB Auto-Sharding效率
MongoDB 的 Auto-Sharding 一直是一個頗受爭議的特性。其理論描述非常完美,但是實際應用上卻出了很多問題,本文深入分析了Auto-Sharding的數(shù)據(jù)遷移過程,找出了影響性能的原因,并提出了作者自己的解決方案。本站簡要轉譯如下:
(更詳細的介紹請看原文:MongoDB Pre-Splitting for Faster Data Loading and Importing)
Auto-Sharding的內部機制
MongoDB 的 Sharding在存儲數(shù)據(jù)時將數(shù)據(jù)進行了分塊存儲(Chunk),每一塊的大小默認為200M。而Sharding 中每一次數(shù)據(jù)遷移的最小單元就是數(shù)據(jù)塊。
MongoDB 后臺有一個叫做Balancer的后臺程序,會檢查各個Sharding結點的分布情況,當發(fā)現(xiàn)不同結點間Chunk數(shù)相差達到一定大小時,就開始時行數(shù)據(jù)遷移,以平衡數(shù)據(jù)在各個Sharding結點的分布。
Balancer 遷移數(shù)據(jù)的過程是,先把要遷移的數(shù)據(jù)從磁盤讀到內存,再進行遷移。
但是當數(shù)據(jù)量比較大時,通常你需要遷移的數(shù)據(jù)可能并沒有被加載到內存里,這時候問題就出現(xiàn)了,你會先把內存中的熱數(shù)據(jù)踢除,以加載從磁盤讀取的需要遷移的數(shù)據(jù),然后在遷移完數(shù)據(jù)后再刪除掉原來結點上的數(shù)據(jù)。在這過程中,由于熱數(shù)據(jù)被踢回磁盤中,可能會嚴重影響性能。
解決方案-預先劃分數(shù)據(jù)區(qū)間
最后的解決方案其實相當于放棄了Auto-Sharding,而是通過MongoDB提供的 Pre-splitting 功能對數(shù)據(jù)進行預先的劃分,這需要你對自己的數(shù)據(jù)分布有一個充分的了解(我相信對數(shù)據(jù)量做一個半年到一年左右的預估來做規(guī)劃還是比較靠譜的做法),在這個基礎上為每臺機器劃分出其合適大小的sharding-key范圍,這樣就能有效的避免過多的數(shù)據(jù)遷移工作。其實這已經相當于放棄了Auto-Sharding轉而使用Manual-Sharding。
Hash Sharding
另外根據(jù)作者透露,10gen 的CTO Eliot 還表示他們正在開發(fā)一種基于Hash的Sharding策略(當前的策略基于范圍值,可以理解為btree方式),這樣可以使數(shù)據(jù)更均勻的分布,但是因為利用了Hash算法,當然也就不能提供范圍查詢這樣的功能了。想像一下相當于一個分布式的key-value存儲。好像也沒什么吸引力。
|