Redis内存管理
Redis内存管理
Redis的内存管理中,有两个主要的策略:过期删除策略和内存淘汰策略。
过期删除策略
过期删除策略指的是可以对 key 设置一个过期时间,并将已过期的键值对删除。
一般来说,Redis中的数据都会有一个过期时间。设置过期时间有这两个好处 :
- 因为内存是有限的,如果没有过期时间,很容易占满内存。
- 对于短信验证码之类有时效性的数据,如果放在数据库中就需要自己判断是否过期,这样不但麻烦而且性能较低。
设置过期时间的方法:
- 字符串类型:
setex <key> <time> <valule>
(setex == set + expire ,添加了键值对并且设置过期时间) - 其他类型:
expire <key> <time>
查看剩余过期时间的方法: ttl <key>
、 取消过期剩余时间的方法: persist <key>
Redis如何判断过期?
Redis 通过一个叫做过期字典(可以看作是 hash 表)来保存数据过期的时间。
过期字典的键指向 Redis 数据库中的某个 key(键),过期字典的值(long类型)是 key 所指向的数据库键的过期时间。
在 redisDb 结构中,数据结构如下:
1 | typedef struct redisDb { |
Redis过期删除策略?
Redis的过期删除策略为 : 【惰性删除 + 定期删除】
惰性删除:
只会在取出 key 的时候才对数据进行过期检查。
优点对 CPU 最友好,缺点是可能会造成太多过期 key 没有被删除。
定期删除:
每隔一段时间抽取一批 key 执行删除过期 key 操作。并且,Redis 底层会通过限制删除操作执行的时长和频率来减少删除操作对 CPU 时间的影响。
优点是相比惰性删除,对内存更友好。缺点是难以确定删除操作执行的时长和频率(太频繁对CPU不好,太稀疏又对内存效果不好)。
默认定期时间为10s,可在
redis.conf.hz
中进行配置。默认抽查数量为20。
注意:还有一种删除策略是
定时删除
。指在设置 key 的过期时间时,同时创建一个定时事件,当时间到达时,由事件处理器自动执行 key 的删除操作。这样对内存消耗太大,redis没有采用。
内存淘汰机制
如果只使用过期删除策略,仅仅通过给 key 设置过期时间还是有问题的。因为还是可能存在定期删除和惰性删除漏掉了很多过期 key 的情况。这样就导致大量过期 key 堆积在内存里,然后就 Out of memory 了。所以当 Redis 的运行内存已经超过 Redis 设置的最大内存之后,则会使用内存淘汰策略删除符合条件的 key,以此来保障 Redis 高效的运行。
Redis内存淘汰策略
Redis 提供 8 种数据淘汰策略,volatile开头的都是在过期数据中(server.db[i].expires
)中淘汰,allkeys开头的都是在所有数据(server.db[i].dict
)中淘汰。
- volatile-random:随机选择数据淘汰。
- volatile-ttl:优先淘汰更早过期的键值。
- volatile-lru(least recently used):挑选最久没使用的数据淘汰。
- volatile-lfu(least frequently used):最不经常使用的数据淘汰。(默认策略)
- allkeys-random:从数据集中任意选择数据淘汰。
- allkeys-lru(least recently used):挑选最久没使用的数据淘汰。
- allkeys-lfu(least frequently used):最不经常使用的数据淘汰。
- no-eviction:(不进行淘汰)禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。
查看淘汰策略:config get maxmemory-policy
,修改淘汰策略 : config set maxmemory-policy <策略>
或 在配置文件中设置maxmemory-policy <策略>