概述
Redis由原来的读/写域名直连升级为Sentinel架构后,业务连接Redis需要先拿到Sentinel配置,通过mymaster返回对应实例连接池,建立连接后相当于直连redis实例。
整个迁移/切换流程主要依赖sentinel在线配置更新进行切换
面临的问题
- sentinel failover 默认无法指定实例进行切换(除非修改指定replica实例上的slave-priority),当集群中master实例下有多个replicas的时候,由sentinel自动选出其中一个replica提升为master。
- sentinel failover 过程中,被选中的replica提升为master时会生成新的master_replid,切换完成后原master会降级为replica,并挂到新的master上。此时由于master_replid发生改变,原master会请求一次新master的rdb全量同步,此时会造成实例阻塞,阻塞时间取决于实例使用内存大小。当阻塞时间过长,则有可能触发sentinel自动failover,从而发生二次切换。
- 在数据同步阶段,如果要在集群加入replica。同样会触发full sync全量同步,对于大内存集群有阻塞风险。
整体架构
主实例:M1, M2, M3 ... Mn
从实例:R1, R2, R3 ... Rn
Sentinel实例:S1, S2, S3 ... Sn
线上Sentinel整体架构
优化后整体切换流程
1、同步阶段:添加待切换replica实例R2,以及R2的replica R3(R2必须作为R1的replica,R3必须作为R2的replica)
同步阶段
2、准备阶段:打开待切换replica实例R2可写,保证切换过程中不存在无法写入的情况
redis-cli -h ${R2_ip} -p ${R2_port} config set slave-read-only no
3、切换阶段:不通过sentinel failover在线切换,优化为在线修改sentinel配置的方式进行集群切换,使R2(replica)提升为M2(master)。同时切换域名解析到M2[R2]
sentinel remove ${mymaster} //清除原集群mymaster监控配置
redis-cli -h ${R2_ip} -p ${R2_port} -a '' slaveof no one //断开R2的数据同步,提升R2为M2[master]
sentinel monitor ${mymaster} ${R2_ip} ${R2_port} 2 //重新添加新集群mymaster监控,主实例指定 M2
kill connections //kill释放原集群master M1 的连接
4、完成阶段:确认业务正常后,下线原集群实例M1,R1。切换完成
redis-cli -h ${M1_ip} -p ${M1_port} shutdown save
redis-cli -h ${R1_ip} -p ${R1_port} shutdown save
切换完成阶段
说明
- 第1步:在数据同步阶段加入R2,R3作为链式复制,同步过程中只会请求R1进行full sync,不会对业务造成影响(业务读写M1)。解决问题3
- 第2,3步:切换过程中通过直接动态配置的方式,指定待切换的集群master,同时避免failover造成的full sync。解决问题1,2
- 整个切换过程sentinel配置无需变更
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。