【Redis】 吃透Redis缓存与数据库双写一致性|4大策略+延时双删+Canal强一致方案(面试必刷)
2026/6/3 0:26:49 网站建设 项目流程

大家好,我是程序员二叉。


简介

Redis + MySQL主流架构中,缓存与数据库数据不一致是后端开发、面试高频重难点。很多线上故障、脏数据问题都源于双写流程设计不合理。

本文系统性梳理四种双写策略、两大主流执行顺序优劣、延时双删原理,以及金融级Canal订阅Binlog强一致性方案,全程标注重点、核心坑点,干货拉满,可直接收藏学习。欢迎点赞收藏关注。


一、为什么会出现双写不一致?

核心重点
数据库和缓存是两个独立存储组件,更新操作无法做到原子执行
一旦两次操作顺序错乱、并发交织,就会出现:

  • 数据库已更新,缓存还是旧数据
  • 缓存更新完成,数据库未同步
    最终产生脏数据,影响业务正常使用。

二、缓存+数据库 四种双写策略(全对比)

1. 先更新数据库 → 再更新缓存

强烈不推荐,线上禁用
执行流程:更新DB → 更新Redis
致命问题
高并发场景下,后提交的数据库请求,反而先完成缓存更新,新数据被旧数据覆盖,永久数据不一致。

2. 先更新数据库 → 再删除缓存

业界主流通用方案(首选)
执行流程:更新DB → 删除Redis对应Key
核心思路:采用懒加载,查询时再回填最新数据。

优点
  1. 规避缓存互相覆盖问题,逻辑简单、性能高
  2. 冷数据自动淘汰,节省Redis内存
  3. 并发冲突概率极低,绝大多数业务场景完全够用
缺点(极端边界场景)

读+写并发交织会短暂出现脏数据:

  1. 读请求A:缓存未命中,查询MySQL拿到旧数据
  2. 写请求B:更新MySQL,并删除缓存
  3. 读请求A:把拿到的旧数据写入缓存

该场景发生条件苛刻,正常业务流量下几乎不会触发。

3. 先删除缓存 → 再更新数据库

不推荐,高并发必出问题
执行流程:删除Redis → 更新DB

优点

流程直观,新手易理解

致命缺点

高并发读写场景极易产生永久脏数据

  1. 写请求A:删除缓存,开始更新数据库
  2. 读请求B:缓存为空,查询MySQL拿到旧数据,写入缓存
  3. 写请求A:数据库更新完成

最终结果:DB是新数据,缓存是旧数据,数据永久不一致。

4. 基于Binlog异步更新缓存

强一致性方案(金融/支付核心业务首选
执行流程:业务只操作DB → 中间件监听Binlog → 异步更新缓存
下文单独详解,适合零容忍脏数据场景。


三、延时双删策略(优化「先删缓存再更新DB」)

1. 适用场景

业务强制要求使用先删缓存流程,又要解决并发脏数据问题,采用延时双删做兜底。

2. 完整执行流程

  1. 第一次删除缓存
  2. 更新数据库
  3. 线程休眠一段时间(延迟等待)
  4. 第二次删除缓存

3. 原理详解

核心重点
休眠时间需要大于「查询数据库 + 写入缓存」的最大耗时
目的:把并发读请求回填到缓存的旧数据再次清除,保证缓存为空,下次查询加载最新数据。

4. 优缺点

优点

有效解决「先删缓存」带来的并发脏数据问题,架构改动小。

缺点
  1. 线程休眠阻塞请求,接口性能下降
  2. 延迟时间依赖经验配置,难以精准适配所有网络环境
  3. 仅保证最终一致性,无法做到实时强一致

四、 强一致性终极方案:Canal 订阅 MySQL Binlog

1. 适用场景

金融、电商交易、支付、订单等不允许出现任何脏数据,对数据一致性要求极高的业务。

2. 核心原理

业务代码只操作数据库,完全不触碰缓存,依靠中间件实现缓存同步,做到解耦+强一致。

3. 整体架构&执行流程

  1. 业务请求执行增/改/删,更新MySQL数据库
  2. MySQL 数据变更,自动记录Binlog 二进制日志
  3. Canal伪装成MySQL从节点,实时监听、拉取Binlog日志
  4. Canal 解析日志,提取表名、主键、变更后数据
  5. 将数据变更消息投递到RocketMQ/Kafka消息队列
  6. 消费服务监听MQ,消费消息并更新/删除Redis缓存

4. 核心优势

  1. 数据强一致:数据库为唯一数据源,缓存被动同步,从根源避免双写错乱
  2. 业务零侵入:原有代码无需改动,同步逻辑完全独立
  3. 高可用&削峰:依靠MQ异步解耦,不影响主业务吞吐量
  4. 支持重试、故障恢复,稳定性远高于代码硬编码双写

5. 缺点

架构复杂度提升,需要维护 Canal、MQ 等中间件,运维成本更高。


五、 方案选型总结(线上落地指南)

  1. 普通业务、允许短暂不一致
    优先选择:先更新数据库,再删除缓存

实现简单、性能最优,互联网绝大多数项目通用。

  1. 历史架构固定,必须先删缓存
    选择:延时双删策略

作为兜底优化方案,折中解决并发问题。

  1. 核心交易、金融、支付等强一致场景
    选择:Canal + Binlog + MQ 异步同步

工业级强一致方案,零脏数据风险。


六、总结(面试速记 精简背诵版)

  1. 先更库再更缓存:并发覆盖,直接淘汰
  2. 先更库再删缓存:主流方案,冲突概率极低
  3. 先删缓存再更库:高并发必脏数据,慎用
  4. 延时双删:删缓存 → 更库 → 延时 → 再删缓存,兜底旧数据
  5. Canal订阅Binlog:强一致终极方案,监听数据库日志异步更新缓存

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询