【Redis 故障排查】「连接失败问题排查和解决」带你总体分析 CPU 及内存的使用率高问题排查指南及方案
主体内容
Redis 实例 CPU 使用率高问题排查和解决
Redis 实例内存使用率高问题排查和解决
Redis 实例 CPU 使用率高问题排查和解决
问题现象
Redis 实例 CPU 使用率短时间内冲高。CPU 过高可能会导致连接超时,影响业务。
发生 Redis 的持久化重写操作,排查及处理措施请参考是否存在 Redis 的持久化重写操作。
排查 QPS 是否过高
客户的业务负载过重,qps 过高,导致 CPU 被用满,排查方法请参考排查 QPS 是否过高。此时可以查看 Info 指令下的 commandstats 子指令进行分析和输出。分析指令执行情况。
查找并禁用高消耗命令
使用了 keys 等消耗资源的命令,排查及处理措施请参考查找并禁用高消耗命令。高消耗资源的命令即时间复杂度为 O(N)或更高的命令,通常情况下,命令时间复杂度越高,在执行时消耗的资源越高,这会导致 CPU 使用率超高,容易触发主备倒换。关于各命令对应的时间复杂度信息请参见 Redis 官网。例如,使用了 keys 等消耗资源的命令,导致 CPU 超高,建议客户改成 scan 命令或者禁用 keys 命令。
慢查询的定位
找出 CPU 使用率高的具体时间段,找出高消耗的命令的慢查询。
慢查询功能会记录执行超过指定时间阈值的命令,通过分析慢查询的语句和执行时长可帮助您找出高消耗命令,具体操参见慢查询。
慢查询是 Redis 用于记录命令执行时间过长请求的机制。查询结果中,涉及的慢语句命令详情,请前往 Redis 官方网站(中文网站)查看。
慢查询结果由实例两个配置参数决定,如下:
slowlog-log-slower-than:如果在 Redis 实例的数据节点中执行一个命令,执行时间超过了 slowlog-log-slower-than 参数设置的阈值(单位为微秒),则会被记录到慢查询中。该参数的默认值为 10000,即 10ms,当 Redis 命令执行时间超过 10ms,则生成慢查询。
slowlog-max-len:Redis 记录的慢查询个数由 slowlog-max-len 参数的值决定,默认值为 128 个。当慢查询个数超过 128 时,会将旧的慢查询删除,记录新的慢查询。
读取慢查询日志
慢查询日志在内存中堆积,因此不会写入一个包含慢速命令执行信息的文件。 这使得慢查询日志非常快,你可以开启所有命令的日志记录(设置_slowlog-log-slower-than_参数值为零),但性能较低。
要读取慢查询日志,请使用 SLOWLOG GET 命令,此命令返回慢查询日志中的每一个条目。 可以只返回最近的 N 个条目,通过给命令传入一个额外的参数(例如:SLOWLOG GET 10)。
输出格式
结果的四个字段组成:
每个慢查询条目的唯一的递增标识符。
处理记录命令的 unix 时间戳。
命令执行所需的总时间,以微秒为单位。
组成该命令的参数的数组。
条目的唯一 ID 可以用于避免慢查询条目被多次处理(例如,你也许有一个脚本使用每个新的慢查询日志条目给你发送报警邮件)。条目 ID 在 Redis 服务器运行期间绝不会被重置,仅在 Redis 服务重启才重置它。
获取慢查询日志的当前长度
使用命令 SLOWLOG LEN 可以获得慢查询日志的长度。
重置慢查询日志
你可以使用命令 SLOWLOG RESET 来重置慢查询日志。删除后,信息将永远丢失。
除了 Keys 之外,Redis 的高风险命令和高消耗命令:FLUSHALL、HGETALL 等。
Redis 的持久化重写操作也会导致 CPU 飙高
对于主备和集群实例,Redis 实例默认开启 AOF 数据落盘,还有有伴随着 AofRewrite 的磁盘整理,AOF 磁盘持久化整理一般在以下 2 种场景执行:
数据量写入不大,AOF 文件不大时,固定在每天的凌晨 1-4 点进行 AOF 持久化重写。所以容易出现这个时间点实例 CPU 使用率超高的现象。
数据量写入过大,AOF 文件大小超过阈值(缓存实例容量的 3-5 倍)时,不论当前的所处的时间,会自动触发后台 AOF 持久化重写。
Redis 的持久化重写操作(Bgsave 或 Bgrewriteaof)比较消耗 CPU 资源,Bgsave 和 Bgrewriteaof 会调用系统的 Fork 机制,造成 CPU 短暂时间冲高。
如果不需要用到持久化功能,建议将该功能关闭(请根据实际业务慎重操作,关闭持久化功能会导致极端故障场景下恢复时,由于没有落盘造成的数据丢失)。关闭操作:将“appendonly”修改为“no”。
Redis 实例内存使用率高问题排查和解决
问题现象
Redis 可提供高效的数据库服务,当内存不足时,可能导致 Key 频繁被逐出、响应时间上升、QPS(每秒访问次数)不稳定等问题,进而影响业务运行。由于 Redis 自身运行机制(主从同步、延迟释放等),内存占用率可能出现略微超过 100%的情况,此为正常情况,此时内存已经写满,用户需要考虑扩容,或者清理一些无用的数据。通常情况下,当内存使用率超过 95%时需要及时关注。
排查原因
查询指定时段的内存使用率信息,“内存利用率”指标持续接近 100%。
查询内存使用率超过 95%的时间段内,“已逐出的键数量”和“命令最大时延”,均呈现显著上升趋势,表明存在内存不足的问题。
Redis 实例如果内存满了但是 key 不多,可能原因是客户端缓冲区(output buffer)占用过多的内存空间。可以在 Redis-cli 客户端连接实例后,执行大 key 扫描命令:redis-cli --bigkeys
,然后执行 info,查看 output buffer 占用情况。
bigkeys 和 hotkeys 参数查找大 Key 和热 Key
Redis-cli 提供了 bigkeys 参数,能够使 redis-cli 以遍历的方式分析 Redis 实例中的所有 Key,并返回 Key 的整体统计信息与每个数据类型中 Top1 的大 Key,bigkeys 仅能分析并输入六种数据类型(STRING、LIST、HASH、SET、ZSET、STREAM),命令示例为:redis-cli -h <实例的连接地址> -p <端口> -a <密码> --bigkeys
。
自 Redis 4.0 版本起,redis-cli 提供了 hotkeys 参数,可以快速帮您找出业务中的热 Key,该命令需要在业务实际运行期间执行,以统计运行期间的热 Key。命令示例为:redis-cli -h <实例的连接地址> -p <端口> -a <密码> --hotkeys
。热 Key 的详情可以在结果中的 summary 部分获取到。
优化建议:
string 类型控制在 10KB 以内,hash、list、set、zset 元素尽量不超过 5000。
版权声明: 本文为 InfoQ 作者【洛神灬殇】的原创文章。
原文链接:【http://xie.infoq.cn/article/7590f575ebfa05347be9f613f】。文章转载请联系作者。
评论