知道 Redis-Cluster 麼?說說其中可能不可用的情況

乾貨滿滿張雜湊發表於2021-02-02

Redis 叢集模式簡述

一個叢集模式的官方推薦最小最佳實踐方案是 6 個節點,3 個 Master 3 個 Slave 的模式,如 圖00 所示。

image

key 分槽與轉發機制

Redis 將鍵空間分為了 16384 個槽,通過以下演算法確定每一個 key 的槽:

CRC16(key) mod 16384

由於 16384 = 2 的 14 次方,對一個 2 的 n 次方取餘相當於對於它的 2 的 n 次方減一取與運算。所以優化為:

CRC16(key) & 16383

當 key 包含 hash tags 的時候(例如 key{sub}1),會以 sub tags 中指定的字串(就是 sub )計算槽,所以key{sub}1key{sub}2會到同一個槽中。

客戶端可以傳送讀取任一個槽的命令到任一個叢集例項,當槽屬於請求的例項的時候,就會處理,否則會告訴客戶端這個槽在哪裡,例如如果將下面命令發到第二個 Master:

GET key1
返回: MOVED slot ip:port(第一個Master的) 

預設情況下,所有的讀寫命令只能傳送到 Master。如果需要使用 Slave 處理讀請求,需要先在客戶端執行 readonly 命令。

主從自動切換機制

當一個 Master 發生故障,如果有 Slave,則會切換為 Master。

如何判斷 Master 發生故障了呢?Redis 叢集配置中有一個配置,cluster-node-timeout叢集心跳超時時間。當叢集內節點建立連線後,定時任務 clusterCron 函式(參考原始碼:https://github.com/redis/redis/blob/6.0/src/cluster.c)會每隔一秒隨機選擇一個節點傳送心跳。如果在超時時間(cluster-node-timeout)的時間內未收到心跳響應,則將這個節點標記為 pfail。

如果叢集中有一半以上的 Master 標記一個節點的狀態是 pfail,那麼這個節點的狀態就會變成 fail。

當節點變成 fail 就會觸發自動主從切換。主從切換的過程,也涉及到類似的選舉:

  1. 當某個 Master 被標記為 fail 之後,對應的 Slave 節點執行定時任務 clusterCron 函式時,選取複製偏移量,也就是主從同步進度最大、資料最新的 Slave 嘗試變為主。
  2. 這個 Slave 設定自己的 currentEpoch += 1(正常情況下叢集中所有的 currentEpoch 相同,每次選舉都會加 1,並且每個 currentEpoch 只能投一次,防止多個 Slave 同時發起選舉後難以獲取大多數票),之後向所有的 Master 傳送 failover 請求,如果得到大多數 Master 的同意則開始執行主從切換。

叢集不可用情況

根據上面的描述,我們可以總結出如下不可用的情況

  1. 當訪問一個 Master 和 Slave 節點都掛了的槽的時候,會報槽無法獲取。
  2. 當叢集 Master 節點個數小於 3 個的時候,或者叢集可用節點個數為偶數的時候,基於 fail 的這種選舉機制的自動主從切換過程可能會不能正常工作,一個是標記 fail 的過程,一個是選舉新的 master 的過程,都有可能異常。

參考

  1. 官方文件:https://redis.io/topics/cluster-spec
  2. 原始碼:[https://github.com/redis/redis

每日一刷,輕鬆提升技術,斬獲各種offer:

image

相關文章