作者:任仲禹

爱可生 DBA 团队成员,善于故障剖析和性能优化,文章相干技术问题,欢送大家一起探讨。

本文起源:原创投稿

*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


背景

问题产生背景为某生产 Redis 集群(版本 Redis 5.0.10 ,架构为 30 片以上),该集群中某一个分片内存使用率异样高(内存占用达70%以上,其它片内存绝对应用较低),咱们模仿生产环境如下监控图所示:

置信看文章题目大家都已晓得问题论断,我这里想跟大家分享的是排查这种问题的办法。

诊断

内存应用散布监控

  • 查看内存应用散布发现,该异样分片实例内存 Redis 应用为356M左右,单个 redis 最大可用内存512M
  • 其它失常分片 redis 内存应用为100M 以内

异样与失常实例内存应用比照

  • 观测到异样实例的数据量(info keyspace)绝对还少一点
  • 但异样实例 数据对象占用内存为其它失常实例2倍
### 失常实例redis-cli -p 6380 -h 10.186.62.28 info keyspace ##数据量# Keyspacedb0:keys=637147,expires=0,avg_ttl=0redis-cli -p 6380 -h 10.186.62.28 info memory |grep -w used_memory ##内存应用used_memory:104917416### 异样实例redis-cli -p 6382 -h 10.186.62.5 info keyspace ##数据量# Keyspacedb0:keys=191433,expires=0,avg_ttl=0redis-cli -p 6382 -h 10.186.62.56 info memory |grep -w used_memory ## 内存应用used_memory:373672656

碎片率应用状况

  • 异样实例内存碎片失常,排除碎片过多状况
redis-cli -p 6382 -h 10.186.62.56 info memory |grep mem_fragmentation_ratiomem_fragmentation_ratio:0.89  ## 碎片率小于1

Bigkeys 扫描剖析

  • 后面剖析未果,尝试通过 bigkeys 剖析扫描(为防止影响业务操作,倡议业务低峰进行)
  • 扫描后果如下(截取要害局部)
# redis-cli -p 6382 -h 10.186.62.56  --bigkeys# 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 string found so far '"key:{06S}:000061157249"' with 3 bytes[00.03%] Biggest string found so far '"key3691"' with 4 bytes[40.93%] Biggest string found so far '"bigkkkkk:0"' with 102400000 bytes[51.33%] Biggest string found so far '"bigk:0"' with 204800000 bytes-------- summary -------Sampled 191433 keys in the keyspace!Total key length in bytes is 4161149 (avg len 21.74)Biggest string found '"bigk:0"' has 204800000 bytes0 lists with 0 items (00.00% of keys, avg size 0.00)0 hashs with 0 fields (00.00% of keys, avg size 0.00)191433 strings with 307777256 bytes (100.00% of keys, avg size 1607.75)0 streams with 0 entries (00.00% of keys, avg size 0.00)0 sets with 0 members (00.00% of keys, avg size 0.00)0 zsets with 0 members (00.00% of keys, avg size 0.00)
  • 其中获悉后果如下

    • 存在2个异样key

      • 如最大的 key为“bigk:0”,占用 200M 左右
      • 大键"bigkkkkk:0",占用 100M 左右
    • 其余string key绝对较小,均匀占用10 字节以内,如 'key:xx' 等
  • 留神,本文因为是本人模仿的测试环境绝对简略,本质生产环境略微简单点,可能有不同类型的如 hash、set 类型的键,这些键通过 --bigkeys 剖析工具后无奈失去内存占用大小,而只能晓得元素/成员个数,所以还须要通过其余命令取得内存占用大小:

    • 对异样key进行内存剖析,后果如下,2个异样key占用空间约 300M 左右,跟监控中内存异样占用高景象吻合
    10.186.62.56:6382> memory usage bigkkkkk:0    (integer) 117440568    10.186.62.56:6382>    10.186.62.56:6382> memory usage bigk:0    (integer) 234881072

论断

  • 通过上述剖析流程,咱们晓得当发现 Redis Cluster 集群中内存散布不均时,剖析 bigkeys 不失为一种疾速无效的排查办法,然而须要留神在低峰期执行

    • redis-cli -p {port} -h {host} --bigkeys
  • BTW,如果大家须要模仿 Redis 的大键、大量数据、或阻塞能够通过一些好用的 debug / mem命令
# 制作 10 条以 renzy:id: 为前缀,大小为 1024 字节的 key127.0.0.1:9999> debug populate 10 renzy:id: 1024OK127.0.0.1:9999> keys renzy:id* 1) "renzy:id::8" 2) "renzy:id::2" 3) "renzy:id::4"·····## 制作阻塞127.0.0.1:9999> debug sleep 2 //阻塞 2 秒OK或# redis-cli -p 9999 keys \* > /dev/null //(如果数据量大的话间接 keys *即可)