用 docker 學習 redis 主從複製3.3 redis-sentinel「哨兵模式」 資料丟失的情況

php_yt 發表於 2022-01-15
Redis Docker

哨兵模式雖然能夠在 master 下線時自動故障轉移,但還是不能保證資料百分百不丟失,本篇介紹下什麼情況下會發生。

1、非同步複製導致資料丟失
由於 master-->slave 的複製是非同步,所以可能有部分資料還沒來得及複製到 slave 就當機了,這部分資料就丟失了。

2、叢集腦裂導致資料丟失
如果 master 因為網路原因導致哨兵 ping 超時,因而判斷為客觀下線,但其實master 並沒有真實下線。哨兵開始故障轉移,而在此過程中,客戶端在向 master 寫入資料。

用 docker 學習 redis 主從複製3 redis-sentinel「哨兵模式」避免資料丟失

在選舉過程中,新的 master 已經產生,哨兵也開始向其他 redis機器 傳送命令讓它們成為新 master 的從節點。而原 master 在沒有成為新 master 的從節點之前,實際上同時有兩個 master,稱之為「叢集腦裂」。

因為原 master 最終會成為新 master 的從節點,因此客戶端寫入的資料會在主從同步完成後刪掉,造成故障轉移期間寫入的資料丟失。

用 docker 學習 redis 主從複製3 redis-sentinel「哨兵模式」避免資料丟失

主節點的兩個配置選項可以減少上述情況的資料丟失
發生以下兩種情況,主節點拒絕執行寫命令。

#從節點的數量少於1個
min-slaves-to-write 2
#或者有2個從節點的延遲(lag)值都大於或等於10秒時
min-slaves-max-lag 10
  1. 非同步複製導致的資料丟失
    min-slaves-max-lag 10
    主從伺服器可以通過傳送和接收 REPLCONF ACK 命令來檢查兩者之間的網路連線是否正常,如果主伺服器超過一秒鐘沒有收到從伺服器發來的REPLCONF ACK命令,那麼主伺服器就知道主從伺服器之間的連線出現問題了,在一般情況下,lag 的值應該在 0 秒或者 1 秒之間跳動。
    如果 min-slaves-to-write 個從節點的 lag 值都大於 10 秒,則拒絕新的寫入。也就是說,客戶端能正常連線進行寫入,但是和從節點的連線出問題了,起不到主備的作用了,那就不要再新寫入資料了。

  2. 腦裂導致的資料丟失
    min-slaves-to-write 2
    在故障轉移過程中,晉升一個節點為主節點後,其他機器會陸續變為新主節點的從節點。這意味著,原主節點的從節點在減少,直到自己也變成從節點。
    如果主節點的從節點少於了 2 臺甚至都沒有從節點了,那麼就拒絕寫入命令。

  3. 拒絕寫入後的客戶端連線問題
    如果主節點連線失敗或者拒絕寫入,就需要發起重試,請求哨兵拿到新的主節點資訊。

本作品採用《CC 協議》,轉載必須註明作者和本文連結
focus