背景
最近一组业务redis数据不断增长需要扩容内存,而扩容内存则需要重启云主机,在按计划扩容升级执行主从切换时意外发生了数据丢失与master进入只读状态的故障,这里记录分享一下。
业务redis高可用架构
该组业务redis使用的是一主一从,通过sentinel集群实现故障时的自动主从切换,这套架构已经平稳运行数年,经历住了多次实战的考验。
高可用架构大体如下图所示:
简单说一下sentinel实现高可用的原理:
集群的多个(2n+1,N>1)哨兵会定期轮询redis的所有master/slave节点,如果sentinel集群中超过一半的哨兵判定redis某个节点已主观下线,就会将其判定为客观下线进行相应处理:
- 如果下线节点是master,选定一个正常work的slave将其选定为新的master节点。
- 如果下线节点是slave,将其从slave节点中移除。
如果已经被客观下线的节点恢复了正常,sentinel中超过一半哨兵确认后则将其加回可用的slave节点。
所有需要读写redis的server并不需要直接写死redis 主从配置,而是通过访问sentinel获取当前redis的主从可用状态,具体实现方式可以定时查询sentinel询问更新,也可以通过订阅机制让sentinel在主从变动时主动通知订阅方更新。
sentinel实现高可用的详细原理这里不做过多赘述,有兴趣的小伙伴可以移步参考文献中的相关资料。
具体内存扩容流程
sentinel可以在检测到故障时自动切换redis主从,也可以主动执行sentinel failover mastername 命令实现手动切换主从,所以这次的内存扩容重启流程设计如下(A代表初始master所在云主机,B代表初始slave所在云主机):
- 升级主机B内存配置,重启主机B
- 检查B重启后其上的redis slave是否重新同步master数据完成,包括:
2.1 查看slave redis log是否异常,无异常pass2.2 使用info keyspace命令check master、slave 各db key数量是否一致,无异常pass2.3 在master写入一个测试key,在slave上check是否同步成功2.4 观察依赖server log是否有异常 - 使用sentinel failover mastername命令手动主从切换,主机A变成新slave,主机B变成新master,根据以前手动切换的经验走到这一步基本上就稳了–因为这里本质上和一次普通主从切换已经没有区别了。
升级主机A内存配置,重启主机A,执行以下check: - 4.1 查看新slave redis log是否异常4.2 使用info keyspace命令