redis查询慢,你们是如何排查优化的?(运维篇4)

1、key集中过期

如果你发现,平时在操作 Redis 时,并没有延迟很大的情况发生,但在某个时间点突然出现一波延时,其现象表现为:变慢的时间点很有规律,例如某个整点,或者每间隔多久就会发生一波延迟。

如果是出现这种情况,那么你需要排查一下,业务代码中是否存在设置大量 key 集中过期的情况。

如果有大量的 key 在某个固定时间点集中过期,在这个时间点访问 Redis 时,就有可能导致延时变大。

2、为什么集中过期会导致 Redis 延迟变大?

 Redis 的过期数据采用被动过期 + 主动过期两种策略:

  1. 被动过期:只有当访问某个 key 时,才判断这个 key 是否已过期,如果已过期,则从实例中删除

  2. 主动过期:Redis 内部维护了一个定时任务,默认每隔 100 毫秒(1秒10次)就会从全局的过期哈希表中随机取出 20 个 key,然后删除其中过期的 key,如果过期 key 的比例超过了 25%,则继续重复此过程,直到过期 key 的比例下降到 25% 以下,或者这次任务的执行耗时超过了 25 毫秒,才会退出循环

注意,这个主动过期 key 的定时任务,是在 Redis 主线程中执行的

也就是说如果在执行主动过期的过程中,出现了需要大量删除过期 key 的情况,那么此时应用程序在访问 Redis 时,必须要等待这个过期任务执行结束,Redis 才可以服务这个客户端请求。

此时就会出现,应用访问 Redis 延时变大。

如果此时需要过期删除的是一个 bigkey,那么这个耗时会更久。而且,这个操作延迟的命令并不会记录在慢日志中

因为慢日志中只记录一个命令真正操作内存数据的耗时,而 Redis 主动删除过期 key 的逻辑,是在命令真正执行之前执行的。

所以,此时你会看到,慢日志中没有操作耗时的命令,但我们的应用程序却感知到了延迟变大,其实时间都花费在了删除过期 key 上,这种情况我们需要尤为注意。

3、如何排查过期key

 (1)、开发人员层面

此时,你需要检查你的业务代码,是否存在集中过期 key 的逻辑。

一般集中过期使用的是 expireat / pexpireat 命令,你需要在代码中搜索这个关键字。

排查代码后,如果确实存在集中过期 key 的逻辑存在,但这种逻辑又是业务所必须的,那此时如何优化,同时又不对 Redis 有性能影响呢?

一般有两种方案来规避这个问题:

  1. 集中过期 key 增加一个随机过期时间,把集中过期的时间打散,降低 Redis 清理过期 key 的压力

  2. 如果你使用的 Redis 是 4.0 以上版本,可以开启 lazy-free 机制,当删除过期 key 时,把释放内存的操作放到后台线程中执行,避免阻塞主线程

第一种方案,在设置 key 的过期时间时,增加一个随机时间,伪代码可以这么写:

这样一来,Redis 在处理过期时,不会因为集中删除过多的 key 导致压力过大,从而避免阻塞主线程。

第二种方案,Redis 4.0 以上版本,开启 lazy-free 机制:

(2)运维人员层面

 运维层面,你需要把 Redis 的各项运行状态数据监控起来,在 Redis 上执行 INFO 命令就可以拿到这个实例所有的运行状态数据。

在这里我们需要重点关注 expired_keys 这一项,它代表整个实例到目前为止,累计删除过期 key 的数量。

你需要把这个指标监控起来,当这个指标在很短时间内出现了突增,需要及时报警出来,然后与业务应用报慢的时间点进行对比分析,确认时间是否一致,如果一致,则可以确认确实是因为集中过期 key 导致的延迟变大。

 

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值