美团在Redis上踩过的一些坑-3.redis内存占用飙升(转载)

一、现象:

redis-cluster某个分片内存飙升,明显比其他分片高很多,而且持续增长。并且主从的内存使用量并不一致。

二、分析可能原因:

1.  redis-cluster的bug (这个应该不存在)

2. 客户端的hash(key)有问题,造成分配不均。(redis使用的是crc16, 不会出现这么不均的情况)

3. 存在个别大的key-value: 例如一个包含了几百万数据set数据结构(这个有可能)

4. 主从复制出现了问题。

5. 其他原因

三、调查原因:

1. 经查询,上述1-4都不存在

2. 观察info信息,有一点引起了怀疑: 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做限制,但是官方也不建议这么做,官方的默认配置中对于输出缓冲区没有限制。

Java代码  

  1. client-output-buffer-limit normal 0 0 0

(4) 密码:redis的密码功能较弱,同时多了一次IO

(5) 修改客户端源代码,禁止掉一些危险的命令(shutdown, flushall, monitor, keys *),当然还是可以通过redis-cli来完成

(6) 添加command-rename配置,将一些危险的命令(flushall, monitor, keys * , flushdb)做rename,如果有需要的话,找到redis的运维人员处理

Java代码  

  1. rename-command FLUSHALL "随机数"
  2. rename-command FLUSHDB "随机数"
  3. rename-command KEYS "随机数"

六、模拟实验:

1.  开启一个空的Redis(最简,直接redis-server)

Java代码  

  1. redis-server

初始化内存使用量如下:

Java代码  

  1. # Memory
  2. used_memory:815072
  3. used_memory_human:795.97K
  4. used_memory_rss:7946240
  5. used_memory_peak:815912
  6. used_memory_peak_human:796.79K
  7. used_memory_lua:36864
  8. mem_fragmentation_ratio:9.75
  9. mem_allocator:jemalloc-3.6.0

client缓冲区:

Java代码  

  1. # Clients
  2. connected_clients:1
  3. client_longest_output_list:0
  4. client_biggest_input_buf:0
  5. blocked_clients:0

2. 开启一个monitor:

Java代码  

  1. redis-cli -h 127.0.0.1 -p 6379 monitor

3. 使用redis-benchmark:

Java代码  

  1. redis-benchmark -h 127.0.0.1 -p 6379 -c 500 -n 200000

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--观察附件中日志

监控脚本:

Java代码  

  1. while [ 1 == 1 ]
  2. do
  3. now=$(date "+%Y-%m-%d_%H:%M:%S")
  4. echo "=========================${now}==============================="
  5. echo " #Client-Monitor"
  6. redis-cli -h 127.0.0.1 -p 6379 client list | grep monitor
  7. redis-cli -h 127.0.0.1 -p 6379 info clients
  8. redis-cli -h 127.0.0.1 -p 6379 info memory
  9. #休息100毫秒
  10. usleep 100000
  11. done

完整的日志文件:

http://dl.iteye.com/topics/download/096f5da0-4318-332e-914f-6f7c7298ddc9

部分日志:

Java代码  

  1. =========================2015-11-06_10:07:16===============================
  2. #Client-Monitor
  3. 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
  4. # Clients
  5. connected_clients:502
  6. client_longest_output_list:4869
  7. client_biggest_input_buf:0
  8. blocked_clients:0
  9. # Memory
  10. used_memory:174411224
  11. used_memory_human:166.33M
  12. used_memory_rss:161513472
  13. used_memory_peak:176974792
  14. used_memory_peak_human:168.78M
  15. used_memory_lua:36864
  16. mem_fragmentation_ratio:0.93
  17. mem_allocator:jemalloc-3.6.0

转载地址:http://blog.csdn.net/liqfyiyi/article/details/50894004

http://carlosfu.iteye.com/blog/2254154

时间: 2024-12-23 10:17:40

美团在Redis上踩过的一些坑-3.redis内存占用飙升(转载)的相关文章

美团在Redis上踩过的一些坑-目录(本人非美团)(转)

来自:http://carlosfu.iteye.com/blog/2254154 分为5个部分: 一.周期性出现connect timeout 二.redis bgrewriteaof问题 三.redis内存占用飙升 四.redis内存使用优化 五.redis cluster遇到的一些问题 附赠PPT: (1) 本次:美团在Redis上踩过的一些坑PPT (2) 以往:<Redis在新浪的大规模运维经验>-演讲人:侯军伟新浪高级DBA.pdf 美团数据库运维平台介绍.pdf

Redis上踩过的一些坑

来自: http://blog.csdn.net//chenleixing/article/details/50530419 上上周和同事(龙哥)参加了360组织的互联网技术训练营第三期,美团网的DBA负责人侯军伟给大家介绍了美团网在redis上踩得一些坑,讲的都是干货和坑. 分为5个部分: 一. 周期性出现connect timeout 二.redis bgrewriteaof问题 三.redis内存占用飙升 四.redis内存使用优化 五.redis cluster遇到的一些问题 一.周期性

线上应用故障排查之二:高内存占用

搞Java开发的,经常会碰到下面两种异常: 1.java.lang.OutOfMemoryError: PermGen space 2.java.lang.OutOfMemoryError: Java heap space 要详细解释这两种异常,需要简单重提下Java内存模型. Java内存模型是描述Java程序中各变量(实例域.静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节. 在Java虚拟机中,内存分为三个代:新生代(New).老生代(Ol

线上应用故障排查之二:高内存占用(转)

搞Java开发的,经常会碰到下面两种异常: 1.java.lang.OutOfMemoryError: PermGen space 2.java.lang.OutOfMemoryError: Java heap space 要详细解释这两种异常,需要简单重提下Java内存模型. (友情提示:本博文章转载,出处:hankchen,http://www.blogjava.net/hankchen) Java内存模型是描述Java程序中各变量(实例域.静态域和数组元素)之间的关系,以及在实际计算机系统

细说分布式Redis架构设计和踩过的那些坑

摘要:本文章主要分成五个步骤内容讲解 Redis.RedisCluster和Codis; 我们更爱一致性; Codis在生产环境中的使用的经验和坑们; 对于分布式数据库和分布式架构的一些看法; Q & A环节. Codis是一个分布式Redis解决方案,与官方的纯P2P的模式不同,Codis采用的是Proxy-based的方案.今天我们介绍一下Codis及下一个大版本RebornDB的设计,同时会介绍一些Codis在实际应用场景中的tips.最后抛砖引玉,会介绍一下我对分布式存储的一些观点和看法

[转载] Codis作者黄东旭细说分布式Redis架构设计和踩过的那些坑们

原文: http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=208733458&idx=1&sn=691bfde670fb2dd649685723f7358fea&scene=1&key=c76941211a49ab58cb17c68ecaeeda0f1c083d9508a0f6629461fff9025fd87de4706bd9c1730e0ddbab70568b34b16a&ascene=0&

Codis作者黄东旭细说分布式Redis架构设计和踩过的那些坑们

本次分享的内容主要包括五个大部分: Redis.RedisCluster和Codis; 我们更爱一致性; Codis在生产环境中的使用的经验和坑们; 对于分布式数据库和分布式架构的一些看法; Q & A环节. ??Codis是一个分布式Redis解决方案,与官方的纯P2P的模式不同,Codis采用的是Proxy-based的方案.今天我们介绍一下Codis及下一个大版本RebornDB的设计,同时会介绍一些Codis在实际应用场景中的tips.最后抛砖引玉,会介绍一下我对分布式存储的一些观点和看

基于ServiceStack.Redis上对REDIS访问的再次封装

概述 RedisOpLib.dll 是基于ServiceStack.Redis上对Redis操作的再一次封装,引用此类之后对REDIS操作变的很简单 2.组成 a. RedisOpLib.dll 封装的主文件 b. Redis.config   默认的配置文件,还可以随意增加如 RedisA.config,RedisB.config,此配置文件结构如下: <configuration>  <AutoStart>YES</AutoStart>  <IdleTimeO

关于CentOS上以低权限用户自启动Tomcat,Redis这类应用服务器的坑

工作太忙了,许久没有上来写个文,今天给大家写一下关于CentOS上以低权限用户自启动Tomcat,Redis这类应用服务器的坑. 最近接手了一个NLP分布式平台架构,实施过程中运维工程师给我埋了一个致命的BUG,Redis服务由于使用了Root用户运行,且,云主机的虚拟外网IP与内网IP之间互相映射,加至没有注意到IPTABLE的设定,致使虽然Redis是只监听了内网IP,但,其实情况是,外网扫描端口时,仍然能顺利通过"未授权"方式或暴力破解方式,击倒Redis天生的软肋(弱爆的密码策