前几天线上发生了一个故障,大批用户反馈自己的数据异常。收到反馈后发现是用户缓存中的一个字段A混入了脏数据。 背景:用户信息是从mysql取,然后存到缓存中。后来加了一个业务:从redis取出另一个数据A,一起存入用户缓存中, 临时将数据异常的缓存清空,然后开始找原因。开始一直以为是redis波动导致取数据A失败,导致A出现脏数据。但是日志中又没有找到当时的redis报错信息。 最后实在没办法,就在设置缓存的方法里记个debug日志,如果待存入缓存的数据中A字段异常,就把调用栈记下来。果然就找到原因了。 根据uid获取用户信息时,如果uid传了是123a,缓存中自然没有123a这个key,穿透到mysql,而mysql由于隐式转换会搜索出id=123的记录,然后redis也没有123a这个key,所以A为空,最后id=123的用户信息和空的A一起存入了id=123用户缓存中。真是坑爹。解决办法就是在获取用户信息的方法前加个强制类型缓存(intval),将123a转换为123。

参考资料:https://yq.aliyun.com/articles/39477