共计 2896 个字符,预计需要花费 8 分钟才能阅读完成。
Redis内存碎片是指Redis中已被回收但仍然处于一块连续的内存区域内的未使用内存空间,这些内存空间无法被重用,而且随着Redis服务的长时间运行,这种现象会逐渐加剧,最终导致Redis内存使用效率下降,甚至会导致Redis进程因为内存不足而奔溃
Redis内存碎片的出现是因为Redis采用的内存分配策略,它在释放一块内存空间时,只能将其标记为已释放,而不能真正释放该内存空间。这种内存分配策略可以提高Redis的内存分配速度,但是它也带来了内存碎片的问题。
为了解决Redis内存碎片问题,可以使用以下方法:
- 定期重启Redis服务:重启Redis服务可以释放Redis内存碎片,但这种方法会导致Redis服务停止服务,因此需要在业务低峰期进行。
- 优化Redis的内存分配策略:可以通过修改Redis的内存分配策略,将内存分配和释放策略改为jemalloc等内存分配库。
- 开启内存碎片检查功能:Redis4.0开始支持内存碎片检查功能,可以通过配置参数开启该功能,当内存碎片超过一定比例时,Redis会自动进行内存碎片整理。
Redis内存分配策略有以下几种:
- jemalloc:Redis默认的内存分配器,通常情况下表现良好,支持多线程和并发,可以防止内存碎片。
- tcmalloc:一款由Google开发的内存分配器,与jemalloc类似,但在某些场景下可能表现更优秀。
- libc:基于操作系统提供的内存分配函数实现,性能一般,容易导致内存碎片。
查看内存使用情况
127.0.0.1:6379> info memory
# Memory
used_memory:8228560
used_memory_human:7.85M
used_memory_rss:19435520
used_memory_rss_human:18.54M
used_memory_peak:8447592
used_memory_peak_human:8.06M
used_memory_peak_perc:97.41%
used_memory_overhead:1017318
used_memory_startup:791424
used_memory_dataset:7211242
used_memory_dataset_perc:96.96%
allocator_allocated:8622512
allocator_active:9297920
allocator_resident:14209024
total_system_memory:3873660928
total_system_memory_human:3.61G
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.08
allocator_frag_bytes:675408
allocator_rss_ratio:1.53
allocator_rss_bytes:4911104
rss_overhead_ratio:1.37
rss_overhead_bytes:5226496
mem_fragmentation_ratio:2.37
mem_fragmentation_bytes:11247984
mem_not_counted_for_evict:0
mem_replication_backlog:0
mem_clients_slaves:0
mem_clients_normal:49694
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
used_memory和used_memory_rss
- used_memory:Redis分配器分配的内存总量 + 虚拟内存(磁盘)
- used_memory_rss:Redis进程占据操作系统的内存 + 进程运行本身需要的内存 + 内存碎片等 (*:注意 used_memory_rss 不包括虚拟内存)
两者区别:
- 面向角度:used_memory: Redis角度 used_memory_rss:操作系统角度
- 大小不一定是后者大于前者:内存碎片和Redis进程运行需要占用内存,使得前者可能比后者小,另一方面虚拟内存的存在,使得前者可能比后者大
mem_fragmentation_ratio
内存碎片比率, 等于 used_memory_rss / used_memory
- mem_fragmentation_ratio > 1 : 值越大,内存碎片比例越大
- mem_fragmentation_ratio < 1 : 说明Redis使用了虚拟内存,由于虚拟内存的媒介是磁盘,比内存速度要慢很多,当这种情况出现时,应该及时排查,如果内存不足应该及时处理,如增加Redis节点、增加Redis服务器的内存、优化应用等。
正常情况下:mem_fragmentation_ratio = 1.03左右 (健康:对于jemalloc来说),查看博主此时得小破站已经到达2+。。。。
mem_allocator
Redis使用的内存分配器,在编译时指定,可以是 libc 、jemalloc或者tcmalloc,默认是jemalloc
used_memory_peak
Redis的内存消耗峰值
开启内存碎片整理
对于4.0版本后的可以配置参数开启
config set activedefrag yes
碎片清理是有代价的:操作系统需要把多份数据拷贝到新位置,把原有空间释放出来,这会带来时间开销。
Redis 是单线程,在数据拷贝时,Redis 进入阻塞状态,从而导致 Redis 无法及时处理请求,性能就会降低
开启自动清理机制之后,需要同时满足两个条件才可以触发执行:
- active-defrag-ignore-bytes 100mb:表示内存碎片的字节数达到 100MB 时,开始清理。
- active-defrag-threshold-lower 10:表示内存碎片空间占操作系统分配给 Redis 的总空间比例达到 10% 时,开始清理
active-defrag-cycle-min 25
: 表示自动清理过程所用CPU
时间的比例不低于25%
,保证清理能正常开展。active-defrag-cycle-max 75
:表示自动清理过程所用CPU
时间的比例不高于75%
,一旦超过,就停止清理
还有另外一个指令,就是
MEMORY PURGE
Redis 4.0 中引入的一个命令,它可以通过清除 Redis 的内存碎片来回收 Redis 进程中的一些内存。该命令会清除 Redis 中所有的内存碎片。需要注意的是,该命令会占用 Redis 进程大量 CPU 和内存,因此需要在空闲时间或者生产环境的非繁忙时间使用