Redis 内存管理

480 阅读4分钟

设置数据的过期时间

Redis 是内存型数据库,内存空间有限,需要合理的安排管理内存空间,因此在写入数据时,需要考虑该数据是否需要永久存储,如果不需要永久性存储,最好设置过期时间以节省内存!

Redis 中可以通过 expire命令来指定 key 的过期时间,这里需要着重说明一下 hash 这个类型

image.png

redis 中常说的数据类型指的都是 value 的数据类型,比如 hash,指的是 value 是一个hash表hash 这种类型会有两种 key,一种就是 redis 这种 key-value 数据库中的主 key,另一种就是 key-valuevaluehash key

注意,Redis 中所有数据类型的过期时间都是作用在 key-value 中的主 key 上的。

也就是说 hash 类型没有办法过期其中的某一条数据,list、set、zset 也同理

设置过期数据的清理策略

过期数据的清理策略通常有以下三种:

  • 定时过期:每个设置过期时间的 key 都需要创建一个定时器,到过期时间就会立即清除

    • 优点 : 数据过期及时,对内存很友好 缺点 : 每个设置过期时间的 key 都需要创建一个定时器,会占用大量的 CPU 资源去处理过期的数据,从而影响缓存的响应时间和吞吐量
  • 惰性过期:只有访问一个 key 时,才会判断该 key 是否已过期,过期则清除

    • 优点 : 该策略可以最大化地节省CPU资源
    • 缺点 : 对内存非常不友好,可能出现大量的过期 key 没有再次被访问,从而 不会被清除,占用大量内存空间。
  • 定期过期:每隔一段时间,扫描 expires 字典中的部分 key,并清除其中已过期的 key

    • 该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

expires 字典存储的是所有过期 key 对应的指针和对应的过期时间。expires 是 hash 结构,其中 hash key 保存的是设置了过期时间的 key, 在键空间中对应的指针。 hash value 保存的是该过期 key 的过期时间,值为毫秒精度的UNIX时间戳

键空间保存的是该 Redis 集群中的所有 key

Redis 中使用定期过期作为基本策略,保证清理大部分过期数据的同时,也不会占用过多 cpu 资源,再辅以惰性过期解决小部分过期数据没有被定期过期覆盖的问题。

设置数据淘汰策略

合理设置了数据的过期时间,也合理设置了过期数据的清理策略就可以高枕无忧了吗,有时候可能业务量突然增大,Redis 很多数据还没有到过期时间,内存就快消耗光了,这个时候我们必须做出抉择清理一些还没过期的数据甚至是一些永久性的数据

Redis 提供了两大类共 6 种淘汰策略

  • 从全局的键空间选择性淘汰

    • noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
    • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key
    • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
  • 从设置过期时间的键空间选择性淘汰

    • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key
    • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
    • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,优先移除即将过期的 key

其中 volatile-lruvolatile-ttlallkeys-lru 三种策略最为常用