米国のグループは、いくつかのピット-3.redis Redisのメモリフットプリントを踏ん舞い上がります
ブログカテゴリー:ソースを記入してくださいハ:http://carlosfu.iteye.com/blog/2254154
もっとRedisの開発、運用・保守だけでなく、アーキテクチャの新たな展開、マイクロチャンネル公衆番号への歓迎の注意:
現象:
断片化されたメモリのRedisのクラスタは、他のフラグメントよりもはるかに高い、明らかに、急騰し、そして成長し続けています。マスターからのメモリの量と一貫性がありません。
第二に、考えられる理由の分析:
バグの1のRedisクラスター(これが存在しないこと)
不均一な分布が得られ、当該2.クライアントのハッシュ(キー)、。(RedisのCRC16を使用して、その凹凸の状況が表示されません)
3.大個々のキーと値の存在:例えば、データ構造の何百万人を含むデータセット(これは可能です)
4.主な問題は、コピーから登場します。
5.その他の理由
第三に、原因を調査:
お問い合わせの際1、1-4以上存在しません
2.情報の情報を観察し、少しは疑惑を呼ん:いくつかの例外をclient_longes_output_list。
3.だから、サービスとクライアントの相互作用を理解することが予想される例この部分はメモリRedisのサーバーの多くを取るだろう場合、各入力および出力バッファのためのクライアントの設定は、バッファです。
上記client_longest_output_listビューから、それが特定のクライアントにエンドRedisのサーバから出力されたデータの大きい、大量の出力バッファメモリであるべきです。
于是使用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命令的进程后,内存很快就降下来了。
五、 预防办法:
1. 为什么会有monitor这个命令发生,我想原因有两个:
(1). 工程师想看看究竟有哪些命令在执行,就用了monitor
(2). 工程师对于redis学习的目的,因为进行了redis的托管,工程师只要会用redis就可以了,但是作为技术人员都有学习的好奇心和欲望。
2. 预防方法:
(1) 对工程师培训,讲一讲redis使用过程中的坑和禁忌
(2) 对redis云进行介绍,甚至可以让有兴趣的同学参与进来
(3) 针对client做限制,但是官方也不建议这么做,官方的默认配置中对于输出缓冲区没有限制。
(4) 密码:redis的密码功能较弱,同时多了一次IO
(5) 修改客户端源代码,禁止掉一些危险的命令(shutdown, flushall, monitor, keys *),当然还是可以通过redis-cli来完成
(6) 添加command-rename配置,将一些危险的命令(flushall, monitor, keys * , flushdb)做rename,如果有需要的话,找到redis的运维人员处理
六、模拟实验:
1. 开启一个空的Redis(最简,直接redis-server)
client缓冲区:
2. 开启一个monitor:
3. 使用redis-benchmark:
4. 观察
(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
部分日志:
- =========================2015-11-06_10:07:16===============================
- #Client-Monitor
- id=7 addr=127.0.0.1:56358 fd=6 name= age=91 idle=0 flags=O db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=4869 omem=133081288 events=rw cmd=monitor
- # Clients
- connected_clients:502
- client_longest_output_list:4869
- client_biggest_input_buf:0
- blocked_clients:0
- # Memory
- used_memory:174411224
- used_memory_human:166.33M
- used_memory_rss:161513472
- used_memory_peak:176974792
- used_memory_peak_human:168.78M
- used_memory_lua:36864
- mem_fragmentation_ratio:0.93
- mem_allocator:jemalloc-3.6.0