• 线上缓存不一致问题排查


    缓存不一致问题

    背景

    会员相关有:

    • 综合系统 :会员的基础CRUD ,旧系统,慢慢废弃,不再维护。
    • 会员系统 :从综合系统里拆分出来的,有基础服务,接口服务,数据同步服务,SSO服务等。 每个服务都是单独的应用。

    两个系统共用同一张表,只是维护的字段不一样。

    email【邮箱】是我们新版本中新支持的功能。综合系统没有 email 字段,会员系统里有 email 字段。

    第一次反馈

    用户反馈说: 邮箱收不邮件,去设置中看,邮箱设置会自动消失。重新设置一下就好了。

    定位问题

    一) 排查数据问题

    怀疑是综合系统中,将 email 字段更新成了默认的空值 。

    系统缺少必要的日志,无法追踪问题。并且缺少sql日志. 无法定位具体问题。

    观察了系统监控,没有异常。 内存,网络也没有波动。问题抛给了测试同学,希望能复现出来。

    第二次反馈

    用户反馈说:又出现邮箱收不到邮件,还没来得及重置,但过了大概一个小时,自动好了。

    定位问题

    一)排查数据库
    此时用户没有做更新操作。保护了数据库现场。

    马上查询数据库. 得到以下结果:

    1. 用户的 email 是存在的。
    2. 数据的最后更新时间,还是用户上次反馈的时间。

    数据现场表明 , 自从上次用户更新过后,没再发生过变化 。字段丢失,然后自动恢复显然不是发生在数据库上。

    此时想到是多服务间的数据不一致性。

    二)排查缓存

    此时想到是缓存问题。

    经过代码求证。 综合系统和会员系统是用的两个缓存key,所以不存在新旧系统的缓存冲突问题。

    二) 排查服务

    此时又想到是不同服务间的字段不一致,导致缓存不一致的可能性。

    由于每个服务都是单独的应用。对于 email 字段,只有基础服务,接口服务使用到了。 上线时只升级了这两个服务,其他服务没有做相应升级。

    也就是说,其他服务在做查询时,是没有 email 字段的 , 那么在写缓存时也是没有的。

    到这一步,基本确定是不同服务间的缓存更新,导致的缓存不一致问题。基本符合用户描述的问题。

    于是将步骤同步给测试同学,由测试同学去复现 。

    问题症结

    尴了尬的。 居然没有复现出来。

    这时才注意到另一个点。 缓存默认时长是 6 小时 。 用户有说过大概一个小时后恢复了。

    用户是持续性事件 ,缓存周期是 6 小时 , 不可能只一个小时就更新了缓存。

    辅助工具不给力

    一)运维平台的 缓存查询功能 , 由于年久失修, 并且过度设计,已经不能支持会员系统的缓存查询 。
    二)线上的缓存服务器只开放给运维人员 , 开发负责人都没权限 的。 关键运维还没人值班,大晚上也找不到人 。

    第三次反馈

    用户反馈说:邮件又不生效了, 此时设置界面也没有邮箱了 。 给我些时间定位问题,他先不重置。

    大晚上的 。 正在找不到问题点时 , 用户竟然还在线 , 并且还在关注问题 。 (中国好用户)

    马上去查询数据库 ,得到以下结果:

    1. 用户的 email 字段还是存在的
    2. 数据的最后更新时间,还是用户第一次反馈的时间。

    由此可以确定 。MD,就是缓存的问题 。

    至此的定位结果

    1. 确认是缓存不一致问题 。
    2. 理论上应该是服务间数据不一致导致的缓存不一致。
      1. 无法复现
      2. 无法解释一小时自动恢复

    缺少必要的支持,问题只能先暂停一下。 跟用户沟通好后 , 决定明天如果还找不到根源,就先把会员系统的其他所有服务都升级一把。
    缓存平台,由于运维人员维护不力 ,必须得催促一下。 太影响工作了。

    后记

    也就是第二天了 。

    先找运维要来了缓存服务器权限 , 由于没有现场, 想来问题肯定不止影响一个用户。去数据库里找了几个活跃用户, 果然试也没几个就找到了问题的用户。

    找到了问题缓存 。 是由于数据同步服务,在查询数据时,写缓存导致把原缓存覆盖了。

    理论上会员基本的CRUD都应该由基础服务来提供接口操作 , 但由于开发人员的不规范开发 , 在数据同步服务直接操作了数据库和缓存 。

    问题解决

    升级了数据同步服务, 问题就解决了。

    但没有完美解决 , 后续很大概率还会出现服务升级不同步, 及开发不规范导致的缓存不一致问题。 需求从技术层面解决服务间缓存不一致的问题。

    解决缓存不一致

    解决思路:

    1. 对缓存添加版本号
    2. 版本号是在打包时生成 ,减少人工成本。
    3. 当 缓存版本 》= 当前服务版本,ok,没问题,缓存是最新的
    4. 当 缓存版本 《 当前服务版本 , 有问题。缓存旧,不适合当前服务使用。 那么淘汰缓存 ,重新生成。

    好了, 有活干了, 对缓存的封装,要赶快做起来了。

    最后

    神奇的一小时 ,还是没解出来 。 还有 MD,测试没复现是 测试的同学步骤错了。。。

  • 相关阅读:
    Delphi Excel 操作大全
    ThreadLocal类
    MyBatis实战总结
    MyBatis入门
    Mybatis逆向工程
    2020年全国高校计算机能力挑战赛初赛java组
    集合论基础
    命题与逻辑
    Redis技术概述
    UML图中6种箭头的含义
  • 原文地址:https://www.cnblogs.com/ElEGenT/p/12578512.html
Copyright © 2020-2023  润新知