1. 引言
Redis作为分布式内存存储,使用广泛,本文聊聊Redis双活。
Redis常用的场景有:数据缓存、分布式锁(Job锁、防重、幂等)、计数器(次数控制、秒杀、库存)、会话(登陆态,交易流程控制)等。
在设计Redis双活方案时,需要整理应用系统所用到的场景,根据数据丢失、不一致的容忍度来选择方案。
目前的方案主要有三种分别是:热备、跨IDC同步、应用双写。
2. 双活方案
2.1. 方案一:热备
1.常规情况
1. 双活IDC的应用连接主IDC的Redis。
2. 双活IDC的Redis处于启动状态,随时可以连接。
2. 容灾切换
主IDC故障,切换到双活:
主IDC故障应用、Redis都不能用,双活IDC的应用切到连接双活IDC的Redis,并承担100%流量访问。
Redis容灾切换时,Redis数据会全部丢失,影响系统业务功能,使用时要评估每种业务场景的影响。
a、共享会话丢失,用户需要重新登录(对应用体验有影响)。
b、计数器归零,对计数器有依赖的场景(库存扣减、秒杀等)有比较大的风险。
c、缓存数据丢失,需要查询DB重建缓存,命中率降为0(缓存击穿)。
d、分布式锁会失效,原子性被破坏。
3. 故障恢复
1、主IDC恢复之后须重启清空Redis数据,避免脏数据影响业务准确性。
2、主IDC、双活IDC的应用都连接双活IDC的Redis。
3、故障机房完全恢复后,在业务最低峰期再把主IDC,双活IDC切到主IDC的Redis,达到故障完全恢复。
4. 总结
此方案的优点是架构简单,故障时切换即可。
但Redis切换时,数据丢失,Redis重置,需要细致评估每个Redis使用场景,是否能接受
2.2. 方案二:跨IDC同步
Redis跨IDC同步,是在热备的基础上增加了Redis数据跨IDC“增量”同步的功能。
1. 常规情况
主IDC的Redis数据通过Redis-Shake的Sync/Psync模式全量或增量实时同步到双活IDC。
2. 容灾切换
主IDC的故障,切换到双活IDC:
Redis是跨IDC同步,在故障的瞬间可能会有1-3秒的数据未同步完成。Redis场景基本上读多写少,对业务影响不大。
3. 故障恢复
主IDC的应用及Redis恢复,需要切回主IDC:
说明:
1、主IDC应用、双活IDC应用都连接到双活IDC的Redis。
2、为保证Redis数据的一致性,双活IDC的Redis反向同步到主IDC,以备后续切为主IDC。
4. 总结
Redis基本上,读多写少,跨IDC同步,保证数据不丢,基本上保证数据一致性,技术上是可行的,对“热备”方案是一个很好补充。
短期,进入双活环境的流量也不大,读多写少。跨IDC同步虽有一定延时,一致性上基本能接受。
注:跨IDC访问存在5-8毫秒延时。
2.3. 方案三:应用双写(不推荐)
应用双写是指应用同时连接主IDC、双活IDC,写数据时同时写两个IDC的Redis,读数据时只读同IDC的Redis。
通过应用双写来实现两个IDC的数据一致性。
1.常规情况
说明:
1、应用同时连接两个IDC的Redis,写数据时同时,写两个Redis。
2、应用只读同IDC的Redis。
问题点:
1、应用实现双写,应用需要改代码。需要收集所有”写“请求的点,进行代码改造。
2、如果程序员在版本迭代过程中,漏掉了一些点,将会产生数据不一致,而且不容易把问题测试出来。
而且,在双写的代码中,Redis原子操作无法保障,程序员如果对异常处理不当,当其中某一集群故障时,就会导致业务不可用。
这点上,对研发、测试要求太高,也容易出问题。
3、应用双写,如果其中一个集群故障一小段时间,则会产生两个集群数据不一致,意味着有个集群是不对的,而且无法进行对账和补偿,需要干掉其中一个。运维都无法识别和处理。
2. 容灾切换
主IDC故障期间,双活IDC跨IDC写会失败,会产生大量异常,并影响到业务功能。
3. 故障恢复
当主IDC故障恢复后,两个Redis的数据已经不一致。主IDC Redis集群的数据无法进行增量补偿,无法解决两个集群数据不一致问题。
这个问题是致命的。
4.总结
此方案,有严重不可补偿的数据不一致问题,不推荐使用。
从此前的评审中,发现有些团队用了此方案,建议根据业务场景重新评估使用。
3. 问题和挑战
1. 一致性问题
作为存储,数据一致性是放在第一位的,其次才是高可用、性能。
应用系统需要分析Redis使用场景及其一致性要求,来选择双活方案。
2. 缓存击穿问题
热备方案Redis切换时,分布式数据缓存场景下,命中率接近0(缓存击穿),数据库的压力增大,需要评估好场景及DB承受能力。
3. 跨IDC时延问题
Redis本身响应时间1~2ms,跨IDC时延5~8ms,跨IDC访问意味着慢3倍左右,这个影响还是挺大的。
短期,在常规情况下,导小部分流量进入双活环境,尽量避免跨IDC访问,监控观察应用系统接受情况。
长期,视实际情况实际问题,实际解决。
4. 方案如何选择
容忍数据丢失,则选择简单方案:热备。否则:跨IDC同步。
应用双写不推荐,方案复杂,且有故障后不能恢复的致命问题。
长期,根据实际业务场景,探索“数据分IDC“方案,尽量避免跨IDC访问。
四. 总结
简单总结之,Redis作为存储,数据一致性,是第一考虑因素。 只有一致性得到基本保障,其次才考虑是高可用、性能等。
“尽量不跨IDC访问“,是在一致性得到基本保障的前提下。
作者:李春明 (LICHUNMING598),网金研发团队架构师
修订:李兴楠(LIXINGNAN945),网金研发团队架构师
本文系个人观点,描述不当或不正确,欢迎指正。