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