连载中 7/20

延迟双删与 Binlog 订阅:把同步做稳

2026-05-27 · 5911 阅读 · 0 评论 · 0 赞

先库后缓存的两根尾巴

上一篇定了写路径的主轴:更新库、删缓存。但两根尾巴还挂着。第一根是主从延迟:读走从库的架构里,主库刚更新、从库还没同步完,此刻删掉缓存,读请求回源查的是从库——查回的还是旧值,又把它填回缓存。旧值不仅复活,还合法。第二根是并发竞态:读请求在库更新前查到旧值,又在缓存删除后才回填,概率低但不是零。延迟双删,就是冲这两根尾巴去的。

延迟双删:再删一次

思路很直白:既然脏数据可能在删除之后被回填,那就在第一次删除之后再补一刀——更新库、删缓存、睡一会儿、再删一次。第二次删除清掉竞态期间被回填的旧值,窗口从「到 TTL 为止」压到「两次删除之间」:

@Transactional
public void updateItem(Item item) {
    itemDao.update(item);                 // 更新主库
    redis.del(key);                       // 第一次删缓存
    delayExecutor.schedule(() ->
        redis.del(key), 500, MILLISECONDS); // 延迟再删一次
}

延迟多久?原则是盖过「读从库回源并回填」的整个耗时,工程上常取主从同步延迟加读接口耗时的总和,几百毫秒到一秒不等,再留点余量。第二次删除丢进延迟队列或线程池异步执行,别让它拖住写请求。方案不优雅——延迟时长靠拍脑袋、二次删除也可能失败——但它简单、够用,是一致性加固的第一选择。

Binlog 订阅:把删缓存从代码里拿走

延迟双删再稳,也改变不了一个事实:删缓存这件事写在业务代码里。每个写接口都要记得删、删对 key、处理失败,几十个接口散落各处,漏一处就是一条不一致的暗线。binlog 订阅换个思路:数据库的变更都会写进 binlog,让一个中间件伪装成 MySQL 的从库把变更收下来,收到哪个表变了,就删对应的缓存:

Canal(伪装从库) ──订阅──> MySQL binlog
     │ 收到 item 表 UPDATE
     ▼
组装缓存 key ──> DEL cache ──失败──> 进 MQ 重试

收益立刻显现:业务代码只管写库,删缓存彻底下线;binlog 是库变更的完整事实,不可能漏删;删除失败走消息队列重试,最终一致有了闭环。代价也要认:链路变长——binlog 到 Canal 有毫秒到秒级延迟,中间件本身要运维、要防故障,表结构与缓存 key 的映射规则要维护。它是重装备,适合缓存 key 多、写入路径散、一致性要求高的系统。

怎么选,看规模

两个方案不是对手,是台阶。中小规模:Cache Aside 加延迟双删加 TTL 兜底,业务代码可控、问题可查,够了。大规模:写入路径多、团队大、key 散,binlog 订阅把一致性问题收口到一个中间件里统一治理,值得上。共同的底座是 TTL——无论上层怎么设计,过期时间永远在,最坏情况永远有界。最终一致是工程默认,强一致请回头加锁或直接读库

一致性的大山翻完,缓存系统还有另一类日常问题:缓存空着的时候怎么办。新服务上线、Redis 重启、大促前夕,冷启动的缓存等于没有缓存——预热这门功课,下一篇开讲。

503

10 年全栈工程师 · 503咖啡馆主理人

#延迟双删#Canal#binlog订阅#主从延迟#最终一致

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞