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