您的位置:澳门皇冠金沙网站 > 办公软件 > 一次关于Redis内存诡异增长的排查过程实战记录

一次关于Redis内存诡异增长的排查过程实战记录

2020-04-15 14:36

一、现象

1.1.1. client list

列出所有客户端连接信息。

每个连接使用一个id=xxx的行表示。

 

 

redis.coe2coe.me:6379> client list

id=8 addr=192.168.197.101:42247 fd=6 name= age=169 idle=169 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=command

id=9 addr=192.168.197.101:42248 fd=7 name= age=134 idle=114 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client

id=10 addr=192.168.197.101:42249 fd=8 name= age=4 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

 

id:64bit唯一的客户端ID。

addr:IP地址和端口号。

fd:   socket对应的文件描述符。

name:客户端名称。使用client setname设置,client getname获取。

age:连接以来的时间,秒。

idle:空闲时间,秒。

flags:标志。

db:当前选择的数据库序号。

sub:频道订阅数量。

psub:模式匹配订阅数量。

multi: MULTI/EXEC上下文中的命令数量。

qbuf:查询缓冲区长度。

qbuf-free:查询缓冲区空闲空间。

ob1:输出缓冲区长度。

ol1:输出链表长度,当输出缓冲区满时,回复信息在这个链表中排队。

omem:输出缓冲区内存使用。

events:文件描述符事件。

cmd:执行的最后一个命令。似乎只显示命令的第1个单词。

 

flags标志的含义如下:

O:客户端在MONITOR模式中作为slave。

S:客户端是正常的slave。

M:客户端是一个master。

x: 客户端在MULTI/EXEC上下文中。

b:客户端在等待阻塞操作。

i:客户端在等待VM I/O(已废弃)。

d:观察的keys已经被修改了。

c:连接在条目回复后将被关闭。

u:客户端是非阻塞的。

U:客户端通过Unix domain socket连接。

r:客户端作为一个集群结点在只读模式中。

A:连接将尽快被关闭。

N:没有设置标志。

 

 

 

 

 

 

实例名:r-bp1cxxxxxxxxxd04(主从)

1.1.2. client  setname

设置当前连接的客户端名称。

redis.coe2coe.me:6379> client setname redis1

OK

redis.coe2coe.me:6379> client getname

"redis1"

 

redis.coe2coe.me:6379> client setname ""

OK

redis.coe2coe.me:6379> client getname

(nil)

 

在设置客户端名称之后,如果被client kill删除了,则客户端名称被清空了。

                                                                                      

问题:一分钟内存上涨了2G,如下图所示:

1.1.3. client  getname

获取当前连接的客户端名称。

redis.coe2coe.me:6379> client getname

(nil)

默认情况下名称为空。可使用client getname设置。

 

redis.coe2coe.me:6379> client setname redis1

OK

redis.coe2coe.me:6379> client getname

"redis1"

 

 

键值规模:6000万左右

1.1.4. client kill

断开指定的客户端的连接,即删除指定的客户端。可按以下几种方式进行删除:

 

(1)参数为客户端连接的IP地址和端口号。

假定当前有redis1,redis2,redis3三个连接:

redis.coe2coe.me:6379> client list

id=13 addr=192.168.197.101:42252 fd=6 name=redis3 age=489 idle=4 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client

id=14 addr=192.168.197.101:42253 fd=7 name=redis1 age=477 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

id=15 addr=192.168.197.101:42254 fd=8 name=redis2 age=41 idle=10 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client

 

现在删除掉redis3这个连接,地址为192.168.197.101:42252。

redis.coe2coe.me:6379> client kill 192.168.197.101:42252

OK

删除客户端成功。

 

再次查看客户端列表,只有2个连接了。

redis.coe2coe.me:6379> client list

id=14 addr=192.168.197.101:42253 fd=7 name=redis1 age=499 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

id=15 addr=192.168.197.101:42254 fd=8 name=redis2 age=63 idle=32 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client

redis.coe2coe.me:6379>

 

 

(2)按照客户端ID进行删除。

 

redis.coe2coe.me:6379> client kill id 14

(integer) 0

默认情况下,skipme为true,删除当前连接似乎是删除不掉的。

 

redis.coe2coe.me:6379> client kill id 14 skipme no

(integer) 1

指定skipme为no,则可以成功删除当前连接。

 

redis.coe2coe.me:6379> client kill id 16

(integer) 1

id为16的连接删除成功了。

 

客户端每次连接到redis服务后,产生一个新的ID。ID的序号总是不断的增加。

 

 

内存一分钟增长2G.png

1.1.5. client pause

让所有客户端暂停指定时间,单位,毫秒。

 

 

redis.coe2coe.me:6379> client pause 10000

OK

所有客户端将暂停10秒钟。

 

立即执行client list指令:

redis.coe2coe.me:6379> client list

并不会立即取得相应结果,而是在等待了一段时间后才取得结果:

 

id=18 addr=192.168.197.101:42257 fd=6 name= age=152 idle=7 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client

id=19 addr=192.168.197.101:42258 fd=7 name=redis3 age=121 idle=1 flags=u db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client

id=20 addr=192.168.197.101:42259 fd=8 name=redis2 age=112 idle=4 flags=u db=0 sub=0 psub=0 multi=-1 qbuf=41 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client

(7.06s)

括号中的数字表明此命令等待了7.06秒。

 

 

二、Redis内存分析

1.1.6. monitor

实时监控Redis收到的各种命令,并反馈到执行monitor命令的客户端连接上。

 

redis.coe2coe.me:6379> monitor

OK

注意:此时不再显示redis提示符。

此时在其它客户端连接上执行一些命令,则这里可以看到所执行的命令,包含参数,但是不包括Redis反馈的执行结果。

 

1499848978.376966 [0 192.168.197.101:42265] "AUTH" "123456"

1499848978.377772 [0 192.168.197.101:42265] "COMMAND"

1499848991.031939 [0 192.168.197.101:42266] "AUTH" "123456"

1499849008.065442 [0 192.168.197.101:42266] "ping"

1499849034.680658 [0 192.168.197.101:42266] "echo" "hello"

1499849323.293098 [0 192.168.197.101:42267] "set" "host" "redis.coe2coe.me"

 

1. 内存组成

上图中的内存统计的是Redis的info memory命令中的used_memory属性,例如:

redisinfomemory#Memoryused_memory:9195978072used_memory_human:8.56Gused_memory_rss:9358786560used_memory_peak:10190212744used_memory_peak_human:9.49Gused_memory_lua:38912mem_fragmentation_ratio:1.02mem_allocator:jemalloc-3.6.0 

每个属性的详细说明

属性名

属性说明

used_memory Redis 分配器分配的内存量,也就是实际存储数据的内存总量 used_memory_human 以可读格式返回 Redis 使用的内存总量 used_memory_rss 从操作系统的角度,Redis进程占用的总物理内存 used_memory_peak 内存分配器分配的最大内存,代表used_memory的历史峰值 used_memory_peak_human 以可读的格式显示内存消耗峰值 used_memory_lua Lua引擎所消耗的内存 mem_fragmentation_ratio used_memory_rss /used_memory比值,表示内存碎片率 mem_allocator Redis 所使用的内存分配器。默认: jemalloc

计算公式如下:

used_memory = 自身内存+对象内存+缓冲内存+lua内存used_rss = used_memory + 内存碎片

如下图所示:

2. 内存分析

(1) 自身内存:一个空的Redis占用很小,可以忽略不计

(2) kv内存:key对象 + value对象

(3) 缓冲区:客户端缓冲区(普通 + slave伪装 + pubsub)以及aof缓冲区(比较固定,一般没问题)

(4) Lua:Lua引擎所消耗的内存

3. 内存突增常见问题

(1) kv内存:bigkey、大量写入

(2) 客户端缓冲区:一般常见的有普通客户端缓冲区(例如monitor命令)或者pubsub客户端缓冲区

三、问题排查

(1) bigkey 经扫描未发现bigkey

Sampled 67234427 keys in the keyspace!Total key length in bytes is 1574032382 (avg len 23.41)Biggest string found 'CCARD_DEVICE_CARD_REF_MAP_KEY_016817000004209' has 20862 bytesBiggest list found 'CCARD_VALID_DEVICE_TRAIN_QUEUE_KEY' has 51 itemsBiggest hash found 'CCARD_VALID_DEVICE_TRAIN_MAP_KEY' has 51 fields67234359 strings with 71767890 bytes (100.00% of keys, avg size 1.07)67 lists with 151 items (00.00% of keys, avg size 2.25)0 sets with 0 members (00.00% of keys, avg size 0.00)1 hashs with 51 fields (00.00% of keys, avg size 51.00)0 zsets with 0 members (00.00% of keys, avg size 0.00)

(2) 键值个数增加?未发现键值有明显变化

本文由澳门皇冠金沙网站发布于办公软件,转载请注明出处:一次关于Redis内存诡异增长的排查过程实战记录

关键词: