1. 程式人生 > >Redis——10叢集—— 10.1Redis叢集之資料分佈理論

Redis——10叢集—— 10.1Redis叢集之資料分佈理論

10.1.1 資料分佈理論
分散式資料庫首先要解決把整個資料集按照分割槽規則對映到多個節點的問題, 即把資料集劃分到多個節點上, 每個節點負責整體資料的一個子集。如圖10-1所示。需要重點關注的是資料分割槽規則。 常見的分割槽規則有雜湊分割槽和順序分割槽兩種, 表10-1對這兩種分割槽規則進行了對比。

                                                                 表10-1 雜湊分割槽和順序分割槽對比


由於Redis Cluster採用雜湊分割槽規則, 這裡我們重點討論雜湊分割槽, 常見的雜湊分割槽規則有幾種, 下面分別介紹。
1.節點取餘分割槽

使用特定的資料, 如Redis的鍵或使用者ID, 再根據節點數量N使用公式:hash( key) %N計算出雜湊值, 用來決定資料對映到哪一個節點上。 這種方案存在一個問題: 當節點數量變化時, 如擴容或收縮節點, 資料節點對映關係需要重新計算, 會導致資料的重新遷移。
這種方式的突出優點是簡單性, 常用於資料庫的分庫分表規則, 一般採用預分割槽的方式, 提前根據資料量規劃好分割槽數, 比如劃分為512或1024張表, 保證可支撐未來一段時間的資料量, 再根據負載情況將表遷移到其他資料庫中。 擴容時通常採用翻倍擴容, 避免資料對映全部被打亂導致全量遷移的情況, 如圖10-2所示。
2.一致性雜湊分割槽

一致性雜湊分割槽( Distributed Hash Table) 實現思路是為系統中每個節點分配一個token, 範圍一般在0~2的32次方, 這些token構成一個雜湊環。 資料讀寫執行節點查詢操作時, 先根據key計算hash值, 然後順時針找到第一個大於等於該雜湊值的token節點, 如圖10-3所示。



這種方式相比節點取餘最大的好處在於加入和刪除節點隻影響雜湊環中相鄰的節點, 對其他節點無影響。 但一致性雜湊分割槽存在幾個問題:
·加減節點會造成雜湊環中部分資料無法命中, 需要手動處理或者忽略這部分資料, 因此一致性雜湊常用於快取場景。
·當使用少量節點時, 節點變化將大範圍影響雜湊環中資料對映, 因此這種方式不適合少量資料節點的分散式方案。
·普通的一致性雜湊分割槽在增減節點時需要增加一倍或減去一半節點才能保證資料和負載的均衡。
正因為一致性雜湊分割槽的這些缺點,一些分散式系統採用虛擬槽對一致性雜湊進行改進, 比如Dynamo系統。
3.虛擬槽分割槽

虛擬槽分割槽巧妙地使用了雜湊空間, 使用分散度良好的雜湊函式把所有資料對映到一個固定範圍的整數集合中, 整數定義為槽( slot) 。 這個範圍一般遠遠大於節點數, 比如Redis Cluster槽範圍是0~16383。 槽是叢集內資料管理和遷移的基本單位。 採用大範圍槽的主要目的是為了方便資料拆分和叢集擴充套件。 每個節點會負責一定數量的槽, 如圖10-4所示。當前叢集有5個節點, 每個節點平均大約負責3276個槽。 由於採用高質量的雜湊演算法, 每個槽所對映的資料通常比較均勻, 將資料平均劃分到5個節點進行資料分割槽。 Redis Cluster就是採用虛擬槽分割槽, 下面就介紹Redis資料分割槽方法。

10.1.2 Redis資料分割槽
Redis Cluser採用虛擬槽分割槽, 所有的鍵根據雜湊函式對映到0~16383整數槽內, 計算公式: slot=CRC16( key) &16383。 每一個節點負責維護一部分槽以及槽所對映的鍵值資料, 如圖10-5所示。


Redis虛擬槽分割槽的特點:
·解耦資料和節點之間的關係, 簡化了節點擴容和收縮難度。
·節點自身維護槽的對映關係, 不需要客戶端或者代理服務維護槽分割槽元資料。
·支援節點、 槽、 鍵之間的對映查詢, 用於資料路由、 線上伸縮等場景。

資料分割槽是分散式儲存的核心, 理解和靈活運用資料分割槽規則對於掌握Redis Cluster非常有幫助。

10.1.3 叢集功能限制
Redis叢集相對單機在功能上存在一些限制, 需要開發人員提前瞭解,在使用時做好規避。 限制如下:
1) key批量操作支援有限。 如mset、 mget, 目前只支援具有相同slot值的key執行批量操作。 對於對映為不同slot值的key由於執行mget、 mget等操作可能存在於多個節點上因此不被支援。
2) key事務操作支援有限。 同理只支援多key在同一節點上的事務操作, 當多個key分佈在不同的節點上時無法使用事務功能。
3) key作為資料分割槽的最小粒度, 因此不能將一個大的鍵值物件如hash、 list等對映到不同的節點。
4) 不支援多資料庫空間。 單機下的Redis可以支援16個數據庫, 叢集模式下只能使用一個數據庫空間, 即db0。
5) 複製結構只支援一層, 從節點只能複製主節點, 不支援巢狀樹狀複製結構。