客户端案例分析
-
Redis内存陡增
-
现象
服务端现象:Redis主节点内存陡增,几乎用满maxmemory,而从节点内存并没有变化。
客户端现象:客户端产生了OOM异常,也就是Redis主节点使用的内存已经超过了maxmemory的设置,无法写入新的数据:
redis.clients.jedis.exceptions.JedisDataException:OOM command not allowed when used memory > 'maxmemory'
-
分析原因
从现象看,可能的原因有两个。
1)确实有大量写入,但是主从复制出现问题:查询了Redis复制的相关信息,复制是正常的,主从数据基本一致。
主节点的键个数:
127.0.0.1:6379> dbsize (integer) 2126870
从节点的键个数:
127.0.0.1:6379> dbsize (integer) 2126870
2)其他原因造成主节点内存使用过大:排查是否由客户端缓冲区造成主节点内存陡增,使用info clients命令查询相关信息如下:
127.0.0.1:6379> info clients # Clients connected_clients:1891 client_longest_output_list:225698 client_biggest_input_buf:0 blocked_clients:0
很明显输出缓冲区不太正常,最大的客户端输出缓冲区队列已经超过了20万个对象,于是需要通过client list命令找到omem不正常的连接,一般来说大部分客户端omem为0(因为处理速度会足够快),于是执行如下代码,找到omem非零的客户端连接:
redis-cli client list | grep -v "omem=0"
-
处理方法和后期处理
对这个问题处理的方法相对简单,只要使用client kill命令杀掉这个连接,让其他客户端回复正常写数据即可。但是更为重要的是在日后如何及时发现和避免这种问题的发生,基本有三点:
-
从运维层面禁止monitor命令,例如使用rename-command命令重置monitor命令为一个随机字符串,除此之外,如果monitor没有做rename-command,也可以对monitor命令进行相应的监控(例如client list)
-
从开发层面进行培训,禁止在生产环境中使用monitor命令,因为有时候monitor命令在测试的时候还是比较有用的,完全禁止也不太现实。
-
限制输出缓冲区的大小。
-
使用专业的Redis运维工具,例如CacheCloud,上述问题在CacheCloud中会受到相应的报警,快速发现和定位问题。
-
-
-
客户端周期性的超时
-
现象
客户端现象:客户端出现大量超时,经过分析发现超时是周期性出现的,这位问题的查找提供了重要依据:
Caused by:redis.clients.jedis.exceptions.JedisConnectionException:java.net.SockedTimeoutException:connect timed out
服务端现象:服务端并没有明显的异常,只是有一些慢查询操作
-
分析
-
网络原因:服务端和客户端之间的网络出现周期性问题,经过观察网络是正常的。
-
Redis本身:经过观察Redis日志统计,并没有发现异常。
-
客户端:由于是周期性出现问题,就和慢查询日志的历史记录对应了一下时间,发现只要慢查询出现,客户端就会产生大量连接超时,两个时间点基本一致。
-
-
处理方法和后期处理
这个问题处理方法相对简单,只需要业务方及时处理自己的慢查询即可,但是更为重要的是在日后如何及时发现和避免这种问题的发生,基本有三点:
-
从运维层面,监控慢查询,一旦超过阀值,就发出报警。
-
从开发层面,加强对于Redis的理解,避免不正确的使用方式。
-
使用专业的Redis运维工具,例如CacheCloud,上述问题在CacheCloud中会受到相应的报警,快速发现和定位问题。
-
-
本文由 Meridian 创作,采用 知识共享署名4.0
国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Jul 25,2019