Redis淘汰策略简介

Redis的淘汰策略发生在内存被写满的时候。内存是有限的,总有满的时候。所以Redis就为我们提供了多种不同的策略让我们来淘汰掉旧的数据。

Redis的内存大小限制和淘汰策略可以用如下配置进行:

maxmemory <bytes>
maxmemory-policy <policy>



eg.   maxmemory 300mb
      maxmemory-policy allkeys-lru

下面就来分别介绍这些策略。

noeviction

noeviction是这些策略里面最特殊的一个,它不淘汰旧数据,而是当内存满的时候,直接拒绝新数据的加入,返回错误。

volatile-random

在设置了过期时间的数据中,随机进行删除。

volatile-ttl

在设置了过期时间的数据中,根据过期时间的先后进行删除,越早过期的越先被删除。

volatile-lru

在设置了过期时间的数据中,使用LRU算法筛选出要删除的数据

volatile-lfu

在设置了过期时间的数据中,使用LFU算法筛选出要删除的数据

allkeys-random

在所有的数据中,随机进行删除

allkeys-lru

在所有的数据中,使用LRU算法筛选出要删除的数据

allkeys-lfu

在所有的数据中,使用LFU算法筛选出要删除的数据

LRU?LFU?

上面的这些其实都很好理解,区别无非是在设置了过期时间还是在全体数据中选择,以及选择时采用的算法不同而已。那么上面都提到了LRU算法和LFU算法,它们是什么意思,有什么区别呢?

LRU(Least Recently Used)就是最近最少使用淘汰算法。Redis在触发淘汰的时候,会优先淘汰最长时间没被使用的那个数据。这其实很合理,因为我们大部分时间使用Redis都是为了将热点数据缓存起来,然后加快访问速度。那么一个数据如果很长时间没有被访问,那它相对来说可能就“没有那么热点”。所以淘汰掉它是很合理的。

但是Redis里的数据太多了,如果把全部的数据都拿来分析,也是一个非常消耗性能的工作。Redis的实现方式是这样的:随机选取一些key,把最长时间没有使用的key移除。这个随机选取的数量可以在 maxmemory-samples这个配置中进行设置。但是这样还是有一些缺点,它在每次选择的时候,没有利用历史信息。每次都是随机移除,但其实在上一轮移除的时候,有几个key的信息我是已经知道了的,可以加以利用。

所以Redis又改进了策略,采用缓冲池。每一轮移除key的时候,如果它的最长未使用时间比池子里的还要大,就把它添加到缓冲池。这样,每次移除的key不仅是随机选择的数据中最长未使用时间最大的,还是包含了池子中的数据里最大的。而且缓冲池中的数据经过多轮筛选,本身概率就要比随机挑选的大,这样就利用好了每次随机选取的数据。

LFU(Least Frequently Used)就是最不经常使用淘汰算法。Redis中,LFU算法是在LRU算法上的进一步优化。在LRU中有这么一个问题,就是如果在取值的时候,一个不常被访问的数据,刚好被访问了,那么它就会被认为是一个热点数据,从而难以被淘汰。淘汰算法的本意是留下热点数据,这就造成了问题。LFU就解决了这个问题,它在LRU的基础上增加了访问次数的统计,当访问次数相同时,再用LRU进行处理。并且并不是每一次被访问,这个访问次数都会+1,而是有一个随机的过程,这使得计数器是非线性递增的。并且还有一个递减策略,防止某些数据短时间内大量访问,但是后面很长一段时间都不被访问,造成一种热点数据的假象。有递减策略,就可以减少这种假热点数据发生的机率。

以上就是Redis淘汰策略的介绍,可以看出,策略是不断发展的,更新的策略会在某种程度上解决旧策略的一些痛点,从而使被淘汰的数据更加合理。

### Redis 淘汰策略详解及最佳实践 Redis 提供了多种内存淘汰策略,这些策略主要分为两大类:**仅作用于设置了过期时间的键(volatile 策略)** 和 **作用于所有键(allkeys 策略)**。此外,还有一种特殊的情况,即当内存达到上限时,Redis 拒绝继续写入,而不是主动淘汰数据[^1]。 #### 一、Redis 内存淘汰策略分类 以下是 Redis 中常见的内存淘汰策略及其特点: 1. **noeviction** 当内存达到上限时,Redis 将拒绝所有写入操作,并返回错误。此策略适用于需要确保数据完整性的场景,例如持久化存储或不允许丢失任何数据的应用[^1]。 2. **allkeys-lru** 从所有键中选择最近最少使用的键进行淘汰。这种策略适合缓存场景,尤其是数据访问模式具有明显的冷热特性时[^4]。 3. **volatile-lru** 仅从设置了过期时间的键中选择最近最少使用的键进行淘汰。此策略适用于缓存层中某些数据有明确生命周期需求的场景[^1]。 4. **allkeys-random** 随机从所有键中选择一个进行淘汰。此策略适合对数据淘汰没有严格要求的场景,例如临时性存储[^4]。 5. **volatile-random** 仅从设置了过期时间的键中随机选择一个进行淘汰。此策略适用于需要快速释放内存但又不希望影响全局数据分布的场景。 6. **volatile-ttl** 从设置了过期时间的键中选择剩余生存时间最短的键进行淘汰。此策略适合那些希望优先清理即将过期的数据的场景[^4]。 7. **allkeys-lfu** 从所有键中选择访问频率最低的键进行淘汰。此策略适合数据访问频率差异较大的缓存场景[^4]。 8. **volatile-lfu** 仅从设置了过期时间的键中选择访问频率最低的键进行淘汰。此策略适合缓存中部分数据有明确生命周期且访问频率不同的场景。 #### 二、配置 Redis 淘汰策略 可以通过以下两种方式配置 Redis淘汰策略: 1. **配置文件设置** 在 Redis 配置文件中添加以下内容以限制最大内存并指定淘汰策略: ```bash maxmemory 2gb maxmemory-policy allkeys-lru ``` 2. **动态配置(Redis CLI)** 使用 Redis CLI 动态调整淘汰策略: ```bash 127.0.0.1:6379> CONFIG SET maxmemory 2147483648 127.0.0.1:6379> CONFIG SET maxmemory-policy volatile-ttl ``` #### 三、使用场景分析 - **缓存场景** 在典型的缓存场景中,推荐使用 `allkeys-lru` 或 `allkeys-lfu` 策略,因为它们能够智能地清理低频或长期未使用的数据,从而提高缓存命中率。 - **短期任务存储** 如果 Redis 被用作短期任务的存储(如会话管理),可以考虑使用 `volatile-lru` 或 `volatile-ttl` 策略,因为这些策略仅作用于设置了过期时间的键。 - **高可靠性场景** 对于需要保证数据完整性的场景(如持久化存储),建议使用 `noeviction` 策略,避免因内存不足而导致的数据丢失[^1]。 #### 四、最佳实践 1. 根据实际业务需求选择合适的淘汰策略,避免盲目使用默认值。 2. 定期监控 Redis 内存使用情况,及时调整 `maxmemory` 和淘汰策略。 3. 在高并发场景下,建议结合 Redis 集群和分片技术,分散单个实例的压力[^3]。 ```python # 示例代码:动态调整 Redis 淘汰策略 import redis r = redis.StrictRedis(host='localhost', port=6379, decode_responses=True) r.config_set('maxmemory', '2gb') r.config_set('maxmemory-policy', 'allkeys-lru') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值