1.如何保证缓存和数据库的一致性?
常用方案:
-
Cache Aside(写后删缓存)
-
双写策略
-
MQ 异步保证最终一致性
**2.**Redis 事务失败能回滚吗?
不能回滚
解决方案:
-
使用 Lua 脚本 保证原子性
-
或在 应用层做补偿逻辑
应用层怎么补偿? 记录操作日志,用于补偿。
如果是新增数据,就删除缓存
如果是更新数据,就还原旧值或者删除缓存
如果是计数器,就减回去
注意,补偿逻辑必须 幂等;
2.1补偿失败了怎么办?
记录失败日志
告警人工介入
定时任务再次补偿
3.MySQL 事务回滚了,但 Redis 已经写成功了,怎么办?
这是一个分布式数据不一致问题,因为:MySQL 支持 事务回滚,而Redis 不支持回滚。两者不在同一个事务里。我们的目标不是"强行回滚",而是 最终一致性 + 应用层补偿
解决方案
通过 本地事务 + 可靠事件 + 补偿机制 保证最终一致性。
核心思想
以 MySQL 为准
Redis 允许短暂不一致
通过 补偿 / 对账 / 重试 修复
**✅ 方案一:应用层补偿(最常用)
执行流程**
- 开启 MySQL 事务
- 写 MySQL
- 写 Redis
- 如果 MySQL 提交失败 → 主动补偿 Redis
如果是新增数据,就删除缓存
如果是更新数据,就还原旧值或者删除缓存
如果是计数器,就减回去
注意,补偿逻辑必须 幂等;补偿失败要 记录日志 / 报警
✅ 方案二:先写 MySQL,后写 Redis(推荐)
mysql写成功再写redis
✅ 方案三:可靠事件 / MQ(进阶)
- MySQL 事务提交成功后
- 发送消息 → 更新 Redis
- 消费者失败 → 重试
常用于高并发、核心业务
✅ 方案四:定期对账(兜底)
定时任务扫描 MySQL
- 对比 Redis 数据
- 不一致 → 自动修复
4.为什么不直接删缓存
删缓存是 最常见、成本最低的补偿
但要注意并发下的 缓存击穿 / 雪崩