Redis中的内存淘汰策略和过期删除策略
127.0.0.1:6379> config set maxmemory 1GB
maxmemory参数默认值为0。我们在使用redis 最好根据实际情况设置其内存大小。放在。redis占用太多内存,导致其他程序不可用。
内存淘汰策略
1.内存没满,但是key过期了 怎么淘汰的?
过期删除策略 进行淘汰
2.内存满了怎么淘汰的
LRU LFU 进行淘汰
Redis中共有下面六种内存淘汰机制:
noeviction: 当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用吧,实在是太恶心了(redis默认的)。
allkeys-Iru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。
allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key,这个
一般没人用吧,为啥要随机,肯定是把最近最少使用的 key 给干掉啊。
volatile-Iru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近
最少使用的 key(这个一般不太合适)。
volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机
移除某个key。
volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。
客户端执行一条新命令,导致数据库需要增加数据(比如set key value)
Redis会检查内存使用,如果内存使用超过 maxmemory,就会按照置换策略删除一些 key
新的命令执行成功
双向链表的查找时间复杂度是O(n),删除和插入是O(1),借助HashMap结构,可以使得查找的时
间复杂度变成O(1)
链表满了,把链表尾部的数据丢弃掉,新加入的缓存直接加入到链表头中。
当链表中的某个缓存被命中时,直接把数据移到链表头部,原本在头节点的缓存就向链表尾部移动
随机采集淘汰的key,每次随机选出5个key(官方推荐5个就足够了,最多不超过10个,越大就越消耗CPU的资源)
然后淘汰这5个key中最少使用的key
maxmemory-samples 5
Redis中维护一个大小为16的候选池,当第一次随机选取采用数据时,会把数据放入到候选池中,
并且候选池中的数据会更具时间进行排序。
当第二次以后选取数据时,只有小于候选池内最小时间的才会被放进候选池。
当候选池的数据满了之后,那么时间最大的key就会被挤出候选池。当执行淘汰时,直接从候选池
中选取最近访问时间小的key进行淘汰。
LFU(Least Frequently Used),表示最近最少使用,它和key的使用次数有关,其思想是:根据key最
近被访问的频率进行淘汰,比较少访问的key优先淘汰,反之则保留。
当添加元素时,找到相同访问频次的节点,然后添加到该节点的数据链表的头部。如果该数据链表
满了,则移除链表尾部的节点
当获取元素或者修改元素是,都会增加对应key的访问频次,并把当前节点移动到下一个频次节
点。

TTL淘汰
Redis 数据集数据结构中保存了键值对过期时间的表,即 redisDb.expires。与 LRU 数据淘汰机制类似,
TTL 在设置了过期时间的key中,淘汰过期时间剩余最短的。
过期删除策略
前面介绍的LRU和LFU算法都是在Redis内存占用满的情况下的淘汰策略,那么当内存没占满时在Redis中过期的key是如何从内存中删除以达到优化内存占用的呢?
在Redis中过期的key不会立刻从内存中删除,而是会同时以下面两种策略进行删除:
惰性删除:当key被访问时检查该key的过期时间,若已过期则删除;已过期未被访问的数据仍保持在内存中,消耗内存资源;
定期删除:默认每隔100ms时间,随机检查设置了过期的key并删除已过期的key;维护定时器消耗CPU资源;
Redis每10秒进行一次过期扫描:
1.随机取20个设置了过期策略的key;
2.检查20个key中过期时间中已过期的key并删除;
3.如果有超过25%的key已过期则重复第一步;
这种循环随机操作会持续到过期key可能仅占全部key的25%以下时,并且为了保证不会出现循环过多的情况,默认扫描时间不会超过25ms;
AOF和RDB的过期删除策略
前面介绍了Redis的持久化策略RDB和AOF,当Redis中的key已过期未删除时,如果进行RDB和AOF的持久化操作时候会怎么操作呢?
在RDB持久化模式中我们可以使用save和bgsave命令进行数据持久化操作
在AOF持久化模式中使用rewriteaof和bgrewriteaof命令进行持久化操作
这四个命令都不会将过期key持久化到RDB文件或AOF文件中,可以保证重启服务时不会将过期key载入Redis。
为了保证一致性,在AOF持久化模式中,当key过期时候,会同时发送DEL命令给AOF文件和所有节点;
从节点不会主动的删除过期key除非它升级为主节点或收到主节点发来的DEL命令;
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
· 面试官:你是如何进行SQL调优的?