【Redis】双写一致性:延迟双删 / 读写锁 / 异步通知 / Canal,一文全解
在后端系统架构中为了提升读请求性能、减轻数据库压力我们通常会引入 Redis 等分布式缓存将热点数据缓存起来形成「数据库MySQL 缓存Redis」的双层存储架构。而双写一致性就是指在这种架构下当数据发生变更时如何保证数据库中的数据与缓存中的数据保持一致避免出现“缓存存旧值、数据库存新值”或“缓存有值、数据库无值”的脏数据问题确保业务查询结果的准确性。前言MySQL与Redis双写一致性解决方案保证MySQL和Redis双写一致性核心是根据业务对“一致性/性能”的要求选择方案我从核心方案、进阶方案、兜底方案三个维度结合优缺点和底层逻辑给您讲清楚可以根据业务场景选择下述缓存一致性方案缓存双删如果公司现有消息队列中间件可以考虑使用该方案反之则不需要考虑。先写数据库再删缓存这种方案从实时性以及技术实现复杂度来说都比较不错推荐大家使用这种方案。Binlog 异步更新缓存如果希望实现最终一致性以及数据多中心模式该方案无疑是最合适的。一、核心方案延迟双删最常用适配80%场景延迟双删其实是对「先删缓存再更新数据库」方案的优化和兜底而「先更新数据库再删缓存」是另一条独立的主流路径1. 核心流程写操作先删缓存 → 更新数据库 → 延迟N秒如1-5秒再删一次缓存读操作缓存命中直接返回 → 缓存未命中 → 查数据库 → 回写缓存 → 返回数据2. 各步骤优缺点步骤优点缺点先删缓存避免更新DB后旧缓存被读请求回填极端并发下仍可能出现脏数据更新数据库保证主数据DB准确性单步操作无额外缺点延迟删第二次缓存解决并发场景下的脏数据问题增加少量延迟需控制延迟时长读未命中查DB回写缓存保证缓存最终有数据提升读性能首次读/缓存失效时有DB查询开销不管是「先操作 Redis缓存再操作数据库」还是「先操作数据库再操作 Redis」本质上因为两个操作无法原子化执行且高并发下读 / 写请求的执行顺序不可控所以必然存在脏数据的可能。我用两个最典型的并发时序场景就能说清原因场景 1先删除缓存再操作数据库左侧时序线程 1写请求执行第 1 步 → 删除缓存缓存变为空线程 2读请求执行第 2 步 → 查询缓存未命中去数据库查到旧值20线程 2读请求执行第 3 步 → 把旧值20写入缓存线程 1写请求执行第 4 步 → 更新数据库为v20这里图里初始 DB 是 20实际业务里是从旧值更新为新值核心逻辑不变✅结果数据库是新值缓存里被写入了旧值 → 出现脏数据。场景 2先操作数据库再删除缓存右侧时序线程 1读请求执行第 1 步 → 查询缓存未命中去数据库查到旧值20线程 2写请求执行第 2 步 → 更新数据库为v20实际业务是从旧值更新为新值线程 2写请求执行第 3 步 → 删除缓存缓存变为空线程 1读请求执行第 4 步 → 把刚才查到的旧值20写入缓存✅结果数据库是新值缓存里被写入了旧值 → 同样出现脏数据。不管先操作哪一方问题的根源都是操作非原子性缓存和 DB 的操作是两步独立操作中间有时间窗口并发时序不可控高并发下读请求可能卡在 “查 DB 拿到旧值” 和 “回写缓存” 之间写请求刚好完成了更新导致旧值被写回缓存缓存回写机制读请求缓存未命中时会自动查 DB 并回写缓存这个 “回写” 动作是脏数据产生的最后一环。这也是为什么单纯的 “先操作 A 再操作 B” 解决不了问题需要延迟双删、加锁、异步通知等方案兜底的核心原因。3. 删两次/延迟删除为什么要删两次缓存解决“读请求在写请求更新DB前已查到旧值并准备回写缓存”的极端场景例① 读请求缓存失效 → ② 读DB拿到旧值 → ③ 写请求删缓存 → ④ 写请求更DB → ⑤ 读请求把旧值写入缓存 → ⑥ 延迟删缓存清空这个旧值。第二次删除是为了兜底清空并发场景下被误写入的旧缓存。为什么要延迟删除延迟时长需覆盖“读请求查DB回写缓存”的耗时一般1-5秒确保能删掉“被并发读请求回填的旧缓存”如果立刻删第二次可能读请求还没完成回写删了也没用。二、进阶方案互斥锁/读写锁强一致性场景互斥锁强一致、性能低读多写少一般采用缓存1. 互斥锁分布式锁如Redisson RLock流程写操作加排他锁→ 删缓存 → 更新DB → 释放锁读操作加共享锁→ 缓存未命中时加排他锁查DB回写缓存。优点严格保证数据强一致无脏数据缺点加锁会阻塞请求降低并发性能可能出现死锁需设置锁超时。2. 读写锁Redisson ReadWriteLock共享锁读锁多个读请求可同时加锁不阻塞保证读性能排他锁写锁写请求加锁后阻塞所有读/写请求保证写操作原子性适用场景读多写少、对一致性要求极高的场景如库存、优惠券缺点写请求会阻塞读请求高并发写场景性能下降。3.代码实现核心说明锁粒度读写锁使用同一个 keyITEM_READ_WRITE_LOCK保证读写互斥、读读共享。写锁逻辑写操作加排他锁期间所有读 / 写请求都会阻塞保证数据更新的原子性更新后删除缓存触发下一次读请求重建缓存。读锁逻辑读操作加共享锁多个读请求可并发执行写锁释放前读锁会等待避免读到脏数据。兜底保障finally块中释放锁确保即使业务异常也不会导致锁泄漏。排他锁写锁)publicvoidupdateById(Integerid){// 获取读写锁RReadWriteLockreadWriteLockredissonClient.getReadWriteLock(ITEM_READ_WRITE_LOCK);// 获取写锁RLockwriteLockreadWriteLock.writeLock();try{// 加写锁writeLock.lock();System.out.println(writeLock...);// 1. 更新业务数据示例模拟更新商品信息ItemitemnewItem(id,华为手机,华为手机,5299.00);try{// 模拟业务处理耗时Thread.sleep(10000);}catch(InterruptedExceptione){e.printStackTrace();}// 2. 删除缓存redisTemplate.delete(item:id);}finally{// 释放写锁writeLock.unlock();}}共享锁读锁publicItemgetById(Integerid){// 获取读写锁RReadWriteLockreadWriteLockredissonClient.getReadWriteLock(ITEM_READ_WRITE_LOCK);// 获取读锁RLockreadLockreadWriteLock.readLock();try{// 加读锁readLock.lock();System.out.println(readLock...);// 1. 先查询缓存Itemitem(Item)redisTemplate.opsForValue().get(item:id);if(item!null){// 缓存命中直接返回returnitem;}// 2. 缓存未命中查询业务数据示例模拟从数据库查询itemnewItem(id,华为手机,华为手机,5999.00);// 3. 写入缓存redisTemplate.opsForValue().set(item:id,item);// 4. 返回数据returnitem;}finally{// 释放读锁readLock.unlock();}}三、高级方案异步通知解耦高可用1. MQ异步通知方案流程更新DB → 发送“删除缓存”消息到MQ → 消费端监听消息 → 删除缓存核心优势利用MQ的持久化重试机制保证缓存最终被删除且业务线程无需等待缓存操作接口响应快缺点有代码侵入需业务主动发消息消息延迟可能导致短暂不一致。2. Canal阿里异步同步方案原理Canal伪装成MySQL从库读取MySQL的Binlog数据变更日志 → 解析Binlog → 异步更新/删除Redis缓存优点零业务代码侵入Binlog天然有序能保证更新顺序一致性更高缺点部署维护成本高Binlog解析有轻微延迟毫秒级不适合极致强一致场景。四、补充方案定时任务兜底对核心数据定时从DB全量同步到Redis修正可能的不一致适合数据变更频率低的场景TTL兜底给缓存设置合理过期时间即使出现脏数据也会自动过期保证最终一致全量更新不推荐写操作直接更新DB更新缓存优点是简单缺点是性能差很多更新无意义、并发下易出现数据覆盖。五、总结性能优先、允许短暂不一致选延迟双删核心 MQ/Canal兜底强一致性优先、读多写少选Redisson读写锁不想侵入业务代码、追求极致解耦选Canal方案中小规模业务延迟双删即可满足需求无需过度设计。关键点回顾延迟双删是基础方案两次删除的核心是解决“并发读回填旧缓存”问题延迟时长需覆盖读请求回写缓存的耗时互斥锁/读写锁保证强一致但牺牲性能适配库存、优惠券等核心场景MQ/Canal是异步解耦方案利用MQ可靠性/Canal零侵入特性保证最终一致性。

相关新闻

COMSOL模拟含裂缝地层流动与传热耦合:油藏数值模拟及裂缝交叉影响分析

COMSOL模拟含裂缝地层流动与传热耦合:油藏数值模拟及裂缝交叉影响分析

COMSOL含裂缝地层流动和传热耦合,油藏数值模拟,COMSOL裂缝流动,包含注入井与生产井,考虑裂缝交叉。裂缝性油藏开发总带着点"地下迷宫"的魔幻感。去年在页岩气项目里被裂缝网络搞到头皮发麻的经历还记忆犹新,…

2026/5/17 11:55:04 阅读更多 →
Windows创建用户和用户组及其作用

Windows创建用户和用户组及其作用

Windows 用户是登录系统的身份标识,用户组是用户的集合;创建用户用于身份隔离与权限分配,创建组用于批量统一管理权限,大幅提升效率与安全性。一、用户与用户组的核心作用1. 用户(User)身份隔离&#xff1a…

2026/5/17 11:55:04 阅读更多 →
别急着装“龙虾”:如何理性看待“自动赚钱”工具?

别急着装“龙虾”:如何理性看待“自动赚钱”工具?

最近,OpenClaw 成了一个热门话题,到处都能看到“AI新风口”、“躺着赚钱神器”的说法,似乎装上一个工具,生活就能自动变好。不少朋友也跟风试了,有的花钱找人代安装,有的买高价教程,还有的为此升…

2026/7/3 5:33:47 阅读更多 →

最新新闻

AI钓鱼攻击:从原理到防御,构建企业安全免疫系统

AI钓鱼攻击:从原理到防御,构建企业安全免疫系统

1. 项目概述:当钓鱼攻击披上AI的“羊皮” 如果你还认为钓鱼邮件是那种满屏错别字、用蹩脚英文催你点链接的“垃圾”,那你的安全观念可能还停留在五年前。我干了十多年网络安全,亲眼看着攻击手段从“广撒网”的群发垃圾邮件,进化到…

2026/7/4 12:14:52 阅读更多 →
如何永久保存微信聊天记录:免费开源工具让你的数字记忆永不丢失

如何永久保存微信聊天记录:免费开源工具让你的数字记忆永不丢失

如何永久保存微信聊天记录:免费开源工具让你的数字记忆永不丢失 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending…

2026/7/4 12:14:52 阅读更多 →
量子科技中的多样性与包容性实践

量子科技中的多样性与包容性实践

1. 量子科技领域为何需要关注多样性与包容性?量子计算、量子通信等量子科技正在重塑未来技术格局。与传统学科不同,量子科技本质上是一门高度交叉的领域,融合了物理学、计算机科学、材料学、工程学等多个学科。这种交叉性决定了其发展特别依赖…

2026/7/4 12:12:52 阅读更多 →
终极指南:3分钟解决Windows上iPhone USB网络共享驱动问题

终极指南:3分钟解决Windows上iPhone USB网络共享驱动问题

终极指南:3分钟解决Windows上iPhone USB网络共享驱动问题 【免费下载链接】Apple-Mobile-Drivers-Installer Powershell script to easily install Apple USB and Mobile Device Ethernet (USB Tethering) drivers on Windows! 项目地址: https://gitcode.com/gh_…

2026/7/4 12:10:51 阅读更多 →
SaToken实战:密码加密与会话查询的深度整合与应用

SaToken实战:密码加密与会话查询的深度整合与应用

1. 项目概述:为什么我们需要深度整合密码加密与会话查询? 在任何一个需要用户登录的现代Web应用中,安全都是悬在开发者头顶的达摩克利斯之剑。我们常常会陷入一种“头痛医头,脚痛医脚”的困境:用户注册时,我…

2026/7/4 12:10:51 阅读更多 →
Appium视觉测试实战:从像素对比到智能忽略的UI自动化回归方案

Appium视觉测试实战:从像素对比到智能忽略的UI自动化回归方案

1. 项目概述:为什么我们需要视觉测试?在移动应用自动化测试的征途上,我们常常会遇到一个令人头疼的问题:功能逻辑明明跑通了,按钮能点,数据能提交,但界面却“跑偏”了。可能是某个按钮在iOS 17上…

2026/7/4 12:08:51 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻