记录一次缓存引起的线上BUG

背景

有一个需求大概是这样的,为了提高推荐系统的性能,需要本来从A服务获取的帖子信息,改为从Redis里面重新读取

Redis里面没有存帖子的所有信息,只存储了推荐系统必要的字段

大概是这样的:

rec_bug.png

至于Redis如何批量和实时维护数据我们不用管,只要还能从Redis读到之前的帖子信息即可

实现

这个实现起来不难,只要根据帖子ID读取Redis的数据,然后原样转为帖子实体即可

问题

帖子信息不全

这是在沙箱环境遇到的问题,Redis存储的帖子信息不够全,虽然对推荐系统是足够的,但对下游的返回结果不够使用

解决方法

在返回之前,重新调用A服务获取帖子信息,覆盖原来的帖子。

为什么不直接调用A服务呢,因为返回结果的时机帖子数量比较少,一般在10条之内,而召回要查询的帖子可能是几百上千条。

rec_bug_stage.png

通过这样修改,沙箱测试也顺利通过

上线后帖子信息仍然不全?

本以为这样就没事,结果上线灰度的过程中,下游服务开始报警,和相关同学确认之后说还是在沙箱环境中碰到那个错

此时我懵了,这个不是已经重新获取了帖子信息吗

x

拼命在核对代码,这个从Redis的帖子信息是怎么绕过重新从A服务获取信息的

通过报警的数量来看,不是必然出现的

怀疑以下原因:

  • 环境问题,因为沙箱没问题,线上有问题,可能是配置不同或者环境变量
  • 并发问题,沙箱测试肯定没有并发,是不是线上并发请求导致哪个变量有问题
  • 异常逻辑,是不是有些请求没做正常逻辑,走了异常逻辑导致提前返回

通过线上灰度和各种log不停调试了两天排除了上述问题和代码逻辑的问题,此时已经接近绝望

曙光

有一点一直能确定,就是从Redis获取的帖子信息返回给了下游,但它是怎么漏出去呢?

突然想到会不会不是灰度的机器返回出去的,而是旧版本的机器返回出去的。

因为我们会对召回回来但是未被使用的帖子做缓存,也就是说,灰度机器召回的不完整帖子通过缓存被旧机器返回回去了

rec_bug_cache.png

总结

在上线过程中,新版本机器产生的脏数据通过缓存Rdis被旧版本机器使用了,而旧版本机器没有对脏数据进行处理导致出现的问题

之所以记录这个问题,是因为这个问题花费了我很多时间,现在看起来简单,但当时却很难发现,所以希望能给看到的同学一些启发

追加

除了数据产生的线上问题之外,之前还碰到过一个不容易发现的线上BUG, 就是全局变量,具体表现为: 线上刚开始表现是正常的,当这个全局变量被改变之后,然后就不正常了,也是一个不太容易发现的问题

posted @ 2022-08-23 10:12  songtianer  阅读(71)  评论(0编辑  收藏  举报