配置文件
redis 的配置文件为 redis.conf
,当 redis 占用的内存达到配置的最大内存时,再使用 redis 增加新的值时会触发淘汰机制将占用的内存释放出来,以创建新的键值。
redis 允许占用的最大内存,约在 567 行:
1 | # maxmemory <bytes> |
找到 maxmemory
去掉前面的 #
井号, 将 <bytes>
(单位:字节) 改为需要设置的最大内存值,一般而言,建议设置为服务器总内存的 50%~75%(需根据服务器情况确定),如果服务器其他进程占用较多内存的话,可以减少这个值。
当 redis 内存占用达到设置的最大值,触发的淘汰策略,约在 598 行:
1 | # maxmemory-policy noeviction |
去掉前面的 #
井号,后面即为淘汰的策略,淘汰策略有许多种,下面进行介绍。不过在此之前,我们可以理解一下 redis 如何淘汰掉键值。
我们通过给一个键值设置过期时间,来让它“自动过期”,但实际上,即使到了过期时间,这个键其实并没有立即被删除,而是当下次取这个键值的时候进行判断,如果这个键设置了过期时间,同时已经过了过期时间再进行删除,这是一种惰性的删除策略。
此外,除了这种被动删除的策略之外还有主动删除策略,例如定期扫描过期的键值,扫描也不可能将全部的键都扫秒一遍,而是通过某种随机算法获取某些键,判断键是否过期再决定是否删除。
为什么键设定了过期时间不能在到期后立即删除呢?因为从技术的角度上来考虑这是一件十分困难的事,如果要追踪一个键值的过期时间,可能需要启动一个进程来追踪并且在过期时“杀掉”这个键,这样使用 redis 的优势就全部没有了,反而要消耗更多的系统资源。
redis 过期的键太多而没有删除,会造成内存资源的浪费,反之,如果过于频繁的去检查过期的键,希望在第一时间释放出内存资源,频繁的检查也是十分耗费资源的事,因此两者之间必须存在一个平衡,这就需要依靠 redis 的淘汰策略。
内存淘汰机制
redis 有如下淘汰策略:
noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用吧
allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)
allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key,这个一般没人用吧
volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key(这个一般不太合适)
volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key
volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除