Post

Redis学习实践(四) -- 业务场景案例

Redis业务场景相关案例

Redis学习实践(四) -- 业务场景案例

1. 背景

光看理论和代码感受不深,本篇梳理记录一些Redis相关的业务场景案例。

相关参考:

说明:本博客作为个人学习实践笔记,可供参考但非系统教程,可能存在错误或遗漏,欢迎指正。若需系统学习,建议参考原链接。

2. 缓存和数据库一致性问题

几个场景和存在的问题:

1、先更新缓存,后更新数据库

  • 场景1:若第一步成功,第二步失败,则数据库是旧值,缓存过期后会从数据库读取到旧值
  • 场景2:多线程并发更新场景,无法保证缓存和数据一致性

2、先更新数据库,后更新缓存

  • 场景1:若第一步成功,第二步失败,则读请求从缓存读取到旧值,等缓存过期才从数据库读取到新值
  • 场景2:多线程并发场景,无法保证缓存和数据一致性

进一步方案:先更新数据库,再删除缓存

3、先删除缓存,后更新数据库

  • 并发场景下依旧有数据不一致问题,解决方案是延迟双删,但这个延迟时间很难评估,所以推荐用 先更新数据库,再删除缓存 的方案

4、先更新数据库,后删除缓存

  • 先更新数据库,再删除缓存 方案下,为了保证两步都成功执行,需配合 消息队列订阅变更日志 的方案来做,本质是通过 重试(异步重试) 的方式保证数据一致性
    • 方案过程:线程A可以生成一条延时消息,写到消息队列中,消费者延时删除缓存
    • 例如:当一条数据发生修改时,MySQL就会产生一条变更日志(Binlog),可以订阅这个日志,拿到具体操作的数据,然后再根据这条数据,去删除对应的缓存。
  • 先更新数据库,再删除缓存 方案下,MySQL读写分离 + 主从库延迟 也会导致缓存和数据库不一致,缓解此问题的方案是 延迟双删,凭借经验发送延迟消息到队列中,延迟删除缓存,同时也要控制主从库延迟,尽可能降低不一致发生的概率
    • 问题过程:线程A更新主库 —> 线程A删除缓存 -> 线程B查询缓存,没命中,查询从库得到旧值 -> 从库同步完成 -> 线程B将旧值写入缓存。最终:缓存中的值是旧值。
    • 方案过程:在线程A删除缓存、更新完数据库之后,先休眠一会,再删除一次缓存

3. 小结

4. 参考

This post is licensed under CC BY 4.0 by the author.