Redis
用作缓存时,通常很容易在添加新数据的同时移除旧数据。 此行为在开发者社区中是众所周知的,因为它是
memcached system
的默认行为。
LRU(Least Recently Used,最近最少使用)
,将最近最少使用的数据删除掉。
从 Redis 4.0
开始引入了LFU(Least Frequntly Used,最不常用)
淘汰策略。
Redis maxmemory
用于将内存使用限制为某一固定量。该配置常在名为redis.conf
的文件中,或者在运行时(runtime
)使用CONFIG SET
命令进行配置。
例如,为了配置内存限制为100 MB,可以在 redis.conf
文件中使用以下设置。
maxmemory 100mb
将 maxmemory
设置为零则没有内存限制。 这是64位系统的默认行为,而32位系统使用3GB的隐式内存限制。
当达到限定的内存量时,可以选择不同的策略。 只有当 Redis
执行的命令要使用更多的内存,Redis
才会返回error,或者Redis
删除一些旧数据,以便在每次添加新数据时返回到指定的限制。
在配置文件里使用 maxmemory-policy
命令可以指定以下淘汰策略:
noeviction
:在达到内存限制并且client
尝试执行可能导致使用更多内存的命令时返回错误。
allkeys-lru
:尝试先删除LRU
的key。
volatile-lru
:尝试先删除LRU
的key,要求删除的这个key必须已经过期。
allkeys-random
:随机删除key。
volatile-random
:随机删除key,要求删除的这个key必须已经过期。
volatile-ttl
:删除已经过期的key,尝试先删除较短生存时间(TTL
)的key。
如果执行这些策略时,发现没有与条件相匹配的key,则volatile-lru
,volatile-random
和volatile-ttl
策略的行为类似于noeviction
。
选择正确的淘汰策略很重要,具体取决于应用程序的访问方式,也可以在应用程序运行时在运行时重新配置该策略,为了方便调整设置,可以使用Redis
的INFO
命令来监控缓存未命中和命中的数量。
一般而言,根据经验:
allkeys-lru
策略。如果你希望request
呈指数分布,也就是说,你希望对于某些元素的访问比其他元素多得多。allkeys-random
。如果你希望对所有的key进行行周期性第连续访问,或者当你期望分布是统一的(所有元素以相同的概率被访问)。volatile-ttl
。如果你希望能够在创建缓存对象时通过使用不同的TTL
值向Redis
表明哪些key是最佳过期候选者。当你要使用单个Redis
实例进行缓存并拥有一些持久化的key时,volatile-lru
和volatile-random
策略相当有用。 但是,最好运行两个Redis
实例来解决此问题。
值得注意的是
,为一个key设置过期时间要耗费内存,因此像allkeys-lru
这样的策略能提高内存效率,因为不需要为那个在内存压力下需要被删除的key设置过期时间。
理解淘汰策略的工作工程时很关键的。
client
运行新命令,从而添加更多数据。Redis
会检查内存使用情况,如果大于maxmemory
限制,则会根据策略删除key。所以内存使用量会一直在maxmemory
上下徘徊,如果某个命令要求添加一个很大的数据很可能造成redis
使用的内存明显超过了maxmemory
限制。
redis
的LRU
没有严格的实现LRU
,这意味着redis
不是淘汰最佳(最久没访问)的数据。。Redis
对LRU
算法进行近似处理,方法是对少量key进行采样,然后从采样的key中删除掉访问时间最早的key。
3.0以后redis
会使用备选池做淘汰,提升了性能,准确性更高,更接近LRU
算法(代码里提升性能很明显,准确率更高这点看不出来,可能官方做统计得出的结论)。可以设置样本大小调整算法的准确率。
maxmemory-samples 5
Redis
之所以不使用真正的LRU
实现,是因为它占用更多内存(要遍历排序,会慢很多)。
从4.0开始redis
引入了一个新的淘汰模型LFU(Least Frequently Used)
。一些情况下这个模型在命中率上更会准确。LFU
会统计数据的使用率,使用率低的会被淘汰,使用率高的留下。LRU会保留最近访问了但是平常访问率很低的数据,风险就是淘汰了一个平常访问率高但是最近没访问的数据。
LFU
不会存在这样的问题,所以LFU
更适用于各种不同的访问模型。LFU
策略配置如下:
volatile-lfu
:在设置了过期时间的数据里使用近似LFU淘汰算法。allkeys-lfu
:在所有的数据上使用LFU淘汰算法。LFU
和LRU
类似也是一种概率计算,LFU
使用一个叫morris counter
的概率统计方法,一个数据只使用几个比特。和一个叫过期时间(decay period
)的数结合使用。统计值(counter
)随着时间减小。LFU
也是使用采样的方式淘汰数据。LFU
有更多的调整选项,4.0默认的配置
这些是经过测试比较好用的,用户也可以自己设置。配置命令如下:
lfu-log-factor 10
lfu-decay-time 1
一个比较特殊的用法是衰败期设置成0,每次统计都会衰败,这是个比较少用的方法。指数因子用来指定多大的访问量会是统计值变为最大,统计值范围0-255。指数因子越大需要越多的访问量使统计值变为最大,指数因子越小访问量低的时候分辨率越高。
+--------+------------+------------+------------+------------+------------+
| factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits |
+--------+------------+------------+------------+------------+------------+
| 0 | 104 | 255 | 255 | 255 | 255 |
+--------+------------+------------+------------+------------+------------+
| 1 | 18 | 49 | 255 | 255 | 255 |
+--------+------------+------------+------------+------------+------------+
| 10 | 10 | 18 | 142 | 255 | 255 |
+--------+------------+------------+------------+------------+------------+
| 100 | 8 | 11 | 49 | 143 | 255 |
+--------+------------+------------+------------+------------+------------+
Redis 官方文档 Using Redis as an LRU cache
LRU缓存机制
用redis当作LRU缓存