文章首发于公众号 “蘑菇睡不着”
《源码级别了解Redis持久化》
《聊聊Redis过时键删除策略》
《Redis数据结构详解》
《超详细Redis五种数据结构底层实现》 redis
这一期我们一块儿来看看 Redis 的内存淘汰策略~算法
你们都知道 Redis 中的键会设置过时时间,当到达过时时间时会经过必定策略清除对应 key,可是 redis 内存是由上限的,当达到内存上限时,就要经过必定策略淘汰掉相应 kv 键值对。segmentfault
maxmemory 配置选项使用来配置 Redis 的存储数据所能使用的最大内存限制。能够经过在内置文件redis.conf中配置,也可在Redis运行时经过命令CONFIG SET来配置。例如,咱们要配置内存上限是100M的Redis缓存,那么咱们能够在 redis.conf 配置以下:缓存
maxmemory 100mb
设置 maxmemory 为 0 表示没有内存限制。在 64-bit 系统中,默认是 0 无限制,可是在 32-bit 系统中默认是 3GB。微信
当存储数据达到限制时,Redis 会根据情形选择不一样策略,或者返回errors(这样会致使浪费更多的内存),或者清除一些旧数据回收内存来添加新数据。数据结构
理解回收过程是运做流程很是的重要,回收过程以下:dom
咱们添加数据时经过检查,而后回收键以返回到限制如下,来接二连三的穿越内存限制的边界。性能
若是一个命令致使大量的内存被占用(好比一个很大的集合保存到一个新的键),那么内存限制很快就会被这个明显的内存量所超越。code
Redis的LRU算法不是一个严格的LRU实现。这意味着Redis不能选择最佳候选键来回收,也就是最久未被访问的那些键。相反,Redis 会尝试执行一个近似的LRU算法,经过采样一小部分键,而后在采样键中回收最适合(拥有最久访问时间)的那个。对象
然而,从Redis3.0开始,算法被改进为维护一个回收候选键池。这改善了算法的性能,使得更接近于真实的LRU算法的行为。Redis的LRU算法有一点很重要,你能够调整算法的精度,经过改变每次回收时检查的采样数量。
这个参数能够经过以下配置指令:
maxmemory-samples 5
Redis没有使用真实的LRU实现的缘由,是由于这会消耗更多的内存。然而,近似值对使用Redis的应用来讲基本上也是等价的。
LFU (Least frequently used) 最不常用算法。而 LRU 是最近最少使用算法。
从 Redis 4.0 开始,可使用 LFU 过时策略。这种模式在某些状况下可能会更好(提供更好的命中率/未命中率),由于使用 LFU Redis 会尝试跟踪项目的访问频率,所以不多使用的项目会被淘汰,而常用的项目有更高的机会留在内存中。
那为何会出现 LFU 算法那?你们请看下面的场景:
A - A - A - - - A - A -A - - - B - - - - B - - B - - - - - - B
若是是 LRU 算法 那么会淘汰 A,由于 B 是最近使用的,可是很明显 A 的使用频率是最高的,理应留下 A,因此 LFU 算法应运而生。(淘汰最少使用的 key)
LFU 把原来的 key 对象的内部时钟的24位分红两部分,前16位还表明时钟,后8位表明一个计数器, 称为Morris 计数器。后8位表示当前key对象的访问频率,8位只能表明255,可是 redis 并无采用线性上升的方式,而是经过一个复杂的公式,经过配置两个参数来调整数据的递增速度。
下图从左到右表示key的命中次数,从上到下表示影响因子,在影响因子为100的条件下,通过10M次命中才能把后8位值加满到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 |
这个参数是可配置的的,经过这个:
lfu-log-factor 10
上说的是计数器的增加,那么什么状况削减那?
默认是 若是一个 key 每一分钟没使用,Morris 计数器 就削减 1. 这个也能够经过下面进行配置:
lfu-decay-time 1
有个问题就是,新的 key 怎么办,岂不是上来就被淘汰?
为了不这种问题 Redis 默认状况下新分配的key的后8位计数器的值为5,防止由于访问频率太低而直接被删除。
Redis 为了不内存超出容量,使用特定的内存淘汰策略来释放内存,主要思想是 LRU 和 Redis 4.0 推出的 LFU 算法。LRU 是最近最少使用算法,LFU 是最少使用算法。
更多精彩内容,微信搜索 “蘑菇睡不着”
若是以为对您有帮助,麻烦帮忙点个赞,你的支持是我创做最大的动力
你越主动就越主动,咱们下期见~