Redis与数据库的一致性

 2024-03-31    0 条评论    490 浏览

redis

新增数据

这个不需要特殊处理,直接新增到数据库,然后其他读线程走正常缓存流程即可

更新数据

先更新缓存再更新DB(不推荐)

优点:不会有其他读线程读取旧数据的问题;

缺点:

  1. 更新DB与更新缓存不是原子性,并发更新会有乱序导致写DB与写Redis的顺序不一致,数据覆盖,导致Redis与DB数据不一致
  2. 更新DB出现异常,会导致数据不一致,并且无法察觉,也无法确定redis与DB中哪个是新的;
先更新DB再更新缓存

优点与缺点同上;

先删除缓存再更新DB(延迟双删)

问题:删除缓存与更新DB非原子性操作,删除缓存后更新DB的过程如果有其他读线程进来,会导致Redis重新被缓存了旧值脏数据;

解决方案:延迟双删;

  1. 删除缓存
  2. 更新DB
  3. 延迟一秒(具体时间看缓存流程耗时)后再删除缓存可能有的脏数据

另一个问题:如果DB是主从结构,数据同步也会有延迟,也要考虑增加延时时常;

先更新DB再删除缓存

优点:不发生异常的情况下,保证数据的最终一致性(可能有那么一两秒的不一致);

缺点:当更新DB后,删除缓存时出现一场,将导致数据不一致;

解决:对异常增加捕获机制,捕获并记录异常,增加重试操作;

另一个问题:如果DB是主从结构,可能会因DB同步延时导致数据不一致;

例如更新主库并删除缓存,此时读线程进来读取了从库脏数据并更新到Redis中,导数据不一致;

总结

更新缓存不推荐,删除缓存推荐

原因是并发更新时,更新缓存与DB操作会有原子性操作问题,而删除缓存操作与更新DB可以不是原子性,乱序不影响最终结果;

无异常的情况

更新DB再删除缓存更推荐

考虑异常情况

捕获并记录异常,增加retry机制;

其它办法
  • key都增加过期时间
  • 设置定时任务定时整体更新DB数据到缓存