原创

redis线上运维系列-redis执行命令慢排查思路

redis大家都很熟了,各种ccuurrdd哈哈

1.在大公司 redis可能都是被公司的中间件人员包装一层,然后给你负责运维,不需要考虑各种redis运维问题
2.如果在小公司呢,特别是独角兽公司,还没不具备完善的 运维体系,前期会考虑成本问题自己搭建redis集群
3.大部分情况下 redis都是极快的 ms级别不需要考虑,但是在业务功能不停增加的前提下,redis会出现各种各样的问题
4.下面主要说下 我在某独角兽直播公司的时候 线上运维redis排查问题的过程

我就尽量不上图片了。。。我的图片服务器资源紧张哈哈
思路

1.首先看看最大连接数设置

ZBMAC-C02WD12BH:~ lishihao$ redis-cli -h 127.0.0.1 -p 6379 CONFIG GET maxclients
1) "maxclients"
2) "10000"

2.当前连接的客户端数和阻塞客户端连接数

ZBMAC-C02WD12BH:~ lishihao$ redis-cli -h 127.0.0.1 -p 6379 info Clients
# Clients
connected_clients:2002
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0

我这里的连接数是 本地java模拟出来的,明显连接数还有很多不是链接数不够导致的
假如真的是链接打满了 你的redis-cli是连不上也看不到当前连接数的怎么办呢
执行shell命令查看,因为我的链接客户端和redis-service都在本机所以我把连接数除以2了!!

利用netstat和tcp连接状态来判断redis当前的连接数,所以在连接数真的满了的情况也可以根据此命令来证明

解决办法就是适当增加redis连接数,不是长久之计,最好根据业务拆分,增加reids集群或者增加读实例

3.如果不是连接数满了导致等等获取连接 间接导致redis执行命令慢的话 就可能是某个命令慢了比如某个时间复杂度为O(n)并且key特别大的命令慢了

其中需要注意的是 如果某个命令慢 会导致所有连接该redis服务的客户端都慢,因为redis在99%的情况下单线程执行出来命令的,一个耗时的key会阻塞其他客户端执行命令!
`

#直接先看redis的慢日志,慢日志是在内存的 直接看不会对线上有影响
`

3)标识执行时间的微秒 4)当前命令已数组形势呈现 5)执行的客户端ip地址

从慢日志可以的5)可以定时是那台机器,再根据机器上的业务找到相关负责人~
或者直接根据命令找人,让他自己去优化,最好是把时间复杂度高的大key hash一下,或者根据有个业务id进行取模 还是另一个维度的hash分散key
从而解决执行某key的时候导致慢

4.如果连慢日志都没该怎么办呢~终极办法MONITOR

此命令是比较耗时的命令,在线上执行的时候时间决不能太多,顶多1秒的日志已经足够分析了
下面是我自己redis客户端模拟出来1秒的monitor数据,线上数据库肯定更加复杂
下图 里面的记录条数大概是0.0006秒的数据

注意因为是线上排查问题要注意使用命令不能使用cat命令或者输出查询大于1000行的日志比如head -n 2000会导致浪费线上cpu和内存资源
参考使用akw和sed等文本处理工具可以有效防止对线上机器造成性能影响!!

其中第二列就是当前客户端的ip+端口号
第一列是时间戳
第三列是命令
第四轮是命令参数
图中凭多年开发经验 明显ZREMRANGEBYSCORE这个命令就在使用上有问题了!此命令时间复杂度O(log(N)+M)比较高,而且频率也太高了。业务程序肯定是是需要改的
在看图中RPOP也有问题啊

图中命令可以看出来在1秒的monitor日志里面竟然有7016次执行rpop,我本机redis的qps 25000左右,当前日志只有22000+行

分析图中RPOP 和 LPUSH的1秒之内执行的次数,明显是取的速度远远大于塞入的速度的在,这就白白浪费cpu和redis的资源,属于程序设计不合理

整体分析一下 这1秒的monitor数据执行的命令次数排行~
根据monitor来分析redis慢是最常见的,也是最有效的,可以方便找出那些命令频繁无意义的执行占用redis资源 导致其他redis客户端执行命令
思路到此结束,如果你有更加有效高效的思路欢迎留言互相学习~

正文到此结束
本文目录