暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

同城双活-Redis篇

Hubble技术架构 2021-04-18
1309

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),网金研发团队架构师

本文系个人观点,描述不当或不正确,欢迎指正。

文章转载自Hubble技术架构,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论