数据库与缓存一致性

160 阅读2分钟

读数据流程

image.png

写数据流程

写数据流程才会产生数据不一致的问题

先删缓存再更新数据库

  • 正常流程

image.png

  • 异常情况

image.png

这就导致了直到下次写数据前(甚至下一次也不一定),读取到的数据始终是脏数据

  • 解决方案

延迟双删:至少保证最多在 x 毫秒内其他线程读取到的数据是脏数据

  1. 先删除缓存
  2. 再更新数据库
  3. 休眠 x 毫秒,再删除缓存

image.png

  • 在数据库更新完成后,等待一段时间(通常是比业务执行时间稍长的延迟),然后再次删除缓存中的数据。这是为了处理在数据库更新和缓存第一次删除之间可能出现的并发请求,确保缓存中的数据是最新的。

  • 关键点:这种策略的关键在于第二次删除缓存的延迟时间要合理设置,以确保尽可能覆盖到所有可能的并发请求

先更新数据库再删缓存

  • 正常流程

image.png

  • 异常情况

image.png

  • 解决方案

    • 重试机制:在删除缓存失败时,自动进行多次重试,以提高成功率。
    • 异步删除:将缓存删除操作放入队列中,由专门的线程或服务异步处理,确保最终一致性。
    • 监控与报警:实现对缓存删除失败的监控和报警机制,以便及时发现和处理问题。

image.png

总结

引入了缓存,都只能确保最终一致性,无法确保强一致性

  • 对于并发几率很小的数据,这种几乎不用考虑这个问题,很少会发生缓存不一致,可以给缓存数据加上过期时间,每隔一段时间触发读的主动更新即可。

  • 对于并发很高,如果业务上能容忍短时间的缓存数据不一致(如客户名名称等),缓存加上过期时间依然可以解决大部分业务对于缓存的要求

  • 如果不能容忍缓存数据不一致,可以通过加分布式读写锁保证并发读写或写写的时候按顺序排好队,读 读的时候相当于无锁

  • 也可以通过监听数据库的binlog日志去修改缓存(同步ES同理)