Redis变慢了?之二

  • Redis变慢了
  • 规律性变慢
  • Redis几种过期策略的区别?
  • 定时过期
  • 惰性过期
  • 定期过期
  • 优化方案
  • 实例内存达上限
  • 内存淘汰策略
  • 写在最后


Redis变慢了

Redis变慢上一篇文章地址:Redis变慢了?这篇文章继续Redis变慢情况的分析。

规律性变慢

在使用Redis的过程中,大家有没有遇到过Redis总是会不定时的规律性的变慢,这种情况一般就是说在固定的时间点有大量的Redis key过期,此时大量访问进来的话响应就会变慢。

Redis几种过期策略的区别?

Redis过期策略主要有三种:定时过期、惰性过期、定期过期。

定时过期

定时过期:在设置 key 的过期时间时,同时创建一个定时事件,当时间到达时,由事件处理器自动执行 key 的删除操作。
优点:可以保证过期 key 会被尽快删除,也就是内存可以被尽快地释放。因此,定时过期对内存是最好的。
缺点:在过期 key 比较多的情况下,删除过期 key 可能会占用相当一部分 CPU 时间,在内存不紧张但 CPU 时间紧张的情况下,将 CPU 时间用于删除和当前任务无关的过期键上,无疑会对服务器的响应时间和吞吐量造成影响。所以,定时过期策略对 CPU 不太好。

惰性过期

惰性过期:每次不主动删除过期键,从数据库访问 key 时,都检测 key 是否过期,如果过期则删除该 key。
优点:因为每次访问时,才会检查 key 是否过期,所以此策略只会使用很少的系统资源,因此,惰性过期策略对 CPU 时间最好。
缺点:如果一个 key 已经过期,而这个 key 又仍然保留在数据库中,那么只要这个过期 key 一直没有被访问,它所占用的内存就不会释放,造成了一定的内存资源浪费。所以,惰性过期策略对内存不太好。

定期过期

定期过期:每隔一段时间「随机」从数据库中取出一定数量的 key 进行检查,并删除其中的过期key。随机抽查的数量由 ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 定义的,它是写死在代码中的,数值是 20。
优点:通过限制删除操作执行的时长和频率,来减少删除操作对 CPU 的影响,同时也能删除一部分过期的数据减少了过期键对空间的无效占用。
缺点:内存清理方面没有定时删除效果好,同时没有惰性过期使用的系统资源少。难以确定删除操作执行的时长和频率。如果执行的太频繁,定期过期策略变得和定时过期策略一样,对CPU不友好;如果执行的太少,那又和惰性过期一样了,过期 key 占用的内存不会及时得到释放。

优化方案

首先在配置redis时选择合适的过期策略搭配,然后就是在业务代码中尽量避免同一时间大批量key过期的情况,分散过期key的时间,减少由于删除过期key,以及大量访问时带来的延迟。

实例内存达上限

Redis当 Redis 的运行内存已经超过 Redis 设置的最大内存之后,则会使用内存淘汰策略删除符合条件的 key,以此来保障 Redis 高效的运行。而踢出旧数据的逻辑也是需要消耗时间的,这也就是当Redis运行内存达上限时写入数据会变慢的情况。

内存淘汰策略

Redis内存淘汰策略主要有以下几种:
• noeviction :它表示当运行内存超过最大设置内存时,不淘汰任何数据,这时如果有新的数据写入,则会触发 OOM,如果只是查询和删除的话则不影响。
对于设置了过期时间的淘汰策略:
• volatile-random:随机淘汰设置了过期时间的任意键值。
• volatile-ttl:优先淘汰更早过期的键值。
• volatile-lru:淘汰所有设置了过期时间的键值中,最久未使用的键值。
• volatile-lfu:淘汰所有设置了过期时间的键值中,最少使用的键值。
对于所有数据适用的淘汰策略:
• allkeys-random:随机淘汰任意键值。
• allkeys-lru:淘汰整个键值中最久未使用的键值。
• allkeys-lfu:淘汰整个键值中最少使用的键值。
一般常用的是allkeys-lru / volatile-lru 淘汰策略。
查看当前Redis淘汰策略

127.0.0.1:6379> config get maxmemory-policy

Redis变慢了?之二_过期策略


可以看到配置的是volatile-lru,设置淘汰策略可以用 【config set maxmemory-policy <策略>】但是Redis重启之后会失效,如果需要永久生效的话需要在配置文件中设置并重启Redis。

写在最后

后续会继续分析其他场景下Redis变慢的情况,敬请关注。