缓存与数据库一致性的核心方案

缓存与数据库一致性的核心方案

一、旁路缓存 (Cache Aside)

适用场景:读多写少的业务场景,是目前业务开发中最常用的缓存一致性方案。

1. 核心执行逻辑

读流程

优先查询缓存,若缓存未命中,再查询数据库,最后将数据库查询结果回写至缓存,供后续请求复用。

写流程

先更新数据库,再删除缓存数据。

核心说明 :写操作优先选择删除缓存而非更新缓存。删除操作具备简单、幂等的特性,能够有效规避并发写场景下的数据一致性问题,避免缓存数据与数据库数据错乱。

2. 核心痛点及解决方案

痛点一:高并发读写一致性问题

受网络延迟、读写并发、数据库主从同步延迟、事务未提交等因素影响,会出现缓存数据被污染的问题,具体执行流程如下:

  1. 线程A执行数据更新操作,率先完成数据库数据更新;

  2. 线程A随即删除对应缓存数据;

  3. 此时线程B发起数据读取请求,缓存为空触发数据库查询逻辑;

  4. 因数据库主从同步延迟、线程A事务未完全提交等原因,线程B查询到数据库旧数据;

  5. 线程B将查询到的旧数据回写入缓存,最终形成数据库为新数据、缓存为旧数据的不一致状态,且该错误数据会一直留存,直至缓存过期。

常规优化方案 :延迟双删策略,延迟时间常规设置为 200ms~500ms,错开读写并发的时间窗口,避免旧数据回写缓存。

痛点二:缓存删除失败问题

若直接删除缓存失败,会导致缓存留存旧数据,引发数据不一致。可将缓存删除操作交由MQ处理,依托MQ的消息重试、持久化机制,保障缓存删除操作最终执行成功。

3. 终极解决方案:Canal 监听 Binlog

通过Canal组件监听MySQL的Binlog日志(读写分离架构下监听从库Binlog),异步感知数据库数据变更,自动执行缓存删除或更新操作。该方案对业务代码完全无侵入,可靠性极高,可同时解决上述两大痛点。

方案核心原理(MySQL 两阶段提交机制)
  1. Prepare阶段:InnoDB引擎将数据写入redo log日志,并将事务状态标记为prepare;

  2. Binlog写入阶段:记录数据逻辑变更信息,写入Binlog日志并刷盘持久化;

  3. Commit阶段:InnoDB将redo log事务状态更新为commit,完成事务提交。

MySQL宕机恢复机制:若事务在Commit阶段宕机,重启后MySQL会校验Binlog完整性。只要Binlog日志已完整写入,即便redo log处于prepare状态,MySQL也会判定事务有效并自动提交。因此,只要Canal读取到Binlog日志,即可判定数据库数据已提交生效,以此保障缓存更新的准确性。

方案优势

传统MQ手动更新方案需改造业务代码,针对Redis、ES、大数据平台等不同中间件单独发送消息,代码冗余且扩展性差。而Canal可作为统一数据分发中心,通过下游配置多组消费者,分别处理Redis缓存更新、ES索引更新、HBase数据同步等需求,大幅简化业务架构。

4. 实战落地

实际开发中,可基于RedisTemplate、Jedis等主流Redis客户端,二次封装通用的CacheService缓存工具类,统一处理缓存查询、删除、更新等操作。

二、读/写直通 (Read/Write Through)

核心特性 :保障缓存与数据库强一致性,适用于对数据准确性、一致性要求极高的核心业务场景。

1. Read Through(读直通)

由缓存服务统一接管数据查询逻辑。业务请求查询数据时,若缓存未命中,缓存服务主动同步查询数据库,将数据加载至缓存后,再返回结果给业务应用,应用无需直接操作数据库。

2. Write Through(写直通)

由缓存服务统一接管数据写入逻辑。业务应用仅需写入缓存,缓存服务会同步将数据更新至数据库,仅当数据库写入成功后,才向应用返回写入成功结果。

3. 核心痛点

所有读写操作均需同步联动数据库,链路耗时较长,接口响应延迟高,并发性能较差。

4. 技术实现

Ehcache缓存框架原生提供CacheLoader(读加载)、CacheWriter(写写入)接口,开发者完成配置后,调用cache.put()等缓存方法,框架会自动执行数据库CRUD操作,无需手动编写SQL。

三、异步写回 (Write Back / Write Behind)

核心特性:以数据一致性为代价,极致提升写入并发性能,适用于高并发、弱一致性业务场景。

1. 执行逻辑

业务应用写入数据时,仅更新缓存即可立即返回成功结果,无需等待数据库写入。缓存服务会异步、批量将缓存中的增量数据刷入数据库,大幅提升接口吞吐能力。

2. 解决问题

完美适配超高并发写入场景,避免大量高频写请求直接冲击MySQL,导致数据库压力过载、宕机。

3. 核心痛点

存在数据丢失风险。若缓存节点在数据异步落库前宕机,未同步至数据库的缓存更新数据会永久丢失,无法恢复。

4. 典型应用场景

  • 社交媒体统计数据:点赞数、阅读量、浏览量等场景,少量数据误差不影响用户体验,但并发量极高,无法直接落地数据库;

  • 操作系统磁盘缓存:系统write()文件写入调用,采用的就是Write Back机制,数据先写入内存Page Cache,再由内核线程异步刷入硬盘。

相关推荐
我叫张小白。1 小时前
基于Redis的缓存架构与一致性保障体系
数据库·redis·缓存·架构
我是一颗柠檬2 小时前
【Redis】数据类型详解Day2(2026年)
数据库·redis·后端·缓存
土狗TuGou2 小时前
SQL内功笔记 · 第7篇:CTE&临时表&递归
数据库·笔记·后端·sql·mysql
我是唐青枫2 小时前
MySQL EXISTS 详解:存在性判断、NOT EXISTS 与实战示例
数据库·mysql
稚枭天卓2 小时前
mac 安装mysql
mysql·macos
念恒123062 小时前
MySQL事务(下)---MySQL InnoDB MVCC 与 Read View:从隐藏列、Undo Log 到 RR 与 RC 的本质区别
数据库·mysql·oracle
Rick19933 小时前
什么是Redis的 IO 多路复用
redis·缓存
Java面试题总结3 小时前
MySQL EXISTS 详解:存在性判断、NOT EXISTS 与实战示例
android·数据库·mysql
您^_^3 小时前
ClaudeCode最近更新导致第三方模型Token消耗率暴涨,缓存命中也相当夸张!!
人工智能·windows·缓存·个人开发·claudecode·deepseek v4 pro