我們一起搞定Redis腦裂問題
Redis 腦裂問題是指,在 Redis 哨兵模式或集群模式中,由于網絡原因,導致主節點(Master)與哨兵(Sentinel)和從節點(Slave)的通訊中斷,此時哨兵就會誤以為主節點已宕機,就會在從節點中選舉出一個新的主節點,此時 Redis 的集群中就出現了兩個主節點的問題,就是 Redis 腦裂問題。
腦裂問題影響
Redis 腦裂問題會導致數據丟失,為什么呢?來看腦裂問題產生的過程:
圖片
而最后一步,當舊的 Master 變為 Slave 之后,它的執行流程如下:
- Slave(舊 Master)會向 Master(新)申請全量數據。
- Master 會通過 bgsave 的方式生成當前 RDB 快照,并將 RDB 發送給 Slave。
- Slave 拿到 RDB 之后,先進行 flush 清空當前數據(此時第四步舊客戶端給他的發送的數據就丟失了)。
- 之后再加載 RDB 數據,初始化自己當前的數據。
從以上過程中可以看出,在執行到第三步的時候,原客戶端在舊 Master 寫入的數據就丟失了,這就是數據丟失的問題。
如何解決腦裂問題?
腦裂問題只需要在舊 Master 恢復網絡之后,切換身份為 Slave 期間,不接收客戶端的數據寫入即可,那怎么解決這個問題呢?
Redis 為我們提供了以下兩個配置,通過以下兩個配置可以盡可能的避免數據丟失的問題:
- min-slaves-to-write:與主節點通信的從節點數量必須大于等于該值主節點,否則主節點拒絕寫入。
- min-slaves-max-lag:主節點與從節點通信的 ACK 消息延遲必須小于該值,否則主節點拒絕寫入。
這兩個配置項必須同時滿足,不然主節點拒絕寫入。
在假故障期間滿足 min-slaves-to-write 和 min-slaves-max-lag 的要求,那么主節點就會被禁止寫入,腦裂造成的數據丟失情況自然也就解決了。