目录

Redis 内存过高

查找bigkey

redis-cli --bigkeys

统计每种数据类型的键值对个数以及平均大小。此外,这个命令执行后,会输出每种数据类型中最大的 bigkey 的信息,对于 String 类型来说,会输出最大 bigkey 的字节长度,对于集合类型来说,会输出最大 bigkey 的元素个数。

内存使用情况

MEMORY STATS命令

在Redis命令行中,执行MEMORY STATS命令查询内存使用详情。 Redis实例的内存开销主要由两部分组成: 业务数据的内存开销,该部分一般作为重点分析对象。 非业务数据的内存开销,例如主备复制的积压缓冲区、Redis进程初始化消耗的内存等。 返回示例及各参数对应的解释如下:

 1) "peak.allocated" //Redis进程自启动以来消耗内存的峰值。
 2) (integer) 79492312
 3) "total.allocated" //Redis使用其分配器分配的总字节数,即当前的总内存使用量。
 4) (integer) 79307776
 5) "startup.allocated" //Redis启动时消耗的初始内存量。
 6) (integer) 45582592
 7) "replication.backlog" //复制积压缓冲区的大小。
 8) (integer) 33554432
 9) "clients.slaves" //主从复制中所有从节点的读写缓冲区大小。
10) (integer) 17266
11) "clients.normal" //除从节点外,所有其他客户端的读写缓冲区大小。
12) (integer) 119102
13) "aof.buffer" //AOF持久化使用的缓存和AOF重写时产生的缓存。
14) (integer) 0
15) "db.0"  //业务数据库的数量。
16) 1) "overhead.hashtable.main" //当前数据库的hash链表开销内存总和,即元数据内存。
    2) (integer) 144
    3) "overhead.hashtable.expires" //用于存储key的过期时间所消耗的内存。
    4) (integer) 0
17) "overhead.total" //数值=startup.allocated+replication.backlog+clients.slaves+clients.normal+aof.buffer+db.X。
18) (integer) 79273616
19) "keys.count" //当前Redis实例的key总数
20) (integer) 2
21) "keys.bytes-per-key" //当前Redis实例每个key的平均大小,计算公式:(total.allocated-startup.allocated)/keys.count。
22) (integer) 16862592
23) "dataset.bytes" //纯业务数据占用的内存大小。
24) (integer) 34160
25) "dataset.percentage" //纯业务数据占用的内存比例,计算公式:dataset.bytes*100/(total.allocated-startup.allocated)26) "0.1012892946600914"
27) "peak.percentage" //当前总内存与历史峰值的比例,计算公式:total.allocated*100/peak.allocated。
28) "99.767860412597656"
29) "fragmentation" //内存的碎片率。
30) "0.45836541056632996"

MEMORY USAGE命令

在Redis命令行中,执行MEMORY USAGE命令查询指定Key消耗的内存(单位为字节)。 命令执行示例:

MEMORY USAGE Key0089393003
(integer) 1000072

MEMORY DOCTOR命令

在Redis命令行中,执行MEMORY DOCTOR命令获取内存诊断建议。

内存碎片查看

INFO memory
"# Memory
used_memory:3986048
used_memory_human:3.80M
used_memory_rss:14991360
used_memory_rss_human:14.30M
used_memory_peak:4330880
used_memory_lua:36864
mem_fragmentation_ratio:3.80
mem_allocator:jemalloc-3.6.0

内存碎片清理

那要如何清除内存碎片呢?

处理内存碎片是Redis调优的一种方法之一。

解决方法一: 重启Redis 没有什么问题是重启无法解决的,yyds!

但,在生产环境不能这么玩啊,如果Redis恰好没有持久化,这会导致数据丢失的,即使持久化了,万一数据量大,重启恢复时间长,期间不可用对业务影响也大。

执行 memory purge 命令 手动暴力整理内存碎片,会阻塞主进程,生产环境慎用。

解决方法二: Redis 4.0-RC3版本之后,Redis提供了一种自动清理内存碎片的参数activedefrag

开启自动内存碎片整理(总开关)

activedefrag yes 只需要设置开启即可:

127.0.0.1:6379> config get activedefrag
1) "activedefrag"
2) "no"
127.0.0.1:6379> config set activedefrag yes
OK

Redis开启了自动清理内存碎片参数,那要达到什么条件才会清理呢?

Redis提供了一下触发机制,下面4个参数都是满足任意一条件后就可以进行清理:

active-defrag-ignore-bytes 100mb 默认值,碎片达到100MB时,开启清理。 active-defrag-threshold-lower 10 默认值,当碎片超过 10% 时,开启清理。 active-defrag-threshold-upper 100 默认值,内存碎片超过 100%,则尽最大努力整理。 只需要进入redis客户端或者在conf配置文件设置即可