缓存策略的一些思考问题和解答(缓存过期时间、更新、二阶段提交)

文章以提问、答的方式进行
在这里插入图片描述

问:缓存设置永久吗?
答:缓存不能设置永久,因为永久是不可靠的。如果不是常更新的,设置较长时间。

资源管理:永久缓存会导致内存浪费(如长期未访问的数据占据空间),需通过LRU策略或定期清理释放资源。
数据兜底:即使业务数据更新频率极低,也需设置较长但有限的过期时间(如30天),防止极端情况下旧数据无法自动失效。
静态数据(如国家列表)可设置较长时间,但需保留手动清除能力。

问:什么时候更新 redis key?
答:更新时删除缓存,查询时加缓存。

采用 “延迟双删”策略 避免并发脏读:
写操作流程:
Step 1:删除旧缓存 → 更新数据库 → 延迟数百毫秒 → 再次删除缓存(应对主从延迟期间的脏读)
示例代码:结合消息队列延迟触发第二次删除
读操作流程:
查询缓存无数据 → 加分布式锁 → 查数据库 → 回填缓存 → 释放锁(防止并发重复回填)

问:经常走到没有key的缓存怎么办?
答:用空value解穿透。一般是空对象 {},而不是空字符,因为空字符有时候是有业务含义的。

空对象设计优化:
空值需设置短过期时间(如30秒),避免长期占用内存。
示例命令:SET user:-1 “{}” EX 30(明确标记无效数据)
布隆过滤器增强:
初始化时预加载合法Key(如预热用户ID列表),拦截非法请求。
需定期同步数据库新增数据(如通过定时任务更新过滤器)。

问:库和缓存哪个先更新?
答:先更新库,再更新缓存。反之可能缓存更新之后,在更新库之前又更新了缓存。

写操作严格流程:
数据库优先:
更新数据库 → 删除缓存 → 异步监听数据库Binlog → 确保从库同步后二次删除缓存
异常处理:
若删除缓存失败,通过重试机制(如Redis的retry policy)或记录日志人工干预。

问:库更新成功后,因为主从延迟,有些人查询从库更新了缓存,缓存又是旧的了,怎么办?
答:可以考虑延迟异步双写,在从库更新后,缓存再更新一次。

基于Binlog的最终一致性方案:
监听主库日志:
使用Canal或Debezium订阅数据库Binlog,仅在主库更新后触发缓存删除。
版本号标记:
数据写入时增加版本号,缓存Value包含版本标识,查询时校验版本一致性。

问:库更新成功,缓存更新失败,或部分失败怎么办?缓存一致性如何保证?
答:部分失败用LUA保证原子性。不过不管怎么做还是会缓存不一致。最终还是得二阶段提交来保证缓存一致性。

分级一致性策略:
最终一致性(通用场景):
异步消息队列(如Kafka)保证删除缓存的最终执行。
示例流程:
更新数据库 → 发送延迟消息 → 消费者接收消息 → 删除缓存
强一致性(金融级场景):
使用Seata等分布式事务框架,但需接受性能损耗(TP95延迟增加20%~30%)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值