您的位置:首页 > 新闻 > 资讯 > 东莞市路桥所_线上设计师与线下设计师的区别_佛山做网站的公司哪家好_中国万网官网

东莞市路桥所_线上设计师与线下设计师的区别_佛山做网站的公司哪家好_中国万网官网

2025/6/4 15:19:02 来源:https://blog.csdn.net/m0_73748193/article/details/147165140  浏览:    关键词:东莞市路桥所_线上设计师与线下设计师的区别_佛山做网站的公司哪家好_中国万网官网
东莞市路桥所_线上设计师与线下设计师的区别_佛山做网站的公司哪家好_中国万网官网

一、⼀致性问题的由来:为什么会不一致?

我们先从现实例子出发,来看为什么会出现一致性问题:

📦 场景举例:电商下单业务

  1. 用户提交订单 → 服务写入数据库订单表;
  2. 同时更新缓存(比如用户的订单数量缓存);
  3. 如果在更新缓存前服务宕机了,那么缓存没有更新;
  4. 数据库是最新的,缓存却是旧的。

这个时候就出现了“缓存与数据库数据不一致”的问题。


二、可能出现不一致的典型操作顺序

操作顺序描述风险
✅ 正常流程先更新数据库,再删除缓存
❌ 反向顺序先删除缓存,再更新数据库如果更新慢或失败,可能被其他请求重新写入旧缓存
❌ 异步删除缓存更新数据库后异步删除缓存异步失败就不会删掉缓存了
❌ 多线程并发写请求并发,缓存与数据库互不协调脏数据风险高

三、解决方案详解

✅ 方案 1:先更新数据库,再删除缓存(强一致)

这是大多数系统采用的方式:

1. update DB
2. delete cache

目前最流行的缓存读写策略 Cache Aside Pattern(旁路缓存模式)就是采用的先写数据库,再删缓存的方式。

  • 失效:应用程序先从缓存读取数据,如果数据不存在,再从数据库中读取数据,成功后,放入缓存。
  • 命中:应用程序从缓存读取数据,如果数据存在,直接返回。
  • 更新:先把数据写入数据库,成功后,再让缓存失效。

左耳朵耗子:Cache Aside Pattern

优点:只要删除成功,下一次读请求就会重新回源数据库拿到最新值再写入缓存。

缺点:并发高时,如果删缓存和数据库之间被另一个请求读到了旧缓存,就不一致。


✅ 方案 2:延迟双删策略(推荐)

为了防止缓存刚删完就被其他线程重新写回老数据,可以在第一次删缓存后等待一段时间再次删一次:

updateDB();
deleteCache();
Thread.sleep(500);
deleteCache();

在这里插入图片描述

适用于读多写少的场景,第二次延迟删除是为了避免“击穿后写入旧数据”。


✅ 方案 3:消息队列补偿策略(最终一致性)

流程如下:

1. 更新数据库成功后,发送一条消息到 MQ(如 Kafka、RocketMQ)
2. 缓存服务订阅这个消息,接收到后再删除缓存

可以专门起一个服务(比如 Canal,阿里巴巴 MySQL binlog 增量订阅&消费组件)去监听 MySQL 的 binlog,获取需要操作的数据。在这里插入图片描述

然后用一个公共的服务获取订阅程序传来的信息,进行缓存删除。

三分恶面渣逆袭:数据库订阅+消息队列保证key被删除
这种方式虽然降低了对业务的侵入,但增加了整个系统的复杂度,适合分布式系统中异步解耦场景。

📌 要求 MQ 高可靠、要做消息幂等处理


✅ 方案 4:读写都走缓存(缓存作为主存)

比如电商秒杀场景,订单库存都缓存于 Redis,数据库作为持久化。

  • 所有写操作先写 Redis
  • 后台定时同步到 DB(MySQL)
  • 或使用 binlog 异步写入(如 Canal)

风险:系统崩溃前未同步的缓存可能丢失,适用于对一致性要求不极端高的场景。


四、附图:缓存与数据库一致性解决策略图

在这里插入图片描述


五、常见问题及应对策略

面试提问建议回答
如何保证缓存和数据库一致性?描述“先更新数据库,再删除缓存”的基本原则,提出“延迟双删”、“消息队列”等高级策略
如果缓存刚删完就被旧值写回了怎么办?回答“延迟双删”或“使用分布式锁防止并发更新”
缓存更新失败怎么办?回答“使用 MQ 补偿机制,做幂等重试”

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com