背景
今天接到一个报警,redis cluster的某个分片节点内存使用85%了。照这样下去
估计周末就要被打爆。
排查过程
1.首先查看监控,确实其他节点都很正常,
但是这个节点使用很高。监控如下:
2.由于这个节点之前已经因为内存使用过高,之前同事已经迁移过了一次,
所以这次再发生,觉得问题不是简单搬迁slot就可以的,于是进一步排查。
首先考虑的是不是大key的问题。
经过大key分析,确实存在大key,大key分析如下:
分析大key的时候要注意系统的CPU使用率,因为SCAN会耗费大量CPU
#命令如下:
$ redis-cli -h ip --bigkeys
#然后开始扫描key
# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type. You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).
[00.00%] Biggest zset found so far 'feeds' with 200 members
[00.00%] Biggest hash found so far 'ursor.14620821' with 2 fields
........#此处省略中间过程
[79.66%] Sampled 5000000 keys so far
[80.55%] Biggest set found so far 'device' with 11 members
[95.59%] Sampled 6000000 keys so far
-------- summary -------
#可以看到总共扫描了600多w的key
Sampled 6276594 keys in the keyspace!
Total key length in bytes is 184805760 (avg len 29.44)
#然后会分析出几种类型分别存在的大key
Biggest list found 'followed_queue' has 2360286598 items
Biggest hash found 'cursor' has 7 fields
Biggest string found 'user' has 62505 bytes
Biggest set found 'device' has 11 members
Biggest zset found 'popular' has 270505 members
1 lists with 2360286598 items (00.00% of keys, avg size 2360286598.00)
2615478 hashs with 2859295 fields (41.67% of keys, avg size 1.09)
139674 strings with 34883495 bytes (02.23% of keys, avg size 249.75)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
3 sets with 15 members (00.00% of keys, avg size 5.00)
分析上面的结果:
看到list
存在一个23亿个值的list,再从名字可以看到是一个队列,
再去看一下这个key的大小:
IP:6379> memory usage followed_queue
(integer) 42563779299
#这里单位字节
42563779299/1024/1024/1024=40G
通过查看,这个redis节点的最大内存是60G,但这个Key就占用到了40GB,
足足的大key了
确定好大key,接下来就是解决方案了:
一般list当作队列就是生产者消费者
的用法:
所以当时我们的解决方案就是:
1:提高消费者的速度,使key的Value减少
2:key是否还在使用,不使用清理掉
3.经过和开发沟通,运气比较好,这个功能刚好迁移到了新的逻辑,也就是这个key不用了。
那我们只要删除这个key就好了。
注意
不要直接del
大key,可以使用ltrim
慢慢进行删除,还要注意系统的负载。
结果
可以看到最后删除完直接从85%使用降到18%,非常明显
至此解决完毕。