對于Share-Nothing架構的分布式數據庫來說,如何將數據均勻的分布到各個節(jié)點、在線擴容,以獲取更大的存儲容量和更高的并發(fā)訪問量,成為各大分布式數據庫系統(tǒng)的一大挑戰(zhàn),今天我將對騰訊云數據庫TBase的數據節(jié)點在線擴容方案做一個簡單的分享。
為了迎接業(yè)務的快速增長,系統(tǒng)不可避免的需要進行擴容,傳統(tǒng)的分布式數據庫所采用hash(row)%nofdn,也就是說先對分布列計算hash值,然后使用這個值對節(jié)點個數取模來決定row存儲在哪個節(jié)點。這里有一個致命的問題,擴容后節(jié)點數會變多,數據分布的計算邏輯會導致已經存在的數據無法正常訪問。為解決這個問題,傳統(tǒng)的分布式數據庫必須把業(yè)務停掉,把所有數據導出,擴容后重新導入,在數據量較多時,這個過程可能會持續(xù)幾天,這對于7*24小時的交易系統(tǒng)來說顯然是不能接受的。為了解決這個問題,TBase引入了一種新的分表方案:sharded table。
TBase的數據分布采用如下的方式:
1.引入一個中間層shard map,shard map中存儲每一項shardid【通過hash(key)計算,key表示分布式鍵值】和DN的映射關系。
2.分布式表中的每條記錄通過hash(key)%#shardmap來決定記錄存儲到哪個數據節(jié)點。
3.每個數據節(jié)點上存儲分配到本節(jié)點的shardid信息,進而進行可見性判斷。
如下圖所示,當hash(key)=1時,此行數據會存放在DN001數據節(jié)點,當hash(key)=2時,此行數據存儲在DN002數據節(jié)點上,以此類推。
這樣做有什么好處呢?比如我們向default_group中新增加節(jié)點時,我們只需要把一些shardmap中的id映射到新加的節(jié)點,并把對應的數據遷移過去就可以了。
如下圖所示,向default_group中新增數據節(jié)點DN003,那么只需要把DN001中的shardid=1和DN002中的shardid=4的數據遷移到DN003中,就可以實現(xiàn)數據的重新分布,并達到節(jié)點間數據平衡。
TBase的在線擴容過程:
1.選擇要遷移到新添加數據節(jié)點的shardid。
2.通過shardid找到要遷移的數據,采取存量+增量的方式把數據遷移到新的數據節(jié)點。
3.當新節(jié)點中的數據和數據源的數據達到一致時,切換協(xié)調節(jié)點(CN)中的shardmap信息,把shardid=3,shardid=4映射到DN003中(shardmap切換時數據庫集群處于只讀狀態(tài),該操作會在秒級完成)。
4.數據清理,釋放空間。如上圖所示,清理DN001中shardid=3和DN002中shardid=4的數據。