Redis cluster故障复盘,预案、工具、判断一样都不能少!
点击上方蓝色字体,关注我们
背景
最近从ELK日志分析发现:
有很多应用连接redis 超时; 监控平台出现”redis 集群不健康“告警;
结合之前的经验,我们一般的应处理手段为:重启连接redis超时的应用,原因有以下两点:
由于redis cluster 发生主从切换,这部分应用没有重连机制,从而导致连接超时; 部分应用使用了redis 分布式锁,可能会出现死锁的情况;
但是这次并没有像我们预想的那样将问题解决,集群仍然不健康而且主节点频繁切换。
快速定位
对于故障的快速定位,我们采用以下几个步骤:
应用版本发布是固定的发版窗口,而此问题出现于版本发布前,因此排除版本影响; Redis cluster 是多应用公用的,因此又有以下几种情况:
某个应用批量数据导入,影响整个redis cluster,此情况大多伴随高网络流量; 某个应用执行keys、del等产生命令堵塞,此情况大多是使用规范的问题;
从以上两种情况分析,显然检查网络流量是比较简单的。
1.流量分析
在几百个应用同时使用,虽然目标单一,我们却无法直接通过监控平台的网卡流量监控来查明原因。还好我们的网络流量监控手段比较丰富,借助科来网络分析系统(前提是网络设备做好流量镜像)可以非常容易的进行流量统计。
通过流量分析,很快定位某个应用和redis cluster的流量很高,经询问相关人员是在进行批量数据导入。果断叫停数据导入并观察,发现集群最终恢复正常。
比较幸运的是,虽然我们的第一种猜测就得到了验证,但运维是不能碰运气的。因此我们还需要查询命令所耗费的时间,以更好的定位是否会引起命令阻塞。
2.命令耗时
Slow log是Redis用来记录查询执行时间的日志系统。
查询执行时间指的是不包括像客户端响应(talking)、发送回复等 IO 操作,而单单是执行一个查询命令所耗费的时间。 slow log 保存在内存里面,读写速度非常快,因此你可以放心地使用它,不必担心因为开启 slow log 而损害 Redis 的速度。
「设置 SLOWLOG」
Slow log的行为由两个配置参数指定,可以通过改写 redis.conf 文件或者用 CONFIGGET 和 CONFIGSET 命令对它们动态地进行修改。
slowlog-log-slower-than ,它决定要对执行时间大于多少微秒(microsecond,1秒 = 1,000,000 微秒)的查询进行记录。 slowlog-max-len ,它决定 slow log _最多_能保存多少条日志, slow log 本身是一个 FIFO 队列,当队列大小超过 slowlog-max-len 时,最旧的一条日志将被删除,而最新的一条日志加入到 slow log ,以此类推。
# 1.记录所有查询时间大于等于 100 微秒的查询:
redis> CONFIG SET slowlog-log-slower-than 100
# 2.slow log 最多保存 1000 条日志:
redis> CONFIG SET slowlog-max-len 1000
# 3.查询两个选项的当前值
redis> CONFIG GET slowlog-log-slower-than
1) "slowlog-log-slower-than"
2) "100"
redis> CONFIG GET slowlog-max-len
1) "slowlog-max-len"
2) "1000"「查询命令耗时」
# 查询时间大于等于 10 微秒的命令
redis> SLOWLOG GET
1) 1) (integer) 12 # 唯一性(unique)的日志标识符
2) (integer) 1324097834 # 被记录命令的执行时间点,以 UNIX 时间戳格式表示
3) (integer) 16 # 查询执行时间,以微秒为单位
4) 1) "CONFIG" # 执行的命令,以数组的形式排列
2) "GET" # 这里完整的命令是 CONFIG GET slowlog-log-slower-than
3) "slowlog-log-slower-than"
相对于monitor虽实时查询命令但不能进行耗时统计,而slowlog更优雅而且不会阻塞命令,因此我们可以放心使用。在实际生产中我们尽量避免使用keys *、del等命令,可以使用scan、unlink 代理。
追根溯源
1.redis日志
* SYNC append only file rewrite performed
* AOF rewrite: 3596 MB of memory used by copy-on-write
* Background AOF rewrite terminated with success
* Residual parent diff successfully flushed to the rewritten AOF (18291.44 MB)
* Background AOF rewrite finished successfully
# Failover auth denied to 97d95b7ewoejasdfj32k0993: its master is up
# Configuration change detected. Reconfiguring myself as a replica of 97d95b7ewoejasdfj32k0993
# Connection with replica 10.10.123.100:6379 lost.
* Before turning into a replica, using my master parameters to synthesize a cached master:
* Connecting to MASTER 10.10.123.100:6379
* MASTER <-> REPLICA sync started
* Non blocking connect for SYNC fired the event.
* Master replied to PING, replication can continue...
* Trying a partial resynchronization (request 23jas8923as12lade209uc3 )
* Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.
* FAIL message received from 2039usadj932laskdg90q2139ri about 97d95b7ewoejasdfj32k0993
* Cluster state changed: fail
从以上一条关键信息”Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.“ 可以看出:
aof文件增长到指定阈值需要进行rewrite,fsync将数据写入磁盘,此时会产生大量磁盘IO; 如果fysnc没有完成,此时aof文件又触发rewrite,再次请求fsync将数据写入磁盘,从而导致redis运行变慢甚至阻塞;
2.redis配置文件
# 开启aof
appendonly yes
# aof策略每秒写入一次
appendfsync everysec
# 保证数据尽可能少的丢失,设置为no,最多丢失2s数据,设置为yes,最多会丢失30s数据
no-appendfsync-on-rewrite no
# 触发重写百分比 (如果设置为0,将禁用AOF自动重写功能)
auto-aof-rewrite-percentage 100
# 触发自动重写的最低文件体积(小于64MB不自动重写)
auto-aof-rewrite-min-size 64mb
# redis启动加载aof文件时,忽略掉错误的命令,尽可能多的加载可用命令
aof-load-truncated yes
# 分批刷入aof文件,可以有效利用顺序IO
aof-rewrite-incremental-fsync yes
其中比较重要的参数为no-appendfsync-on-rewrite no/yes,其中:
yes:触发rewrite时,新数据执行AOF操作时不会进行fsync(),数据暂存于 aof buffer缓冲区,等待BGSAVE或BGREWRITEAOF结束后进行刷盘; no:触发rewrite时,新数据执行AOF操作时也会进行fsync(),默认为no;
而由于此项参数我们配置为no,因此会导致没有等待fsync刷盘结束,再次触发fsync,导致redis不堪重负。
3.监控
对于redis cluster 我们目前只有状态类监控,如:
集群健康状态 集群节点数量 集群内存使用情况
但是对于核心指标类监控是缺少的,从而导致后期没有足够的运行数据来帮助我们更好的分析问题,在此我们可借鉴补充以下指标的监控。
主要从aof触发rewrite文件大小和fsync处理延时两个方面进行监控。
总结
通过本次故障的复盘,我们从以下方面有所启发:
第一时间以恢复系统为主,快速排除系统变更或其他操作等外部因素,根据应急预案快速重启相关应用; 监控平台固然重要,但也要善于结合流量统计、抓包、安全等外部工具来排查问题; 对于中间件或其他公共组件,监控平台只有状态监控,缺少性能或核心指标监控;
对的那条路,往往不是最好走的!
精彩文章合集
文章推荐
札记:最好的架构、需求和设计出自:自组织团队。
-- 敏捷团队
喜欢这篇文章,记得点赞+在看哦~