当前位置: 首页 > news >正文

Redis 删除缓存失败怎么办?重试、死信、补偿的工程化方案

这篇聊一个很现实的问题:数据库已经改成功了,但缓存删除失败了,线上怎么办?

先给答案

如果你项目里只有一句redis.del(key),那一致性是靠运气。

一套更稳的做法是:

  1. 主流程里先写库再删缓存
  2. 删除失败立刻进入重试队列
  3. 超过重试上限进入死信队列
  4. 死信触发告警和人工/自动补偿
  5. 全链路打点,能看见“删失败率”和“补偿成功率”

一句话:删除缓存不是一个动作,而是一条可观测、可补偿的链路。


为什么“删缓存失败”必须单独设计

很多同学会说:“删失败就下次再读库呗。”

这句话在低并发时看起来没毛病,但线上高峰期会出事:

  • 热点 key 还在,用户继续读到旧值
  • 读流量越大,旧值传播越快
  • 你又没有补偿机制,脏数据会“活很久”

最麻烦的是:这个问题不会立刻报错,而是以“偶发投诉”“数据不对”的形式出现,排查成本很高。


一个真实可落地的链路

成功

失败

成功

失败超过阈值

业务写请求

更新 MySQL

删除 Redis key

返回成功

发送重试消息

消费者重试删除

记录成功指标

进入死信队列

告警通知

补偿任务

你会发现,核心不是“怎么删”,而是“删不掉时怎么兜”。


代码示例:主流程 + 异步重试

1. 主流程(写库后删缓存)

@ServicepublicclassProductService{@ResourceprivateProductMapperproductMapper;@ResourceprivateStringRedisTemplateredisTemplate;@ResourceprivateCacheDeleteProducercacheDeleteProducer;@Transactional(rollbackFor=Exception.class)publicvoidupdateProduct(Productproduct){Stringkey="product:"+product.getId();// 1) 数据库是事实来源productMapper.updateById(product);// 2) 主流程删缓存,失败则入重试队列try{redisTemplate.delete(key);}catch(Exceptionex){cacheDeleteProducer.sendDeleteEvent(key,1);}}}

2. 重试消费者(指数退避 + 最大次数)

@ComponentpublicclassCacheDeleteConsumer{privatestaticfinalintMAX_RETRY=5;@ResourceprivateStringRedisTemplateredisTemplate;@ResourceprivateCacheDeleteProducercacheDeleteProducer;@ResourceprivateDeadLetterProducerdeadLetterProducer;publicvoidonMessage(CacheDeleteEventevent){try{redisTemplate.delete(event.getCacheKey());// 打点:delete_success_total +1}catch(Exceptionex){intnextRetry=event.getRetryCount()+1;if(nextRetry>MAX_RETRY){deadLetterProducer.send(event.getCacheKey(),ex.getMessage());return;}longdelaySeconds=(long)Math.pow(2,nextRetry);// 2,4,8,16,32cacheDeleteProducer.sendDeleteEvent(event.getCacheKey(),nextRetry,delaySeconds);}}}

3. 死信补偿任务(定时巡检)

@ComponentpublicclassCacheDeleteCompensationJob{@ResourceprivateDeadLetterRepositorydeadLetterRepository;@ResourceprivateStringRedisTemplateredisTemplate;// 每 5 分钟跑一次@Scheduled(cron="0 */5 * * * ?")publicvoidcompensate(){List<DeadLetterRecord>records=deadLetterRepository.queryUnresolved(200);for(DeadLetterRecordrecord:records){try{redisTemplate.delete(record.getCacheKey());deadLetterRepository.markResolved(record.getId());}catch(Exceptione){deadLetterRepository.increaseFailCount(record.getId(),e.getMessage());}}}}

这 5 个细节,决定你方案能不能用

  1. 幂等性
    删缓存天生幂等,删不存在 key 也算成功,别把它当异常。

  2. 重试上限
    不要无限重试,超过阈值必须死信,不然就是隐性消息堆积。

  3. 退避策略
    固定 1 秒重试容易打爆 Redis,用指数退避更稳。

  4. 死信可见性
    死信不等于丢弃,要有告警和处理面板。

  5. 链路监控
    至少要有这几个指标:

  • cache_delete_fail_total
  • cache_delete_retry_total
  • cache_delete_dlt_total
  • cache_delete_compensation_success_total

常见误区

误区 1:删失败概率很低,可以忽略

线上你总会遇到:网络抖动、Redis 短暂超时、连接池耗尽。
低概率 * 高频请求 = 可观事故数。

误区 2:有延迟双删就够了

延迟双删只能覆盖一部分并发窗口,无法替代失败重试链路

误区 3:死信就是失败,人工看就行

只靠人工盯死信,夜里一定会漏。
最好是“告警 + 自动补偿 + 人工兜底”三层。


选型建议(按团队规模)

团队阶段推荐方案
小团队、单体服务写库后删缓存 + 本地重试(短期)
中型团队、多服务写库后删缓存 + MQ 重试 + 死信告警
大团队、高一致性要求事件驱动一致性 + 死信平台 + 自动补偿任务

最后总结

“删除缓存失败”不是小概率边角料,它是缓存一致性的主战场。

真正能扛线上流量的方案,通常长这样:

  1. 主链路快:写库后删缓存
  2. 失败可恢复:异步重试
  3. 极端可兜底:死信补偿
  4. 整体可观测:指标和告警

把这四件事做到位,你的缓存一致性就不是“玄学”,而是工程能力。

http://www.cnnetsun.cn/news/1870436.html

相关文章:

  • 写给传统 IT 部门:AI Agent Harness Engineering 转型指南
  • C语言逆向学习基础课 第 11 课:宏定义与位运算陷阱详解
  • Nginx-UI 终极安装指南:快速解决端口配置与访问失败的完整方案
  • Python实战:利用cdsapi高效批量下载ERA5日尺度气象数据
  • 致远OA A8 任意用户登录漏洞深度剖析与利用链还原
  • 利用apk2url高效挖掘APK中的网络资产:IP与URL节点提取实战
  • WarcraftHelper:让魔兽争霸III在现代电脑上焕发新生的终极解决方案
  • placo实战:如何利用C++与Python绑定实现机器人高精度运动控制
  • 国产数据库认证之路:从TiDB到OceanBase的实战心得与选型启示
  • 别再怕交换机堆叠配置了!手把手教你用H3C IRF搞定两台S5130的堆叠与MAD BFD检测
  • 基于WIFI的家用可燃气体监控系统的设计与实现(有完整资料)
  • Chord开源大模型实战:增量训练适配垂直领域(如医学影像术语)
  • 微信小程序授权登录
  • 深入理解ES6 Promise
  • Python电子书处理终极指南:如何用EbookLib轻松管理EPUB文件
  • STM32H743双CAN总线负载太高?试试用CubeIDE+CanFestival同时跑两个CANopen主站
  • 深度解析Unity资源管理:YooAsset 2.2.12跨平台加密方案完全指南
  • BiliTools:3步解锁哔哩哔哩高效学习新体验,让知识获取速度提升300%
  • 5个简单步骤:使用Campus-Imaotai实现茅台自动预约的完整指南
  • Redis 高级篇(最佳实践)
  • 解锁博士论文“超能力”:好写作AI,学术征途的“超级外挂”
  • 把 ABAP RFC Gateway 日志真正配明白,SMGW、gw/logging 与 secinfo、reginfo 的实战思路
  • 【自动驾驶】从轨迹规划到安全评估:核心术语场景化解读
  • CoPaw驱动智能RPA:通过自然语言指令自动化办公流程
  • Windows 11系统优化指南:用Win11Debloat释放40%系统性能
  • 终极指南:如何绕过Windows驱动签名强制验证(DSEFix完整教程)
  • SystemVerilog--- task---高效调试与验证技巧
  • DeepSeek-R1-Distill-Qwen-1.5B实战:低配电脑也能流畅运行的代码助手
  • 图图的嗨丝造相-Z-Image-Turbo多场景落地:动漫同人图/轻小说插画/游戏立绘
  • 003、YOLO初探:目标检测核心思想与YOLO系列模型演进史