如何保证redis和mysql数据一致性方案对比

一. 先更新数据库再更新缓存

  1. 业务代码中先 DB 后 Cache(不推荐)

updateDB();

updateCache();

原因:

  1. DB成功,Cache失败 缓存不一致 无法进行回滚

为啥使用@Transactional不能保证数据一致性?

@Transactional

public void update() {

updateDB(); // 数据库

updateCache(); // Redis / 本地缓存

}

上面代码的执行顺序:

1.updateDB() → 执行 SQL(未提交)

2.updateCache() → Redis 已更新

3.方法结束

4.事务提交(或回滚)

@Transactional满足条件?

@Transactional 的本质基于数据库的事务。

它只能保证:

1.多条数据库 SQL

2.在同一个数据源

3.同一个线程

4.同一个事务上下文

  1. 业务代码中先 DB ,再删除 Cache(推荐)但是会出现短暂不一致

@Transactional

public void update() {

updateDB();

}

public void afterUpdate() {

deleteCache();

}

流程:

更新 DB(事务)

提交成功

删除缓存

下次读 → 回源 DB → 重建缓存

二. 先更新缓存再更新数据库

结论:

先更新缓存再更新数据库的做法,永远无法保证数据严格的一致性。

原因:事务A更新缓存成功,更新数据库失败,就会导致redis和mysql的

数据不一致。

绝大多数场景不使用先更新缓存再更新数据库。

特殊场景:缓存为主,DB为辅。

思路:缓存是主存储,数据库只是持久化备份

适用场景:

游戏排行榜 / 计分系统

高频访问、对性能要求极高的热点数据

热点缓存需要立即生效,DB 延迟可接受

高吞吐、读多写少的场景

DB 写操作是瓶颈,先更新缓存可以减少 DB 压力

三. 双删策略

并发问题:并发读写导致的缓存脏数据

假设有 三个事务 A、B、C,涉及 DB + Redis 缓存?

事务A:

deleteCache() // 删除缓存

updateDB() // 更新数据库

DB还没有更新完成

还没执行第二次删除缓存

事务 B(读操作):

cache miss // 缓存已被删除

read DB // 读到旧值(事务 A 还没提交/更新完成)

write cache // 回写旧值到缓存

事务C:

读取缓存中旧的数据

四 . canal监听Binlog日志

双删策略对比canal监听Binlog日志的劣势?

双删策略缺点?

  1. 时间窗口不太好控制

如果 sleep 太短 → 不一致仍可能

如果 sleep 太长 → 延迟大,业务性能受影响

  1. 业务耦合

每个更新操作都要手动加双删逻辑

多服务、多表、多缓存的情况下,维护成本高

  1. 无法扩展到多个下游系统

比如缓存 + Elasticsearch + MQ

双删只能针对单个缓存,无法保证其他下游系统同步

canal 监听 Binlog 的优势?

DB update → MySQL binlog → Canal → 消费端处理 → 更新缓存 / 下游系统

  1. 完全解耦业务

业务代码只管 DB,不用关心缓存

不会增加每个更新的复杂度

  1. 可扩展性

一个Canal消费端可以同时同步缓存,搜索引擎,消息队列等。

多个下游系统共享同一条 Binlog 数据,保证最终一致性

统一容错处理

Canal 自带消费重试

消费失败可以回溯 binlog

远比双删"sleep+delete"可控

五、为什么大规模系统不用双删而用 Canal

维度 双删 Canal

业务 耦合 强,每个更新都要写双删 弱,业务只管 DB

多下游系统 每个系统都要自己写双删 一条 Binlog 可以同步多个系统

可靠性 不可控,sleep 仍可能不一致 可控,Binlog 消费可重试

扩展性 差 好,适合微服务和大流量系统

可维护性 差 好, 统 一逻辑

双删适合小型、单服务、低流量场景;

Canal + Binlog 更新缓存适合大型、分布式、高并发场景,因为它解耦、统一、可重试,维护成本更低。

相关推荐
guodingdingh1 分钟前
软件开发工作问题总结0718
java·开发语言·数据库
GuWenyue2 小时前
Cursor黑盒拆解!1套LangChain.js手写Mini编程Agent,自动生成React项目,效率提升60%
前端·数据库·人工智能
Miao121314 小时前
某海外住宿平台如何在大规模场景下实现指标一致性:Minerva 指标平台实践
大数据·数据库·人工智能
CodexDave4 小时前
MySQL事务隔离级别与MVCC机制解析
前端·数据库·mysql·nginx·性能优化·负载均衡
碎光拾影4 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
曾阿伦4 小时前
MongoDB 查询语句备忘手册
数据库·mongodb
一叶龙洲4 小时前
wslg打开Ubuntu24.04默认打开图形界面
linux·服务器·数据库·ubuntu
CCPC不拿奖不改名4 小时前
大模型推理架构与开源生态知识整理
数据库·windows·python·架构·langchain·开源·github
爬也要爬着前进6 小时前
redis主从搭建
数据库·redis·缓存
@Mike@6 小时前
02-数据库学习笔记(SQL引擎)
数据库·笔记·学习