双服务器架构下Redis/Sentinel故障转移可行性及方案咨询
先帮你捋清楚为啥大家说Redis故障转移通常要3台服务器——核心是防脑裂(split-brain)。比如哨兵模式里,得超过半数的哨兵达成共识才能触发故障转移,3台的话2台同意就能拍板,不会因为网络分区出现两边各自当主的尴尬情况。但你只有2台服务器,也有几个靠谱的方案,结合你的会话、通知场景,给你拆解下:
把两台服务器分别部署为主Redis和从Redis,然后在每台服务器上各跑一个Sentinel进程,配置逻辑如下:
- 服务器A:部署Redis主实例,负责所有读写请求
- 服务器B:部署Redis从实例,实时同步主节点的数据
- 两台服务器上各启动一个Sentinel,配置
quorum 1(只要1个哨兵检测到主节点故障,就触发故障转移)
关键配置优化(降低脑裂风险)
在主节点的redis.conf里添加以下参数:
min-slaves-to-write 1 min-slaves-max-lag 10
这俩参数的作用是:主节点必须至少有1个从节点在10秒内完成数据同步,才允许接受写请求。如果出现网络分区导致主从断开,主节点会直接拒绝写操作,避免两边同时写入数据造成不一致。
应用层适配
应用连接Redis时,别直接写死主节点IP,要通过Sentinel的地址自动获取当前主节点——大部分主流Redis客户端(比如Jedis、StackExchange.Redis)都支持Sentinel自动发现功能,故障转移后应用能自动切换到新的主节点,不用改代码。
用Keepalived给Redis绑定一个虚拟IP(VIP),应用全程只需要连接这个VIP,不用关心背后的Redis节点:
- 正常状态下,VIP绑定在主Redis所在的服务器A,应用通过VIP读写主节点
- 当服务器A的Redis挂了,Keepalived会自动把VIP切换到服务器B,同时触发预设脚本把服务器B的从节点提升为主节点
- 等服务器A恢复后,手动把它设为新主节点的从,同步数据即可
注意点
- 要写个简单的检测脚本,让Keepalived能判断Redis是否存活(比如执行
redis-cli ping,返回PONG就认为正常) - 这个方案的缺点是故障恢复后需要手动介入同步,但胜在配置简单,适合小体量的会话、通知场景
如果你的云服务商有超小规格的实例(比如1核1G的廉价机型),可以花很少的成本加一台服务器专门跑Sentinel,这样就凑齐了3个哨兵节点,完美解决脑裂问题,这也是最稳妥的生产级方案。毕竟会话数据如果丢了或者不一致,用户体验会打折扣,这点成本还是值得的。
总结
如果预算有限,优先选方案1(主从+双哨兵),配合那两个配置参数能把风险降到最低;如果追求极致简单,方案2的Keepalived也能满足需求;如果想彻底规避脑裂风险,方案3是最优解。
内容的提问来源于stack exchange,提问作者Aditya T

