踩坑redis混部,导致AOF写磁盘过多,导致影响其他实例。通过与sre协作、分析日志,解决了问题。
背景
组内维护了一个较老的服务,从22年10月国庆开始,偶发出现了redis相关报错。
报错示例:
|
|
这个服务的这种报错,以假期的规律出现,比如国庆假期第一天上午,开始频繁报警。
同周期出现的,还有另一个报错:
|
|
对应报错的接口是一个资质查询的缓存。一周维度的请求数据为:
近一周总访问量 12,595,893,qps 352 。
分析
分析日志
首先通过日志,可以看到报错给出两个信息:
- 拿不到连接
- 可能的原因:
- Redis宕机了。
- 应用使用了比服务端连接池更多的连接。
- 应用使用完连接后,没及时释放连接资源。
- 可能的原因:
- 连接超时
- 读取响应超时,可能的原因:
- Redis服务器的资源利用率过高或内存不足。
- Redis连接池配置错误,导致连接过多或连接过少。
- Redis客户端未启用自动断开连接功能,导致连接空闲时间过长。
- Redis命令执行时间过长,例如在BLPOP操作时,阻塞等待响应时间超过了socket_timeout设置的时间。
- Redis建立连接超时时间过短,例如socket_connect_timeout设置的时间过短。
- 读取响应超时,可能的原因:
排查应用流量
观察到报错随着假期(高峰期)的周期出现,于是通过日志平台与监控验证下我们服务的流量是否有高峰激增。
日志、监控显示,我们的流量并没有激增太多。结合背景部分的具体数据,qps 352 对于Redis即使是单实例也完全形不成压力。
所以问题流量并没经过我们这个服务。
那么这就奇怪了!!!
与sre协作
本服务内找不到问题,尝试找sre,看看有没有什么有效信息。
一问,sre给出了关键日志:
|
|
如果熟悉Redis,可以get到,此时我们的Redis实例正被阻塞于AOF fsync写文件的操作上,但是由于磁盘IO过高,磁盘此时压力过大, fsync一直卡着。
这也是导致我们的服务一直拿不到Redis连接的直接原因!
接着我们验证了服务对应Redis的AOF写入量,发现并不多!这就奇怪了!
再次询问sre,得知这台Redis与其他20+个实例混合部署在同一台机器上。
此时,所有疑点都明朗了。
破案
我们的Redis由于与其他20+个实例混部在同一台机器上,其他实例流量激增导致磁盘压力过大,导致我们的实例迟迟无法获取到IO权限。
服务端这边也迟迟拿不到连接,看到的假象就是Redis停止服务!
解决
捋清脉络,并且与相关干系人快速沟通后,我们决定切换Redis实例到独立的机器上。
操作后,此报错在多个假期未出现,问题解决!