redis内存碎片率很低——上篇
一、起因
今天有业务找过来说,说自己就存了几十个string类型的数据,为什么集群上节点的内存使用率就占到了200多M。224MB
按照redis的string类型数据的内存占用来计算的话,怎么都算不到这么多呀,但查看监控之后发现还真是这样。
之后查看 info memory 如下(redis-4.0.12):
10.142.38.35:33423
# Memory
used_memory:236490880
used_memory_human:225.54M
used_memory_rss:3207168
used_memory_rss_human:3.06M
used_memory_peak:236491904
used_memory_peak_human:225.54M
used_memory_peak_perc:100.00%
used_memory_overhead:236408208
used_memory_startup:1458456
used_memory_dataset:82672
used_memory_dataset_perc:0.04%
total_system_memory:270763003904
total_system_memory_human:252.17G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:2147483648
maxmemory_human:2.00G
maxmemory_policy:noeviction
mem_fragmentation_ratio:0.01
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0
刚开始以为是系统内存错误或者显示错误,就重启了一下从库,发现问题仍然存在,而且这个内存碎片率还更低了!!!
二、分析
2.1 自己分析
used_memory_human:225.54M
used_memory_rss_human:3.06M
mem_fragmentation_ratio:0.01
used_memory表示redis分配器分配的容量,used_memory_rss 表示从操作系统看,redis进程占用的容量,mem_fragmentation_ratio = used_memory_rss / used_memory,表示内存碎片率
一般情况下used_memory_rss 比used_memory 大一些,也就是mem_fragmentation_ratio比1大一些
又看了两个 # Keyspace 为空的redis-4.0.12版本的redis集群节点:
10.142.94.35:34424(第二个集群的节点)
# Memory
used_memory:236566592
used_memory_human:225.61M
used_memory_rss:5611520
used_memory_rss_human:5.35M
maxmemory_policy:allkeys-lru
mem_fragmentation_ratio:0.02
mem_allocator:jemalloc-4.0.3
10.114.33.8:34381 (第三个集群的节点)
# Memory
used_memory:1575224
used_memory_human:1.50M
used_memory_rss:6922240
used_memory_rss_human:6.60M
maxmemory_policy:allkeys-lru
mem_fragmentation_ratio:4.39
mem_allocator:jemalloc-4.0.3
现在更迷了,,,,
初步怀疑是redis进程运行时存的其他的一些数据,让业务试试多刷一些数据进去,这些200M的数据占比应该会随着实际存储数据的增大而减少,可能这个问题就不足为奇了。
2.2 搜索资料
再次百度查看这个信息的含义:
used_memory是Redis使用的内存总量,它包含了实际缓存占用的内存和Redis自身运行所占用的内存(如元数据、lua)。它是由Redis使用内存分配器分配的内存,所以这个数据并没有把内存碎片浪费掉的内存给统计进去。
used_memory_rss的rss是Resident Set Size的缩写,表示该进程所占物理内存的大小,是操作系统分配给Redis实例的内存大小。除了用户定义的数据和内部开销以外,used_memory_rss指标还包含了内存碎片的开销,内存碎片是由操作系统低效的分配/回收物理内存导致的。
若是内存碎片率低于1的话,说明Redis内存分配超出了物理内存,操作系统正在进行内存交换。内存交换会引起非常明显的响应延迟。
根据上述定义来说的话,这个 used_memory_rss 应该就是包含 used_memory 的呀,所以这个 used_memory_rss 应该始终比 used_memory 大才对呀。但是为什么我们使用 info memory 看到的信息却是 used_memory 比 used_memory_rss 大200多M(集群一和集群二)??
百度无果之后决定上机器一探究竟…
2.3 分析进程占用
登录运行redis实例的机器,使用
top -c查看
13734 work 20 0 366m 15m 1100 S 0.0 0.0 156:30.36 /home/work/redis/redis-4.0.12/bin/redis-server *:33420 [cluster]
进程为13734
使用pmap分析内存
pmap 使用:https://blog.csdn.net/sunny05296/article/details/65975710
[work@redis05 ~]$ pmap -x 13734
13734: /home/work/redis/redis-4.0.12/bin/redis-server *:33420 [cluster]
Address Kbytes RSS Dirty Mode Mapping
0000000000400000 1280 452 0 r-x-- redis-server
000000000073f000 24 24 24 rw--- redis-server
0000000000745000 92 88 88 rw--- [ anon ]
000000000080a000 132 56 56 rw--- [ anon ]
0000003926a00000 128 40 0 r-x-- ld-2.12.so
0000003926c1f000 4 4 4 r---- ld-2.12.so
0000003926c20000 4 4 4 rw--- ld-2.12.so
0000003926c21000


2321

被折叠的 条评论
为什么被折叠?



