何时触发淘汰策略
- 客户端执行新命令导致更多的数据被添加到内存
- redis检查内存使用量,如果超过了
maxmemory则根据策略淘汰key - 下一条命令 以此类推
不断的超过内存限制maxmemory,不断的淘汰key保持在内存限制边界以下
如果一个命令使用了大量的内存,将会大幅超过限制内存maxmemory
maxmemory可以在配置文件中配置也可以通过运行时的命令设置,64位redis默认无限制,32位默认为3GB
淘汰策略
noeviction: 不淘汰直接返回errorallkeys-lru: 在所有key中选择最近最少使用的key淘汰volatile-lru: 在带过期时间的key中选择最近最少使用的key淘汰allkeys-random: 在所有key中随机选择key淘汰volatile-random: 在带过期时间的key中随机选择key淘汰volatile-ttl: 淘汰带过期时间的key,且TTL最短的key优先被淘汰
带volatile的淘汰策略都是从带过期时间的key中淘汰key,如果没有符合条件的key(所有key都没有设置过期时间)此时volatile-*的行为和noeviction一样
如何选择策略
淘汰策略可以在Redis运行时重新配置,使用 Redis INFO命令监控缓存命中和未命中次数以便调整策略
allkeys-lru适用于二八原则的场景,即类似于20%的key有80%的概率被访问,80%的key有20%的概率被访问到。官方叫法:Power-law Distributions(幂律分布)allkeys-random适用于每个key访问概率差不多时的场景如果想通过设置不同的TTL来引导Redis淘汰key可以使用
volatile-ttl
The volatile-lru and volatile-random policies are mainly useful when you want to use a single instance for both caching and to have a set of persistent keys. However it is usually a better idea to run two Redis instances to solve such a problem
设置过期时间也消耗内存,因此不设置过期时间使用allkeys-lru策略通常是最高效的
LRU的近似算法
Redis通过少量key的采样实现LRU的近似算法,maxmemory-samples n可以调整近似算法的精度:n越大,样本越多,LRU越精准,算法性能越低,选择淘汰的目标key越是最佳
Redis之所以不使用真正的LRU实现,是因为它会占用更多内存,实际上在符合幂律分布的场景中Redis的近似算法和真正LRU实现是几乎等效的
LRU与近似LRU对比测试
以一定量的数据填充到redis中,然后从第一个到最后一个依次访问,因此第一个key是LRU淘汰的最佳选择,之后再添加50%的数据用来强制淘汰一半数据
左上:理论上的淘汰结果 右上:Redis3.0 近似LRU 10样本的结果 非常接近理论值 左下:Redis2.8 近似LRU 5样本 的结果 右下:Redis3.0 近似LRU 5样本 的结果
- 浅灰色是被淘汰的对象
- 灰色是未淘汰的对象
- 绿色是新添加的对象
Redis的LRU只会以概率的方式让老数据过期
如果你的数据访问模式与幂律极为相似,LRU近似算法几乎等效理论LRU
通常可以把样本调整到10用来检测对缓存命中率是否有影响,但会增加额外的硬件资源消耗(cpu内存)
LFU
Redis4.0及之后,Least Frequently Used 最少使用,通过访问频率来淘汰
volatile-lfuallkeys-lfu
LFU近似于LRU,每个object中用几个bit来表示访问频率:counter(范围:0-255),counter也会随时间而慢慢变小
lfu-decay-time 1
lfu-log-factor 10
lfu-decay-time 1表示每1分钟衰减一次counter,为0时表示每次被扫描都衰减(不常用)
lfu-log-factor因子决定了counter随访问次数增大的速度,见下表
+--------+------------+------------+------------+------------+------------+
| 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 |
+--------+------------+------------+------------+------------+------------+