缓存与数据库的一致性

缓存与数据库的一致性

一般而言,缓存都需要设置过期时间,通过缓存过期实现缓存与数据库的数据一致性是最后的兜底策略。
然后根据更新数据库的先后和是更新还是删除缓存做排序,有以下四种情形。
一般是使用更新数据库,删除缓存,当然都还是有并发问题的。

  • 更新缓存,更新数据库
    • 如果更新数据库失败,那么其实操作还没执行成功,缓存最终还是会变回旧数据
    • 如果缓存不是会被经常读取,那么这个缓存就会占用空间,还可能浪费计算资源
  • 删除缓存,更新数据库
    • 同样有更新数据库失败问题
  • 更新数据库,更新缓存
    • 同样有更新缓存问题
  • 更新数据库,删除缓存
    • 以数据库更新是否成功为准
    • 删除缓存,减少了空间占用和计算
    • 如果删除缓存失败,只能通过过期更新

删除缓存导致缓存击穿

  • 机器不多,可以只用本地锁
  • 机器多,需要上分布式锁

解决并发更新缓存

  • 双删除:删除缓存->更新数据库->延迟一段时间->删除缓存。
    这个延迟一段时间,第一是等待那些读到旧值的线程完成缓存的写入,第二可以等待mysql主从同步

解决删除缓存失败

  • 本地重试:但是如果是网络问题,短时间内的网络重试没什么意义
  • MQ异步重试:本地删除失败了,通过MQ的消费服异步删除,只有在redis和MQ同时故障的时候才行不通
  • Mysql的binlog异步删除:通过一个服务解析binlog,去删除相应的缓存

强一致性

强一致性方案当然可以解决并发更新缓存问题。

  • 分布式读写锁:让读线程等待写线程完成写入。
    读多写少可能还好,读少写多的缓存没啥作用,可能要考虑是不是要去掉缓存

参考文章:

聊聊数据库与缓存数据一致性问题

【原创】分布式之数据库和缓存双写一致性方案解析


缓存与数据库的一致性
https://cellargalaxy.github.io/posts/分布式/7.缓存与数据库的一致性/
作者
cellargalaxy
发布于
2020年7月27日
许可协议