news 2026/6/21 16:29:25

如何保证数据库和缓存一致性问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何保证数据库和缓存一致性问题

如何保证数据库和缓存一致性问题

我刚开始以为数据一致性指的是不同请求拿到的数据是一样的,但是这个对于一致性的定义其实是强一致性。

为了保证系统的可用性和性能,我们选择的是牺牲强一致性来获取最终一致性,那么接下来我们只需要保证最终一致性而无需考虑整个过程中的数据强一致性。我们使用的是旁路缓存的方式。

对于读策略,如果缓存没有过期,直接读取即可。如果缓存过期,可以选择客户端线程或者是redis的后台线程去读数据库的数据,然后更新到缓存中,最后再返回给客户端。

对于写策略,有两种方式,先更新数据库,后删缓存。先删缓存,后更新数据库。

对于先删缓存,后更新数据库来说,假设线程A删缓存,此时线程B访问数据,发现数据不在缓存中。那么线程B需要去数据库中获取数据再将数据放到缓存中,等到线程A更新完数据库后,此时数据库和缓存中的数据不一样,无法保证最终一致性。对于先更新数据库,后删缓存来说,线程A先进行数据库的更新,此时线程B访问缓存有数据直接返回,接着线程A再进行缓存的删除,此时可以保证缓存和数据库的一致性。后续请求访问缓存时,没有命中会到数据库中进行获取对应数据。有一种特殊情况,线程B在缓存中没有找到数据,去数据库中进行数据的查找,线程A更新数据库,等到线程A删除缓存中的数据后,线程B再将之前获取的数据放到缓存中。由于线程B拿到的数据是在线程A更新数据库之前的,那么此时会存在数据库和缓存数据不一致的问题,但是这样的概率会很低,因为将数据写到缓存中的速度大于线程A更新数据库的速度

删除缓存一般存在两种方式:通过设置数据的过期时间和直接删除的方式。

通过设置数据的过期时间比较麻烦,设置过小,缓存没有起到缓存效果,请求会发到数据库中,造成数据库的压力。设置过大,缓存和数据库之间数据延迟较大,且浪费内存。

因此我们选择直接删除的方式来进行优化。此时我们需要保证直接删除能够成功,否则旧有数据一直存放到缓存中,会造成数据一致性问题。


对于直接删除数据会有两种方式。

一种是删除数据重试策略,我们会将需要删除的数据放在消息队列中,由客户端去获取需要删除的数据,尝试删除,如果删除成功那么将消息从消息队列中进行移除,如果没有成功那么重新尝试几次。尝试几次依然没有成功,需要向业务层反馈这个问题。

这种方式缺点是我们需要通过在代码中写死向mq队列发送特定要删除的数据。

另外一种是通过订阅binlog + canal + 消息队列方式。我们通过订阅binlog,将数据解析为结构化数据存放到消息队列中,接着编写一个简单的消费数据的消费者订阅mq,接着通过获取数据的key来完成删除操作。通过ack机制来保证数据一致性问题。

这种方式我们通过订阅binlog。数据发生更新,此时binlog会发生改动,那么canal能够察觉binlog的变化并将改动后的信息发送给mq。这样子并不需要我们硬编码,来完成数据的删除操作。缺点是实现起来比较麻烦。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 7:47:55

2025年移动开发框架深度对决:Framework7与Ionic的终极较量

2025年移动开发框架深度对决:Framework7与Ionic的终极较量 【免费下载链接】framework7 Full featured HTML framework for building iOS & Android apps 项目地址: https://gitcode.com/gh_mirrors/fra/Framework7 在移动应用开发领域,技术选…

作者头像 李华
网站建设 2026/6/20 18:23:48

java基础-ArrayDeque

ArrayDeque 是 Java 集合框架 中的一个类,它是一个基于可调整大小的循环数组实现的双端队列是Deque接口的实现类之一继承关系:Iterable (接口)↓ Collection (接口)↓ Queue (接口)↓ Deque (接口)↓ ┌─────────────────┐ │ ArrayD…

作者头像 李华
网站建设 2026/6/21 16:05:31

47年国货焕新:中顺洁柔凭北森学习系统建立制造业人才转型样板

在北森第三届用户英雄大会AI Learning分论坛上,中顺洁柔人力资源总监张建瓴女士的分享,为在场听众勾勒出一幅传统制造业在时代浪潮中稳健又充满活力的进化图景。这家拥有47年历史的国货品牌,没有讲述多么炫酷的技术神话,而是坦诚地…

作者头像 李华
网站建设 2026/6/15 21:52:56

jetty9配置contextPath

配置 Jetty 9 的 Context Path在 Jetty 9 中配置 contextPath 可以通过多种方式实现&#xff0c;以下是几种常见的方法&#xff1a;通过 web.xml 配置在 web.xml 文件中&#xff0c;可以通过 <context-param> 设置 contextPath。例如&#xff1a;<context-param>&l…

作者头像 李华
网站建设 2026/6/20 5:48:53

从零配置Python测试环境:详解路径、依赖与虚拟环境最佳实践

事情是这样的&#xff1a;前几天写了篇推广自动化测试的吐槽文章&#xff0c;结果被同事刷到了&#xff08;谁也逃不过大数据&#xff09;&#x1f602; 不过他没生气&#xff0c;反而说一定会搞明白 Python 到底是啥&#x1f60f; 那行吧&#xff0c;这篇就当作一个小小的 Pyt…

作者头像 李华
网站建设 2026/6/20 9:01:50

测试管理:为何测试场景覆盖不全问题频现?

在软件开发和质量管理的过程中&#xff0c;测试场景覆盖不足是一个常见的痛点。尽管测试团队倾力构建详尽的测试用例集&#xff0c;但在实践中却常常出现测试场景覆盖不全的情况&#xff0c;这不仅可能导致产品质量问题的漏检&#xff0c;还可能引发用户在实际使用过程中的不满…

作者头像 李华