db-tutorial/docs/nosql/redis/Redis缓存淘汰策略.md

3.5 KiB
Raw Blame History

Redis 缓存淘汰策略

概述

  • 最大缓存

Redis 允许通过 maxmemory 参数来设置内存最大值。

  • 主键失效

作为一种定期清理无效数据的重要机制,在 Redis 提供的诸多命令中EXPIRE、EXPIREAT、PEXPIRE、PEXPIREAT 以及 SETEX 和 PSETEX 均可以用来设置一条 Key-Value 对的失效时间,而一条 Key-Value 对一旦被关联了失效时间就会在到期后自动删除(或者说变得无法访问更为准确)。

  • 淘汰机制

随着不断的向 redis 中保存数据当内存剩余空间无法满足添加的数据时redis 内就会施行数据淘汰策略,清除一部分内容然后保证新的数据可以保存到内存中。

内存淘汰机制是为了更好的使用内存,用一定得 miss 来换取内存的利用率,保证 redis 缓存中保存的都是热点数据。

  • 非精准的 LRU

实际上 Redis 实现的 LRU 并不是可靠的 LRU也就是名义上我们使用 LRU 算法淘汰键,但是实际上被淘汰的键并不一定是真正的最久没用的。

淘汰策略

内存淘汰只是 Redis 提供的一个功能,为了更好地实现这个功能,必须为不同的应用场景提供不同的策略,内存淘汰策略讲的是为实现内存淘汰我们具体怎么做,要解决的问题包括淘汰键空间如何选择?在键空间中淘汰键如何选择?

Redis 提供了下面几种淘汰策略供用户选择,其中默认的策略为 noeviction 策略:

  • noeviction - 当内存使用达到阈值的时候,所有引起申请内存的命令会报错。
  • allkeys-lru - 在主键空间中,优先移除最近未使用的 key。
  • allkeys-random - 在主键空间中,随机移除某个 key。
  • volatile-lru - 在设置了过期时间的键空间中,优先移除最近未使用的 key。
  • volatile-random - 在设置了过期时间的键空间中,随机移除某个 key。
  • volatile-ttl - 在设置了过期时间的键空间中,具有更早过期时间的 key 优先移除。

这里补充一下主键空间和设置了过期时间的键空间,举个例子,假设我们有一批键存储在 Redis 中,则有那么一个哈希表用于存储这批键及其值,如果这批键中有一部分设置了过期时间,那么这批键还会被存储到另外一个哈希表中,这个哈希表中的值对应的是键被设置的过期时间。设置了过期时间的键空间为主键空间的子集。

如何选择淘汰策略

  • 如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用 allkeys-lru。
  • 如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用 allkeys-random。
  • volatile-lru 策略和 volatile-random 策略适合我们将一个 Redis 实例既应用于缓存和又应用于持久化存储的时候,然而我们也可以通过使用两个 Redis 实例来达到相同的效果。
  • 将 key 设置过期时间实际上会消耗更多的内存,因此我们建议使用 allkeys-lru 策略从而更有效率的使用内存。

内部实现

Redis 删除失效主键的方法主要有两种:

  • 消极方法passive way在主键被访问时如果发现它已经失效那么就删除它。
  • 主动方法active way周期性地从设置了失效时间的主键中选择一部分失效的主键删除。
  • 主动删除:当前已用内存超过 maxmemory 限定时,触发主动清理策略,该策略由启动参数的配置决定主键具体的失效时间全部都维护在 expires 这个字典表中。