redis更新策略
1. 先更新缓存再更新数据库:在双写场景下,很容易出现一致性问题,在读写场景下,小概率出现一致性问题,所以Pass。
2. 先删除缓存再更新数据库:在双写场景下,不会出现一致性问题,在读写场景下,很容易出现一致性问题,所以Pass。
3. 先更新数据库再更新缓存:在双写场景下,很容易出现一致性问题,在读写场景下,小概率出现一致性问题,所以Pass。
4. 先更新数据库再删除缓存:在双写场景下,不会出现一致性问题,在读写场景下,小概率出现一致性问题,所以暂时保留。
5. 延迟双删 : 先进行缓存清除,再执行update ,最后(延迟N秒)再执行缓存清除。
延迟双删策略只是一种同步数据库与缓存的手段,在系统并发量不高的情况下可以使用这种方式解决,如果是并发量高的情况下我们也可以另寻其他解决方案 如:canal
redis过期策略
先区分两个概念,被动删除与主动删除
1 .被动删除:key 再被操作时,Redis主动检查key 是否过期,过期则删除;
优劣:对CPU友好,只有在被操作时删除,不浪费CPU时间;对内存不友好,如果同时大量key 过期,这些key 在被使 用前不会被删除造成资源浪费;
2 .主动删除:Redis会定期随机扫描一批设置了过期时间的key 并进行删除处理;当已用内存超过最大内存maxmemory时也会触发主动清除策略;
Redis采用的是定期删除 + 懒惰删除策略。
定期删除策略
Redis会将每个设置了过期时间的key 放入到一个独立的字典中,默认每 100 ms 进行一次过期扫描:
随机抽取20 个key ,删除这 20 个key 中过期的key ,如果过期的 key 比例超过 1 /4 ,就重复步骤 1 ,继续删除。
为什不扫描所有的 key?
Redis 是单线程,全部扫描岂不是卡死了。而且为了防止每次扫描过期的 key 比例都超过1 /4 ,导致不停循环卡死线程,Redis 为每次扫描添加了上限时间,默认是 25 ms。
如果在同一时间出现大面积 key 过期,Redis 循环多次扫描过期词典,直到过期的key 比例小于1 /4 。这会导致卡顿,而且在高并发的情况下,可能会导致缓存雪崩。
从库的过期策略
从库不会进行过期扫描,从库对过期的处理是被动的。主库在key到期时,会在AOF文件里增加一条del 指令,同步到所有的从库,从库通过执行这条 del 指令来删除过期的 key。
因为指令同步是异步进行的,所以主库过期的 key 的 del 指令没有及时同步到从库的话,会出现主从数据的不一致,主库没有的数据在从库里还存在。
懒惰删除策略
Redis 为什么要懒惰删除(lazy free)?
删除指令 del 会直接释放对象的内存,大部分情况下,这个指令非常快,没有明显延迟。不过如果删除的 key 是一个非常大的对象,
比如一个包含了千万元素的 hash ,又或者在使用 FLUSHDB 和 FLUSHALL 删除包含大量键的数据库时,那么删除操作就会导致单线程卡顿。
redis 4.0 引入了 lazyfree 的机制,它可以将删除键或数据库的操作放在后台线程里执行, 从而尽可能地避免服务器阻塞。
Redis 4.0 之前有以下 6 种淘汰策略:
noeviction:不淘汰任何数据,当内存不足时,新增操作会报错,读请求不受影响,Redis 默认内存淘汰策略;
allkeys-lru:淘汰整个键值中最久未使用的键值;
allkeys-random:随机淘汰任意键值;
volatile -lru:淘汰所有设置了过期时间的键值中最久未使用的键值;
volatile -random:随机淘汰设置了过期时间的任意键值;
volatile -ttl:优先淘汰更早过期的键值。
在 Redis 4.0 版本中又新增了 2 种淘汰策略:
volatile -lfu:淘汰所有设置了过期时间的键值中,最少使用的键值;
allkeys-lfu:淘汰整个键值中最少使用的键值。
其中 allkeys-xxx 表示从所有的键值中淘汰数据,而 volatile -xxx 表示从设置了过期键的键值中淘汰数据。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构