Redis 内存淘汰机制

Redis内存淘汰指的是用户存储的一些键被能够被Redis主动地从实例中删除,从而产生读miss的状况,那么Redis为何要有这种功能?这就是咱们须要探究的设计初衷。Redis最多见的两种应用场景为缓存和持久存储,首先要明确的一个问题是内存淘汰策略更适合于那种场景?是持久存储仍是缓存?redis

内存的淘汰机制的初衷是为了更好地使用内存,用必定的缓存miss来换取内存的使用效率。缓存

 

做为Redis用户,我如何使用Redis提供的这个特性呢?看看下面配置dom

 

# maxmemory <bytes>设计

 

咱们能够经过配置redis.conf中的maxmemory这个值来开启内存淘汰功能,至于这个值有什么意义,咱们能够经过了解内存淘汰的过程来理解它的意义:内存

 

1.      客户端发起了须要申请更多内存的命令(如set)。io

 

2.      Redis检查内存使用状况,若是已使用的内存大于maxmemory则开始根据用户配置的不一样淘汰策略来淘汰内存(key),从而换取必定的内存。效率

 

3.      若是上面都没问题,则这个命令执行成功。配置

 

maxmemory为0的时候表示咱们对Redis的内存使用没有限制。请求

 

Redis提供了下面几种淘汰策略供用户选择,其中默认的策略为noeviction策略:im

 

·         noeviction:当内存使用达到阈值的时候,全部引发申请内存的命令会报错。

 

·         allkeys-lru:在主键空间中,优先移除最近未使用的key。

 

·         volatile-lru:在设置了过时时间的键空间中,优先移除最近未使用的key。

 

·         allkeys-random:在主键空间中,随机移除某个key。

 

·         volatile-random:在设置了过时时间的键空间中,随机移除某个key。

 

·         volatile-ttl:在设置了过时时间的键空间中,具备更早过时时间的key优先移除。

 

这里补充一下主键空间和设置了过时时间的键空间,举个例子,假设咱们有一批键存储在Redis中,则有那么一个哈希表用于存储这批键及其值,若是这批键中有一部分设置了过时时间,那么这批键还会被存储到另一个哈希表中,这个哈希表中的值对应的是键被设置的过时时间。设置了过时时间的键空间为主键空间的子集。

 

咱们了解了Redis大概提供了这么几种淘汰策略,那么如何选择呢?淘汰策略的选择能够经过下面的配置指定:

 

# maxmemory-policy noeviction

 

可是这个值填什么呢?为解决这个问题,咱们须要了解咱们的应用请求对于Redis中存储的数据集的访问方式以及咱们的诉求是什么。同时Redis也支持Runtime修改淘汰策略,这使得咱们不须要重启Redis实例而实时的调整内存淘汰策略。

 

下面看看几种策略的适用场景:

 

·         allkeys-lru:若是咱们的应用对缓存的访问符合幂律分布(也就是存在相对热点数据),或者咱们不太清楚咱们应用的缓存访问分布情况,咱们能够选择allkeys-lru策略。

 

·         allkeys-random:若是咱们的应用对于缓存key的访问几率相等,则可使用这个策略。

 

·         volatile-ttl:这种策略使得咱们能够向Redis提示哪些key更适合被eviction。

 

另外,volatile-lru策略和volatile-random策略适合咱们将一个Redis实例既应用于缓存和又应用于持久化存储的时候,然而咱们也能够经过使用两个Redis实例来达到相同的效果,值得一提的是将key设置过时时间实际上会消耗更多的内存,所以咱们建议使用allkeys-lru策略从而更有效率的使用内存。