天天看點

看完這篇Redis-Cluster,穩拿30W年薪大廠offer(上)1 叢集的意義2 meet3 指派槽4 叢集伸縮

1 叢集的意義

Redis叢集不斷發展,可實作在多台機器,部署多執行個體,每個執行個體存部分資料。

同時每個執行個體可以帶上Redis從執行個體,保證若Redis主執行個體挂了,自動切換到redis從執行個體。

上古時代,很多用codis之類用戶端支援叢集。現在版本大家都用Redis cluster,即官方提供的叢集模式,必須深入研究了。

從單機的一主多從複制架構到現在的分布式架構

看完這篇Redis-Cluster,穩拿30W年薪大廠offer(上)1 叢集的意義2 meet3 指派槽4 叢集伸縮

主要有如下次元:

業務

追求更高QPS

資料量

Scale Up已經無法滿足,超過了單機極限,考慮Scale Out分布式。

Redis記憶體淘汰政策,保證不可能超過master節點記憶體門檻值。master節點資料和slave節點的資料保持一緻。

一個redis即可橫向擴容了。若要支撐更大資料緩存,就橫向擴容更多master節點,每個master節點就能存放更多資料。單台伺服器32G,30台即可達1TB。

網絡流量

業務流量超過伺服器網卡上限,考慮分布式分流

離線計算

需要中間環節緩沖等需求

2 meet

節點之間完成互相通信的基礎,有一定的頻率和規則。

CLUSTER MEET指令被用來連接配接不同的開啟叢集支援的 Redis 節點,以進入工作叢集。

2.1 基本思想

每個節點預設互不信任,并且被認為是未知節點,以防系統管理錯誤或位址被修改,而不太可能将多個不同的叢集節點混成一個叢集。

是以,為了使給定節點能将另一個節點接收到組成 Redis Cluster 的節點清單中,這裡隻有兩種方法:

系統管理者發送一個CLUSTER MEET指令強制一個節點會見另一個節點

一個已知節點發送一個儲存在 gossip 部分的節點清單,包含着未知節點。如果接收的節點已經将發送節點信任為已知節點,它會處理 gossip 部分并且發送一個握手消息給未知的節點。

Redis Cluster 需要形成一個完整的網絡(每個節點都連接配接着其他每個節點),但為建立一個叢集,不需要發送形成網絡所需的所有CLUSTER MEET指令。發送CLUSTER MEET消息以便每個節點能夠到達其他每個節點隻需通過一條已知的節點鍊就夠了。由于在心跳包中會交換 gossip 資訊,将會建立節點間缺失的連結。

是以,如果我們通過CLUSTER MEET連結節點 A 和 B ,并且 B 和 C 有連結,那麼節點 A 和 C 會發現他們握手和建立連結的方法。

2.2 案例

假設某一叢集有A、B、C、D四個節點,可以隻發送以下一組指令給 A :

CLUSTER MEET B-ip B-port
CLUSTER MEET C-ip C-port
CLUSTER MEET D-ip D-port      

由于 A 知道及被其他所有節點知道,它将會在發送的心跳包中包含gossip部分,這将允許其他每個節點彼此都建立一個連結,即使叢集很大,也能在數秒内形成一個完整網絡。

CLUSTER MEET無需互相執行,即若發送指令給 A 以加入B ,那就不必也發送給 B 以加入 A。

2.3 實作細節:MEET 和 PING 包

當某一給定節點接收到一個MEET消息時,指令中指定的節點仍不知發送了該指令,是以為使節點強制将接收指令的節點将它作為信任的節點接受它,它會發送MEET包而非PING包。兩個消息包有相同的格式,但是MEET強制使接收消息包的節點确認發送消息包的節點為可信任的。

3 指派槽

把16384個槽平分給節點管理,每個節點隻對自己負責的槽進行讀寫。

看完這篇Redis-Cluster,穩拿30W年薪大廠offer(上)1 叢集的意義2 meet3 指派槽4 叢集伸縮

每個節點間都互相通信,是以每個節點都知道其它節點所管理槽的範圍

看完這篇Redis-Cluster,穩拿30W年薪大廠offer(上)1 叢集的意義2 meet3 指派槽4 叢集伸縮

用戶端與指派槽

看完這篇Redis-Cluster,穩拿30W年薪大廠offer(上)1 叢集的意義2 meet3 指派槽4 叢集伸縮

4 叢集伸縮

叢集的伸縮包括新節點的加入和舊節點退出。

4.1 加入新節點

  1. 準備新節點

    啟動一個叢集模式下的Redis節點

  2. 加入叢集

    通過與任意一叢集中的節點握手加入新節點

  3. 遷移slot到新節點

    再向新節點配置設定它負責的slot并向其遷移slot對應資料。

  4. 由于Redis采用Gossip協定,是以可讓新節點與任一現有叢集節點握手,一段時間後整個叢集都會知道加入了新節點。

4.1.1 案例

向如下叢集中新加入一個節點6385。由于負載均衡的要求,加入後四個節點每個節點負責4096個slots,但叢集中原來的每個節點都負責5462個slots,是以6379、6380、6381節點都需要向新的節點6385遷移1366個slots。

Redis叢集并沒有一個自動實作負載均衡的工具,把多少slots從哪個節點遷移到哪個節點完全是由使用者指定。

看完這篇Redis-Cluster,穩拿30W年薪大廠offer(上)1 叢集的意義2 meet3 指派槽4 叢集伸縮
看完這篇Redis-Cluster,穩拿30W年薪大廠offer(上)1 叢集的意義2 meet3 指派槽4 叢集伸縮

遷移資料的流程圖

看完這篇Redis-Cluster,穩拿30W年薪大廠offer(上)1 叢集的意義2 meet3 指派槽4 叢集伸縮
  • 遷移key可以用pipeline進行批量的遷移。

對于擴容,原理已經很清晰了,至于具體操作,網上很多。

至于縮容,也是先手動完成資料遷移,再關閉redis。收縮時如果下線的節點有負責的槽需要遷移到其他節點,再通過cluster forget指令讓叢集内所有節點忘記被下線節點