Redis内存调优

一、保存内存信息

使用redis-cli -a iesapp info memory > memory.txt将内存信息保存到文件

二、内存信息含义:

# Memory

used_memory:8589737336 Redis 分配器分配的内存总量,包含了redis进程内部的开销和数据占用的内存,以字节(byte)为单位

used_memory_human:8.00G 以更直观的单位展示分配的内存总量

used_memory_rss:13926313984 向操作系统申请的内存大小。与 top ps等命令的输出一致。在理想情况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿。当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。

used_memory_rss_human:12.97G 更直观的单位展示向操作系统申请的内存大小

used_memory_peak:8590052144 redis的内存消耗峰值(以字节为单位)

used_memory_peak_human:8.00G 以更直观的格式返回redis的内存消耗峰值

used_memory_peak_perc:100.00% 使用内存达到峰值内存的百分比,即(used_memory/ used_memory_peak) *100%

used_memory_overhead:8533733870 Redis为了维护数据集的内部机制所需的内存开销,包括所有客户端输出缓冲区、查询缓冲区、AOF重写缓冲区和主从复制的backlog

used_memory_startup:791952 Redis服务器启动时消耗的内存

used_memory_dataset:56003466 数据占用的内存大小,即used_memory-used_memory_overhead

used_memory_dataset_perc:0.65% 数据占用的内存大小的百分比,100%*(used_memory_dataset/(used_memory-used_memory_startup))

allocator_allocated:8589767360

allocator_active:10937163776

allocator_resident:11065339904

total_system_memory:135053119488操作系统内存

total_system_memory_human:125.78G以更直观的格式显示操作系统内存

used_memory_lua:37888 Lua脚本存储占用的内存

used_memory_lua_human:37.00K以更直观的格式显示Lua脚本存储占用的内存

used_memory_scripts:0 Lua脚本使用的字节数

used_memory_scripts_human:0B

number_of_cached_scripts:0

maxmemory:8589934592 Redis实例的最大内存配置

maxmemory_human:8.00G以更直观的格式显示Redis实例的最大内存配置

maxmemory_policy:allkeys-lfu当达到maxmemory时的淘汰策略

allocator_frag_ratio:1.27

allocator_frag_bytes:2347396416

allocator_rss_ratio:1.01

allocator_rss_bytes:128176128

rss_overhead_ratio:1.26

rss_overhead_bytes:2860974080

mem_fragmentation_ratio:1.62碎片率,used_memory_rss/ used_memory,正常情况下稍大于1低于1Redis实例可能会把部分数据交换到硬盘上,内存交换会严重影响Redis的性能,所以应该增加可用物理内存。大于1.5表示碎片过多。额外碎片的产生是由于Redis释放了内存块,但内存分配器并没有返回内存给操作系统,这个内存分配器是在编译时指定的,可以是libcjemalloc或者tcmalloc

mem_fragmentation_bytes:5336639544

mem_not_counted_for_evict:0

mem_replication_backlog:0

mem_clients_slaves:0

mem_clients_normal:8531269918

mem_aof_buffer:0

mem_allocator:jemalloc-5.1.0内存分配器,Redis支持glibc’s mallocjemalloc11tcmalloc几种不同的内存分配器,每个分配器在内存分配和碎片上都有不同的实现。不建议普通管理员修改Redis默认内存分配器,因为这需要完全理解这几种内存分配器的差异,也要重新编译Redis

active_defrag_running:0表示没有活动的defrag任务正在运行,1表示有活动的defrag任务正在运行(defrag:表示内存碎片整理)

lazyfree_pending_objects:0 0表示不存在延迟释放的挂起对象

 

三、内存碎片整理

redis4.0以上可以使用新增指令来手动回收内存碎片。

获取是否开启自动内存碎片整理config get activedefrag

开启自动内存碎片整理 config set activedefrag yes

手动清理内存碎片 memory purge

配置文件如下:

# Enabled active defragmentation

# 碎片整理总开关

# activedefrag yes

 

# Minimum amount of fragmentation waste to start active defrag

# 内存碎片达到多少的时候开启整理

active-defrag-ignore-bytes 100mb

 

# Minimum percentage of fragmentation to start active defrag

# 碎片率达到百分之多少开启整理

active-defrag-threshold-lower 10

 

# Maximum percentage of fragmentation at which we use maximum effort

# 碎片率小余多少百分比开启整理

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

 

四、客户端缓冲区

通过client list查看所有连接的客户端

可以看到172.20.3.3的omem=8559066736,前面说过used_memory_overhead是Redis为了维护数据集的内部机制所需的内存开销,包括所有客户端输出缓冲区、查询缓冲区、AOF重写缓冲区和主从复制的backlog。猜测这里应该是该客户端的输出缓冲区了,这样就和redis内存占用如此大对上了。

 

Redis的输出缓冲区用于保存执行客户端请求命令返回的结果或返回值。每个客户端都有两个输出缓冲区,一个输出缓冲区的大小是固定的,另一个输出缓冲区的大小是可变的。

之前在程序中写redis的时候,为了提高效率,写入之后并没有获取reply,导致redis的输出缓冲区一直没有清。

最后的处理方案是,由于是循环往redis中写大量数据,不需要判断是否写入成功,所以在写入后只读取一部分reply,每隔一小时重新连接redis,重连时就会将输出缓冲区占用的内存释放掉。如果是阻塞方式连接的,会导致在getreply中等待直到有reply返回,每小时重连避免了写入个数计算不正确,导致的getreply阻塞。

 

参考:

https://www.cnblogs.com/undefined22/p/12580818.html

猜你喜欢

转载自blog.csdn.net/yuan1164345228/article/details/106751586