随着业务的发展, Redis集群内存使用量暴涨, 即使删除了部分数据, 内存占用量依然没有明显下降.
带着这个问题, 我们一起看下如何分析Redis的使用情况.
1. 内存情况查看
1.1
Redis 内存查看
Redis可以使用 info命令查看节点内存信息占用情况.
127.0.0.1:6379> info memory
# Memory# Redis 保存数据申请的内存空间
used_memory:848136
used_memory_human:828.26K
# 操作系统分配给 Redis 进程的内存空间
used_memory_rss:2449408
used_memory_rss_human:2.34M
# Redis 进程在运行过程中占用的内存峰值
used_memory_peak:910608
used_memory_peak_human:889.27K
# 使用内存达到峰值内存的百分比, 即(used_memory/ used_memory_peak) *100%
used_memory_peak_perc:93.14%
# Redis为了维护数据集的内部机制所需的内存开销, 包括所有客户端输出缓冲区, 查询缓冲区, AOF重写缓
used_memory_overhead:836278
# Redis服务器启动时消耗的内存
used_memory_startup:786488
# 数据占用的内存大小, 即used_memory - used_memory_overhead
used_memory_dataset:11858
# 数据占用的内存大小的百分比# 100%*(used_memory_dataset/(used_memory-used_memory_startup))
used_memory_dataset_perc:19.24%
# 系统内存
total_system_memory:2095968256
total_system_memory_human:1.95G
# Lua脚本存储占用的内存used_memory_lua:37888
used_memory_lua_human:37.00K
# Redis实例的最大内存配置maxmemory:0
maxmemory_human:0B
# 淘汰策略
maxmemory_policy:noeviction
# 内存的碎片率, used_memory_rss/used_memory
mem_fragmentation_ratio:2.89
# 内存分配器
mem_allocator:jemalloc-4.0.3
# 表示没有活动的defrag任务正在运行, 1表示有活动的defrag任务正在运行(defrag:表示内存碎片整理)
active_defrag_running:0
# 表示redis执行lazy free操作,在等待被实际回收内容的键个数
lazyfree_pending_objects:0
1.2
内存碎片
通过上述命令可以发现, Redis的内存实际使用量和申请空间是不相同的, 这也就是内存碎片.
Redis内存碎片率(mem_fragmentation_ratio)
计算公式:
mem_fragmentation_ratio = used_memory_rss / used_memory
ratio值>1 表示有内存碎片, 越大表明越多;
ratio值<1 表示正在使用虚拟内存, 虚拟内存其实就是硬盘, 性能比使用内存低很多, 最好增加内存提高性能;
一般来说, ratio值在1 - 1.5之间是比较健康的;
2. 碎片整理
2.1
碎片整理
了解了当前Redis内存情况之后, 就是内存的碎片整理了.
Redis中提供了碎片调整参数, 根据自己集群节点的情况调整.
可以在redis.conf中配置, 也可以使用 CONFIG SET 命令进行设置.
#Enabled active defragmentation
#碎片整理总开关
#activedefrag yes
#Minimum amount of fragmentation waste to start active defrag
#当碎片达到 100mb 时, 开启内存碎片整理
active-defrag-ignore-bytes 100mb
#Minimum percentage of fragmentation to start active defrag
#当碎片超过 10% 时, 开启内存碎片整理
active-defrag-threshold-lower 10
#Maximum percentage of fragmentation at which we use maximum effort
#内存碎片超过 100%, 则尽最大努力整理
active-defrag-threshold-upper 100
#Minimal effort for defrag in CPU percentage
#内存自动整理占用资源最小百分比
active-defrag-cycle-min 25
#Maximal effort for defrag in CPU percentage
#内存自动整理占用资源最大百分比
active-defrag-cycle-max 75
active-defrag-ignore-bytes, active-defrag-threshold-lower 控制是否进行内存碎片整理;
这两个参数同时满足时, 进入内存碎片整理逻辑, 碎片整理过程中,会对集群有一定的影响, 需要将值调整到一个合理的值.
active-defrag-cycle-min, active-defrag-cycle-max 控制整理内存碎片的力度;
占用主线程资源比率的上下限, 当资源占用越多时, 内存碎片整理力度越大; 时间越短, 对性能的影响也更大.
内存回收会使Redis集群的响应变慢, 因为内存碎片整理是在主线程中执行的, 通过源码发现, 内存碎片整理操作会scan迭代整个 redis 节点, 并进行内存复制, 转移等操作.
3. 内存处理命令
3.1
MEMORY命令
在4.0版本之后提供了memory命令, 可以更方便的查看内存状态并给出一定的建议.
127.0.0.1:6379> MEMORY help
1) "MEMORY DOCTOR - Outputs memory problems report"
2) "MEMORY USAGE <key> [SAMPLES <count>] - Estimate memory usage of key"
3) "MEMORY STATS - Show memory usage details"
4) "MEMORY PURGE - Ask the allocator to release memory"
5) "MEMORY MALLOC-STATS - Show allocator internal stats"
3.2
MEMORY DOCTOR
Redis内存使用方面的建议
127.0.0.1:6379> MEMORY DOCTOR
Hi Sam, this instance is empty or is using very little memory,
my issues detector can't be used in these conditions.
Please, leave for your mission on Earth and fill it with some data.
The new Sam and I will be back to our programming as soon as I finished rebooting.
3.3
MEMORY USAGE
查看指定key内存占用量.
127.0.0.1:6379> keys *
1) "key"
2) "\xac\xed\x00\x05t\x00\x04kset"
127.0.0.1:6379> MEMORY USAGE key
(integer) 57
3.4
MEMORY STATS
查看内存使用详情, 和info memory命令结果是一样的.
127.0.0.1:6379> MEMORY STATS
1) "peak.allocated"
2) (integer) 910608
3) "total.allocated"
4) (integer) 848136
5) "startup.allocated"
6) (integer) 786488
7) "replication.backlog"
8) (integer) 0
9) "clients.slaves"
10) (integer) 0
11) "clients.normal"
12) (integer) 49638
13) "aof.buffer"
14) (integer) 0
15) "db.0"
16) 1) "overhead.hashtable.main"
2) (integer) 152
3) "overhead.hashtable.expires"
4) (integer) 0
17) "overhead.total"
18) (integer) 836278
19) "keys.count"
20) (integer) 3
21) "keys.bytes-per-key"
22) (integer) 20549
23) "dataset.bytes"
24) (integer) 11858
25) "dataset.percentage"
26) "19.235012054443359"
27) "peak.percentage"
28) "93.1395263671875"
29) "fragmentation"
30) "2.8875539302825928"
info memory命令结果
127.0.0.1:6379> info memory
# Memory
used_memory:848136
used_memory_human:828.26K
used_memory_rss:2449408
used_memory_rss_human:2.34M
used_memory_peak:910608
used_memory_peak_human:889.27K
used_memory_peak_perc:93.14%
used_memory_overhead:836278
used_memory_startup:786488
used_memory_dataset:11858
used_memory_dataset_perc:19.24%
total_system_memory:2095968256
total_system_memory_human:1.95G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:2.89
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0
127.0.0.1:6379>
3.5
MEMORY PURGE
请求分配器释放内存,同样只对jemalloc生效.
127.0.0.1:6379> memory purge
OK
3.6
MEMORY MALLOC-STATS
打印内存分配器状态,只在使用jemalloc时有用.
127.0.0.1:6379> MEMORY MALLOC-STATS
___ Begin jemalloc statistics ___
Version: 4.0.3-0-ge9192eacf8935e29fc62fddc2701f7942b1cc02c
Assertions disabled
Run-time option settings:
opt.abort: false
opt.lg_chunk: 21
opt.dss: "secondary"
opt.narenas: 16
opt.lg_dirty_mult: 3 (arenas.lg_dirty_mult: 3)
opt.stats_print: false
opt.junk: "false"
opt.quarantine: 0
opt.redzone: false
opt.zero: false
opt.tcache: true
opt.lg_tcache_max: 15
CPUs: 4
Arenas: 16
Pointer size: 8
Quantum size: 8
Page size: 4096
Min active:dirty page ratio per arena: 8:1
Maximum thread-cached size class: 32768
Chunk size: 2097152 (2^21)
Allocated: 1102328, active: 1335296, metadata: 1330432, resident: 2543616, mapped: 4194304
Current active ceiling: 2097152
arenas[0]:
assigned threads: 1
dss allocation precedence: secondary
min active:dirty page ratio: 8:1
dirty pages: 326:17 active:dirty, 1 sweep, 4 madvises, 8 purged
allocated nmalloc ndalloc nrequests
small: 369144 12921 1139 1500998
large: 733184 114 105 137
huge: 0 0 0 0
total: 1102328 13035 1244 1501135
active: 1335296
mapped: 2097152
metadata: mapped: 53248, allocated: 192512
bins: size ind allocated nmalloc ndalloc nrequests curregs curruns regs pgs util nfills nflushes newruns reruns
8 0 1936 322 80 797 242 1 512 1 0.472 14 11 1 0
16 1 165152 10415 93 10701 10322 41 256 1 0.983 108 9 41 0
24 2 16248 712 35 1283 677 2 512 3 0.661 164 10 2 0
32 3 384 119 107 248 12 1 128 1 0.093 13 11 1 0
40 4 560 106 92 9 14 1 512 5 0.027 2 4 1 0
48 5 1584 130 97 1487532 33 1 256 3 0.128 21 11 1 0
56 6 1120 106 86 14 20 1 512 7 0.039 2 4 1 0
64 7 1216 80 61 30 19 1 64 1 0.296 3 3 1 0
80 8 3120 136 97 40 39 1 256 5 0.152 7 4 1 0
96 9 12672 208 76 193 132 2 128 3 0.515 45 11 3 1
112 10 6048 154 100 49 54 1 256 7 0.210 10 4 2 0
128 11 4736 69 32 36 37 2 32 1 0.578 10 3 3 0
160 12 16000 100 0 0 100 1 128 5 0.781 1 0 1 0
---
256 15 0 16 16 4 0 0 16 1 1 1 3 1 0
320 16 7680 72 48 16 24 1 64 5 0.375 2 3 1 0
384 17 384 32 31 1 1 1 32 3 0.031 1 3 1 0
---
512 19 512 10 9 4 1 1 8 1 0.125 1 2 2 0
640 20 0 32 32 1 0 0 32 5 1 1 3 1 0
---
896 22 16128 49 31 18 18 1 32 7 0.562 1 3 1 0
1024 23 2048 10 8 3 2 1 4 1 0.500 1 2 3 0
1280 24 20480 16 0 0 16 1 16 5 1 1 0 1 0
---
2048 27 4096 10 8 2 2 1 2 1 1 1 2 5 0
---
5120 32 87040 17 0 17 17 5 4 5 0.850 0 0 5 0
---
large: size ind allocated nmalloc ndalloc nrequests curruns
16384 39 0 1 1 1 0
20480 40 61440 11 8 34 3
---
32768 43 32768 1 0 1 1
40960 44 40960 97 96 97 1
---
57344 46 57344 1 0 1 1
---
81920 48 81920 1 0 1 1
---
131072 51 131072 1 0 1 1
---
327680 56 327680 1 0 1 1
---
huge: size ind allocated nmalloc ndalloc nrequests curhchunks
---
--- End jemalloc statistics ---
127.0.0.1:6379>
小结
以上就是Redis经常用来处理内存相关的命令.