redis-cluster某个分片内存飙升,明显比其余分片高不少,并且持续增加。而且主从的内存使用量并不一致。mysql
一、redis-cluster的bug (这个应该不存在)redis
二、客户端的hash(key)有问题,形成分配不均。(redis使用的是crc16, 不会出现这么不均的状况)sql
三、存在个别大的key-value: 例如一个包含了几百万数据set数据结构(这个有可能)服务器
四、主从复制出现了问题。数据结构
五、其余缘由运维
一、经查询,上述1-4都不存在学习
二、观察info信息,有一点引发了怀疑: client_longes_output_list有些异常。lua
三、因而理解想到服务端和客户端交互时,分别为每一个客户端设置了输入缓冲区和输出缓冲区,这部分若是很大的话也会占用Redis服务器的内存。spa
从上面的client_longest_output_list看,应该是输出缓冲区占用内存较大,也就是有大量的数据从Redis服务器向某些客户端输出。3d
因而使用client list命令(相似于mysql processlist) redis-cli -h host -p port client list | grep -v "omem=0",来查询输出缓冲区不为0的客户端链接,因而查询到祸首monitor,因而豁然开朗.
monitor的模型是这样的,它会将全部在Redis服务器执行的命令进行输出,一般来说Redis服务器的QPS是很高的,也就是若是执行了monitor命令,Redis服务器在Monitor这个客户端的输出缓冲区又会有大量“存货”,也就占用了大量Redis内存。
进行主从切换(主从内存使用量不一致),也就是redis-cluster的fail-over操做,继续观察新的Master是否有异常,经过观察未出现异常。
查找到真正的缘由后,也就是monitor,关闭掉monitor命令的进程后,内存很快就降下来了。
一、工程师想看看究竟有哪些命令在执行,就用了monitor
二、工程师对于redis学习的目的,由于进行了redis的托管,工程师只要会用redis就能够了,可是做为技术人员都有学习的好奇心和欲望。
一、对工程师培训,讲一讲redis使用过程当中的坑和禁忌
二、对redis云进行介绍,甚至可让有兴趣的同窗参与进来
三、针对client作限制,可是官方也不建议这么作,官方的默认配置中对于输出缓冲区没有限制。
client-output-buffer-limit normal 0 0 0
四、密码:redis的密码功能较弱,同时多了一次IO
五、修改客户端源代码,禁止掉一些危险的命令(shutdown, flushall, monitor, keys *),固然仍是能够经过redis-cli来完成
六、添加command-rename配置,将一些危险的命令(flushall, monitor, keys * , flushdb)作rename,若是有须要的话,找到redis的运维人员处理
rename-command FLUSHALL "随机数" rename-command FLUSHDB "随机数" rename-command KEYS "随机数"
初始化状态以下:
# Memory used_memory:815072 used_memory_human:795.97K used_memory_rss:7946240 used_memory_peak:815912 used_memory_peak_human:796.79K used_memory_lua:36864 mem_fragmentation_ratio:9.75 mem_allocator:jemalloc-3.6.0 # Clients connected_clients:1 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0
redis-cli -h 127.0.0.1 -p 6379 monitor
redis-benchmark -h 127.0.0.1 -p 6379 -c 500 -n 200000
1)info memory:内存一直增长,直到benchmark结束,monitor输出完毕,可是used_memory_peak_human(历史峰值)依然很高--观察附件中日志
2)info clients: client_longest_output_list: 一直在增长,直到benchmark结束,monitor输出完毕,才变为0--观察附件中日志
3)redis-cli -h host -p port client list | grep "monitor" omem一直很高,直到benchmark结束,monitor输出完毕,才变为0--观察附件中日志
监控脚本:
while [ 1 == 1 ] do now=$(date "+%Y-%m-%d_%H:%M:%S") echo "=========================${now}===============================" echo " #Client-Monitor" redis-cli -h 127.0.0.1 -p 6379 client list | grep monitor redis-cli -h 127.0.0.1 -p 6379 info clients redis-cli -h 127.0.0.1 -p 6379 info memory #休息100毫秒 usleep 100000 done