跳至主要內容

Redis进阶-内存淘汰机制

Zenghr大约 4 分钟

Redis 内存淘汰机制

Redis的用途非常广泛。作为一个高性能的内存数据库,它经常被用于缓存的业务场景。

所谓缓存,即在第一次获取到数据的时候,把它暂存在内存中。这样下次需要这个数据的时候,就直接从内存中取,不用再去查询数据库或调用远程接口,这样可以极大地提高应用程序的性能。

如果缓存中的数据永久存在,那占用的内存就会变得越来越大。而内存是有限的,所以缓存系统需要在需要的时候删除一些不必要的缓存数据以节约内存空间。

Redis提供了两种机制配合来达到上述目的:过期策略内存淘汰机制

Key 过期策略

Redis中大家会对存入的数据设置过期时间,那么这些数据如果过期了,Redis 是怎么样把他们消灭掉的呢?我们一起来探讨一下。下面介绍三种清除策略:

惰性删除

当访问Key时,才去判断它是否过期,如果过期,直接干掉。这种方式对CPU很友好,但是一个key如果长期不用,一直存在内存里,会造成内存浪费

定时删除

设置键的过期时间的同时,创建一个定时器,当到达过期时间点,立即执行对Key的删除操作,这种方式最不友好

定期删除

隔一段时间,对数据进行一次检查,删除里面的过期Key,至于要删除多少过期Key,检查多少数据,则由算法决定。

举个例子方便大家理解:Redis每秒随机取100个数据进行过期检查,删除检查数据中所有已经过期的Key,如果过期的Key占比大于总数的25%,也就是超过25个,再重复上述检查操作

Redis服务器实际使用的是 定期删除+惰性删除 两种策略:通过配合使用这两种删除策略,可以很好地在合理使用CPU和避免浪费内存之间取得平衡

Redis 内存淘汰机制

Redis内存淘汰机制是指当内存使用达到上限(可通过maxmemory配置,0为不限制,即服务器内存上限),根据一定的算法来决定淘汰掉哪些数据,以保证新数据的存入

# maxmemory <bytes> 配置内存阈值
# maxmemory-policy noeviction

常见的内存淘汰机制分为四大类:

  • LRU: LRU是Least recently used,最近最少使用的意思,简单的理解就是从数据库中删除最近最少访问的数据,该算法认为,你长期不用的数据,那么被再次访问的概率也就很小了,淘汰的数据为最长时间没有被使用,仅与时间相关
  • LFU: LFU是Least Frequently Used,最不经常使用的意思,简单的理解就是淘汰一段时间内,使用次数最少的数据,这个与频次和时间相关
  • TTL: Redis中,有的数据是设置了过期时间的,而设置了过期时间的这部分数据,就是该算法要解决的对象。如果你快过期了,不好意思,我内存现在不够了,反正你也要退休了,提前送你一程,把你干掉吧
  • 随机淘汰: 随机移除某个key

maxmemory-policy 配置选项

  • volatile-lru: 找出已经设置过期时间的数据集,将最近最少使用(被访问到)的数据干掉

  • volatile-ttl: 找出已经设置过期时间的数据集,将即将过期的数据干掉

  • volatile-random: 找出已经设置过期时间的数据集,进行无差别攻击,随机干掉数据

  • volatile-lfu: 找出已经设置过期时间的数据集,将一段时间内,使用次数最少的数据干掉

  • allkeys-lru: 与第1个差不多,数据集从设置过期时间数据变为全体数据

  • allkeys-lfu: 与第4个差不多,数据集从设置过期时间数据变为全体数据

  • allkeys-random: 与第3个差不多,数据集从设置过期时间数据变为全体数据

  • no-enviction: 什么都不干,报错,告诉你内存不足,这样的好处是可以保证数据不丢失,这也是系统默认的淘汰策略

参考资料