故障描述
处理经过
原因分析
故障总结
新入职的小O同学正在吃饭,突然
Redis无法正常提供数据,研发请求Redis一会能读到数据一会读不到数据
时间 | 处理同学 | 动作 |
12:00 | 小OP | 收到告警,放下饭碗,奔赴电脑 |
12:05 | 小OP | 查看日志和状态没有第一时间发现异常 |
12:10 | 小DE | 见小OP没结论,bypass Reids业务降级 |
12:30 | 小OP | 重启一个Redis实例,业务恢复 |
故障集群为RedisCluster模式,使用的是SmartClient,小O同学大概知道是如下流程:
小O同学登陆到机器上之后做了几件事情
查看Redis日志、监控、状态,有异常但是无法快速定位问题
在研发服务机器上进行抓包,确认问题边界确实为Redis返回空
日志和监控
由于小O同学新接手Redis,掌控尚不深入,加之故障集群Redis是运行在K8S上,所以日志和监控看了一眼就开始百度:
上边已经说明了问题,但是小O同学误以为是历史错误,从而错过了最重要的信息,草草看了一眼就结束。
Redis集群状态
紧接着小O同学在Redis上使用命令查看集群信息,没有发现问题,一度以为研发搞乌龙。
研发侧抓包
于是在研发机器上抓包,这才确认问题边界:Redis确实反回null了
正如研发所说,一会又是好的:
对比两个图,小O同学发现:
尾号82的主机会返回1
尾号104的主机会返回null
由于研发机器上没有redis-cli命令,小O使用nc命令连接尾号104的redis:
结果是MOVED到82,一切都很正常,因为
104是SLAVE
82是MASTER
为什么nc命令可以得到MOVED而业务程序得到null呢?这里涉及小O同学的知识盲区:ReadOnly
Redis 的ReadOnly要解决什么问题呢?
主从的负载不均衡问题。
ReadOnly enables read queries for a connection to a Redis Cluster replica node.
这就解决了小O为什么用nc命令会得到MOVED的原因了,因为这个连接没有开启Readonly。开启后终于复现问题,获取到null。
原来104就没有数据。这时小O终于理解了最开始的错误日志了,原来是
SLAVE没有连上Master,keyspace为空
233.71是一个根本不存在的IP,可能是Pod上次残留的IP,Redis还以为它是主呢。将这个104这个实例删除之后,集群立刻恢复正常了。
小D第一时间做了降级处理,极大的减少了损失。是非常正确的。
小O疏忽了最开始的日志定位时间较长。所以监控和日志还是要仔细观看。