Redis 6与MariaDB 10.5数据同步最佳实践咨询
缓存与DB一致性的最佳实践及方案选择
一、维护Redis与MariaDB数据一致性的核心方案
1. 先更新DB,再同步缓存(适配你的额度扣减场景)
用户发起查询请求时,先执行MariaDB的扣减操作:
UPDATE user_quota SET available = available - 1 WHERE user_id = ? AND available >= 1;
确认DB更新成功后,再更新Redis缓存:
SET user:quota:{user_id} {new_available} EX 60
就算Redis更新失败也不用慌,因为缓存有60秒TTL,到期后会自动失效,下次请求会从DB拉取最新数据,最终一致性能得到保证。另外,扣减操作一定要依赖user_id的主键或索引,触发InnoDB的行锁,避免并发扣减导致超卖。
2. 缓存失效+延迟双删(解决并发脏读问题)
如果担心并发场景下出现脏缓存,可以在DB更新后做两次缓存删除:
- 第一步:DB扣减成功后,立即删除对应Redis缓存:
DEL user:quota:{user_id} - 第二步:延迟1~2秒(根据你的业务并发量调整),再次执行
DEL user:quota:{user_id}
这么做是为了防止在DB更新完成前,有其他请求读取旧值并写入Redis,延迟删除能把这个脏缓存清理掉,确保后续请求拿到的是DB最新数据。
3. Redis Lua脚本原子化操作(高并发场景优化)
如果你的API并发量较高,可以用Lua脚本封装缓存扣减逻辑,保证操作原子性:
local current = redis.call('GET', KEYS[1]) if current and tonumber(current) >= tonumber(ARGV[1]) then redis.call('DECRBY', KEYS[1], ARGV[1]) return redis.call('GET', KEYS[1]) else return nil end
使用时的流程是:先尝试用Lua脚本扣减Redis缓存,如果成功,异步更新MariaDB;如果缓存不存在或余额不足,再查询DB,扣减DB后同步更新缓存。注意要给异步更新DB加重试机制(比如本地消息队列),避免DB更新失败导致数据不一致。
二、弃用Redis,仅用MariaDB的可行性分析
如果觉得缓存一致性维护太麻烦,直接弃用Redis也是完全可行的:
- 性能足够:如果你的API并发量不算高(比如QPS低于1000),MariaDB单表带索引的扣减操作响应时间在毫秒级,完全能扛住。
- 架构简化:省去缓存层后,代码逻辑更简单,排查问题也不用跨Redis和DB两层,适合业余项目的维护。
- 后续扩展:如果以后并发量上来了,再考虑做DB读写分离、分库分表也不迟,初期优先简化架构。
三、针对你场景的推荐
因为你的Redis缓存TTL只有60秒,属于短期缓存,优先推荐先更DB再同步缓存的方案,实现成本低,最终一致性有保障。如果怕并发脏读,再加个延迟双删就行,定时器用简单的线程睡眠或者本地任务就能实现。
要是你的API并发量很低,直接弃用Redis反而更省心,减少不必要的架构复杂度。
内容的提问来源于stack exchange,提问作者Andre
相关产品推荐
相关产品推荐

