线上缓存不一致问题排查
缓存不一致问题
背景
会员相关有:
- 综合系统 :会员的基础CRUD ,旧系统,慢慢废弃,不再维护。
- 会员系统 :从综合系统里拆分出来的,有基础服务,接口服务,数据同步服务,SSO服务等。 每个服务都是单独的应用。
两个系统共用同一张表,只是维护的字段不一样。
email【邮箱】是我们新版本中新支持的功能。综合系统没有 email 字段,会员系统里有 email 字段。
第一次反馈
用户反馈说: 邮箱收不邮件,去设置中看,邮箱设置会自动消失。重新设置一下就好了。
定位问题
一) 排查数据问题
怀疑是综合系统中,将 email 字段更新成了默认的空值 。
系统缺少必要的日志,无法追踪问题。并且缺少sql日志. 无法定位具体问题。
观察了系统监控,没有异常。 内存,网络也没有波动。问题抛给了测试同学,希望能复现出来。
第二次反馈
用户反馈说:又出现邮箱收不到邮件,还没来得及重置,但过了大概一个小时,自动好了。
定位问题
一)排查数据库
此时用户没有做更新操作。保护了数据库现场。
马上查询数据库. 得到以下结果:
- 用户的 email 是存在的。
- 数据的最后更新时间,还是用户上次反馈的时间。
数据现场表明 , 自从上次用户更新过后,没再发生过变化 。字段丢失,然后自动恢复显然不是发生在数据库上。
此时想到是多服务间的数据不一致性。
二)排查缓存
此时想到是缓存问题。
经过代码求证。 综合系统和会员系统是用的两个缓存key,所以不存在新旧系统的缓存冲突问题。
二) 排查服务
此时又想到是不同服务间的字段不一致,导致缓存不一致的可能性。
由于每个服务都是单独的应用。对于 email 字段,只有基础服务,接口服务使用到了。 上线时只升级了这两个服务,其他服务没有做相应升级。
也就是说,其他服务在做查询时,是没有 email 字段的 , 那么在写缓存时也是没有的。
到这一步,基本确定是不同服务间的缓存更新,导致的缓存不一致问题。基本符合用户描述的问题。
于是将步骤同步给测试同学,由测试同学去复现 。
问题症结
尴了尬的。 居然没有复现出来。
这时才注意到另一个点。 缓存默认时长是 6 小时 。 用户有说过大概一个小时后恢复了。
用户是持续性事件 ,缓存周期是 6 小时 , 不可能只一个小时就更新了缓存。
辅助工具不给力
一)运维平台的 缓存查询功能 , 由于年久失修, 并且过度设计,已经不能支持会员系统的缓存查询 。
二)线上的缓存服务器只开放给运维人员 , 开发负责人都没权限 的。 关键运维还没人值班,大晚上也找不到人 。
第三次反馈
用户反馈说:邮件又不生效了, 此时设置界面也没有邮箱了 。 给我些时间定位问题,他先不重置。
大晚上的 。 正在找不到问题点时 , 用户竟然还在线 , 并且还在关注问题 。 (中国好用户)
马上去查询数据库 ,得到以下结果:
- 用户的 email 字段还是存在的
- 数据的最后更新时间,还是用户第一次反馈的时间。
由此可以确定 。MD,就是缓存的问题 。
至此的定位结果
- 确认是缓存不一致问题 。
- 理论上应该是服务间数据不一致导致的缓存不一致。
- 无法复现
- 无法解释一小时自动恢复
缺少必要的支持,问题只能先暂停一下。 跟用户沟通好后 , 决定明天如果还找不到根源,就先把会员系统的其他所有服务都升级一把。
缓存平台,由于运维人员维护不力 ,必须得催促一下。 太影响工作了。
后记
也就是第二天了 。
先找运维要来了缓存服务器权限 , 由于没有现场, 想来问题肯定不止影响一个用户。去数据库里找了几个活跃用户, 果然试也没几个就找到了问题的用户。
找到了问题缓存 。 是由于数据同步服务,在查询数据时,写缓存导致把原缓存覆盖了。
理论上会员基本的CRUD都应该由基础服务来提供接口操作 , 但由于开发人员的不规范开发 , 在数据同步服务直接操作了数据库和缓存 。
问题解决
升级了数据同步服务, 问题就解决了。
但没有完美解决 , 后续很大概率还会出现服务升级不同步, 及开发不规范导致的缓存不一致问题。 需求从技术层面解决服务间缓存不一致的问题。
解决缓存不一致
解决思路:
- 对缓存添加版本号
- 版本号是在打包时生成 ,减少人工成本。
- 当 缓存版本 》= 当前服务版本,ok,没问题,缓存是最新的
- 当 缓存版本 《 当前服务版本 , 有问题。缓存旧,不适合当前服务使用。 那么淘汰缓存 ,重新生成。
好了, 有活干了, 对缓存的封装,要赶快做起来了。
最后
神奇的一小时 ,还是没解出来 。 还有 MD,测试没复现是 测试的同学步骤错了。。。