Redis内存淘汰策略

Redis占用内存大小

1、通过配置文件配置
//redis.conf

maxmemory 100mb

2、在客户端动态修改

//设置Redis最大占用内存大小为100M127.0.0.1:6379> config set maxmemory 100mb//获取设置的Redis能使用的最大内存大小
127.0.0.1:6379> config get maxmemory

如果不设置最大内存大小或者设置最大内存大小为0,在64位操作系统下不限制内存大小,在32位操作系统下最多使用3GB内存

Redis的内存淘汰策略

如果可以内存用完了,那继续往Redis里添加数据不就没内存可用了吗?Redis使用几种内存淘汰策略来处理这种情况:

  • noeviction(默认策略):对于写请求不在提供服务,直接返回错误(DEL请求和部分特殊请求除外)
  • allkeys-lru:从所有可以中使用LRU算法进行淘汰
  • vllatile-lru:从设置了过期时间的key中使用LRU算法进行淘汰
  • allkeys-random:从所有可以中随机淘汰数据
  • volatile-random:从设置了过期时间的key中随机淘汰
  • volatile-ttl:在设置了过期时间的key中,根据key的过期时间进行淘汰,越早过期越早淘汰

当使用volatile-lru、volatile-random、volatile-ttl这三种策略时,如果没有key可以被淘汰,则和noeviction一样返回错误

LRU(Least Recently Used),即最近最少使用,是一种缓存置换算法。在使用内存作为缓存的时候,缓存的大小一般是固定的。当缓存被占满,这个时候继续往缓存里面添加数据,就需要淘汰一部分老的数据,释放内存空间用来存储新的数据。这个时候就可以使用LRU算法了。其核心思想是:如果一个数据在最近一段时间没有被用到,那么将来被使用到的可能性也很小,所以就可以被淘汰掉。

获取及设置内存淘汰策略

获取当前内存淘汰策略:

127.0.0.1:6379> config get maxmemory-policy

通过配置文件设置淘汰策略(修改redis.conf文件):

maxmemory-policy allkeys-lru

通过命令修改淘汰策略:

127.0.0.1:6379> config set maxmemory-policy allkeys-lru

LRU在Redis中的实现

近似LRU算法
Redis使用的是近似LRU算法,它跟常规的LRU算法还不太一样。近似LRU算法通过随机采样法淘汰数据,每次随机出5(默认)个key,从里面淘汰掉最近最少使用的key。

可以通过maxmemory-samples参数修改采样数量:例:maxmemory-samples 10 maxmenory-samples配置的越大,淘汰的结果越接近于严格的LRU算法

Redis为了实现近似LRU算法,给每个key增加了一个额外增加了一个24bit的字段,用来存储该key最后一次被访问的时间。
Redis3.0对近似LRU的优化
Redis3.0对近似LRU算法进行了一些优化。新算法会维护一个候选池(大小为16),池中的数据根据访问时间进行排序,第一次随机选取的key都会放入池中,随后每次随机选取的key只有在访问时间小于池中最小的时间才会放入池中,直到候选池被放满。当放满后,如果有新的key需要放入,则将池中最后访问时间最大(最近被访问)的移除。
当需要淘汰的时候,则直接从池中选取最近访问时间最小(最久没被访问)的key淘汰掉就行。

LFU算法

LFU算法是Redis4.0里面新加的一种淘汰策略。它的全称是Least Frequently Used,它的核心思想是根据key的最近被访问的频率进行淘汰,很少被访问的优先被淘汰,被访问的多的则被留下来。
LFU算法能更好的表示一个key被访问的热度。假如你使用的是LRU算法,一个key很久没有被访问到,只刚刚是偶尔被访问了一次,那么它就被认为是热点数据,不会被淘汰,而有些key将来是很有可能被访问到的则被淘汰了。如果使用LFU算法则不会出现这种情况,因为使用一次并不会使一个key成为热点数据。

LFU一共有两种策略:

  • volatile-lfu:在设置了过期时间的key中使用LFU算法淘汰key
  • allkeys-lfu:在所有的key中使用LFU算法淘汰数据

为什么是近似LRU算法

答案仅供参考
如果使用LRU,则需要维护一个链表,按照时间排序,当一个key被访问到时,则该数据要移动到链表头部,维护这样的链表以及节点的移动很耗费时间和空间;还有一种可能是如果当前链表前面一部分是热点数据,而程序访问了一批很少被访问到的数据,那这批数据会放入链表前面,淘汰的时候,热点数据就会被优先淘汰。

### Redis 内存淘汰策略机制及实现 Redis内存管理机制是其性能优化的核心之一,当 Redis内存使用量达到配置的限制时(由 `maxmemory` 参数控制),Redis 会根据指定的内存淘汰策略来释放空间,以保证服务的可用性[^1]。以下是 Redis 内存淘汰策略的工作原理和实现细节。 #### 一、内存淘汰策略概述 Redis 提供了多种内存淘汰策略,这些策略通过 `maxmemory-policy` 配置项进行设置。根据键的范围和淘汰算法的不同,可以将这些策略分为三类[^5]: - **noeviction**:不淘汰任何键,当内存不足时直接返回错误。 - **allkeys**:在所有键中选择淘汰目标。 - **volatile**:仅在设置了过期时间的键中选择淘汰目标。 具体淘汰算法包括以下四种: 1. **随机淘汰(Random)**:随机选择键进行淘汰。 2. **最少使用(LRU, Least Recently Used)**:淘汰最久未使用的键。 3. **最少访问频率(LFU, Least Frequently Used)**:淘汰访问频率最低的键。 4. **基于大小(TTL, Time To Live)**:优先淘汰剩余存活时间较短的键。 #### 二、内存淘汰策略的实现细节 1. **随机淘汰** - 在 `allkeys-random` 和 `volatile-random` 策略中,Redis 使用伪随机数生成器从候选键集合中随机选择键进行淘汰[^5]。 - 这种方法简单高效,但可能会导致重要数据被意外删除。 2. **LRU 淘汰** - LRU 淘汰策略(如 `allkeys-lru` 和 `volatile-lru`)依赖于 Redis 的内部 LRU 数据结构,该结构记录每个键的最后访问时间[^1]。 - 当需要淘汰键时,Redis 会扫描一定数量的候选键,并选择最后访问时间最早的键进行淘汰。 - Redis 并不维护一个完整的全局 LRU 列表,而是通过采样技术(例如每轮检查 5 个随机键)来近似实现 LRU 淘汰[^2]。 3. **LFU 淘汰** - LFU 淘汰策略(如 `allkeys-lfu` 和 `volatile-lfu`)基于键的访问频率进行淘汰[^3]。 - Redis 使用一个计数器记录每个键的访问频率,淘汰时选择访问频率最低的键。 - 访问频率的计算结合了时间衰减因子,确保长期未访问的键也能被淘汰。 4. **TTL 淘汰** - TTL 淘汰策略(如 `volatile-ttl`)优先淘汰剩余存活时间较短的键[^4]。 - 这种策略特别适用于缓存场景,能够有效减少内存占用。 #### 三、内存淘汰策略的监控与优化 为了确保内存淘汰策略的有效性,建议通过监控工具(如 RedisInsight 或 Prometheus)实时跟踪内存使用情况和淘汰指标[^2]。常见的优化实践包括: - 根据业务需求选择合适的淘汰策略。 - 定期分析淘汰日志,识别高频淘汰的键并优化存储逻辑。 - 调整 `maxmemory` 配置以平衡内存使用和性能需求。 ```python # 示例:设置 maxmemory 和淘汰策略 redis-cli config set maxmemory 1gb redis-cli config set maxmemory-policy allkeys-lru ``` #### 四、内存回收机制 除了内存淘汰策略外,Redis 还通过定期删除和惰性删除两种方式来清除过期的键[^3]: - **惰性删除**:仅在访问某个键时检查其是否已过期,若已过期则立即删除。 - **定期删除**:后台线程定期扫描一定比例的过期键并删除。 这两种机制共同作用,确保过期键不会长时间占用内存。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值