当前位置: 首页 > news >正文

Redis内存碎片详解

Redis内存碎片详解

1. 什么是内存碎片?

你可以将内存碎片简单地理解为那些不可用的空闲内存。

内存碎片(Memory Fragmentation)是指由于频繁的内存分配和释放,导致可用的内存空间变得不连续,从而影响内存利用率和性能。在 Redis 中,内存碎片通常指的是 Redis 向操作系统申请的内存与实际存储数据的内存之间的差值。

内存碎片的计算方式:
碎片率 = Redis 占用的物理内存 Redis 记录的内存使用量 碎片率 = \frac{\text{Redis 占用的物理内存}}{\text{Redis 记录的内存使用量}} 碎片率=Redis 记录的内存使用量Redis 占用的物理内存
其中:

  • Redis 占用的物理内存:Redis 进程在系统中实际使用的内存(由 info memory 中的 used_memory_rss 统计)。
  • Redis 记录的内存使用量:Redis 逻辑上存储数据所占的内存(由 info memory 中的 used_memory 统计)。
  • 碎片率大于 1.0 表示有内存碎片,碎片率越大,碎片越严重。

2. 为什么会有内存碎片?

Redis 的内存碎片主要来源于以下几个方面:

(1) 内存分配策略

Redis 默认使用 jemalloc 作为内存分配器(可以使用 jemallocglibc malloc),而 jemalloc 通过分配不同大小的内存块来管理内存。当某些键被删除或修改后,会导致内存块无法被完全回收,进而产生碎片。

(2) 数据的增删改
  • 大 key 的删除:当一个大对象(如大型 hashlistset)被删除时,其占用的内存可能不会立刻释放给操作系统,而是继续留在 Redis 进程中,形成碎片。
  • 数据更新:当一个 string 类型的键从 100B 扩展到 10KB,Redis 可能会重新分配新的更大的内存空间,旧的内存块可能无法完全复用,从而导致碎片。
(3) 内存回收机制
  • jemalloc 可能不会将空闲的内存立刻归还给操作系统,而是继续留在 Redis 进程中以备后续使用。
  • 操作系统本身的内存管理也可能导致碎片,例如 glibc malloc 使用 mmap/brk 分配内存,某些情况下释放的内存不会立刻回收。

3. 如何查看 Redis 的内存碎片?

可以通过 info memory 命令查看 Redis 的内存碎片情况,关注以下几个字段:

127.0.0.1:6379> info memory

输出示例:

used_memory:104857600         # Redis 逻辑上使用的内存(100MB)
used_memory_rss:157286400     # Redis 实际占用的物理内存(150MB)
mem_fragmentation_ratio:1.50  # 内存碎片率(1.5)

关键指标:

  • mem_fragmentation_ratio:内存碎片率。
    • < 1.0:可能 Redis 触发了 swap,数据被交换到磁盘,影响性能。
    • ≈ 1.0:内存利用率较好,没有明显的碎片问题。
    • > 1.2:可能有较多的内存碎片,影响性能。
    • > 1.5:内存碎片较严重,可能需要手动清理。

4. 如何清理 Redis 的内存碎片?

如果 mem_fragmentation_ratio 过高(通常 >1.3~1.5),可以采取以下措施来减少内存碎片:

(1) 触发 Redis 主动释放内存

可以通过 MEMORY PURGE(Redis 4.0+)来强制 jemalloc 释放空闲内存:

127.0.0.1:6379> MEMORY PURGE

这会通知 jemalloc 释放未使用的内存给操作系统,可能会减少 used_memory_rss,但不会影响 used_memory

(2) 重启 Redis

如果碎片严重,MEMORY PURGE 无法明显降低 mem_fragmentation_ratio,可以尝试重启 Redis:

$ systemctl restart redis

注意:重启 Redis 会导致数据丢失(如果没有持久化),在生产环境中应先做好备份。

(3) 重新加载数据

如果 Redis 使用 RDBAOF 持久化,可以尝试 SAVE + FLUSHALL + RELOAD

127.0.0.1:6379> SAVE           # 先保存当前数据到 RDB
127.0.0.1:6379> FLUSHALL       # 清空所有数据
127.0.0.1:6379> SYSTEM RELOAD  # 重新加载 RDB 文件

这样 Redis 会重新分配内存,降低碎片率。

(4) 调整 jemalloc 参数

如果 jemalloc 产生过多碎片,可以尝试手动调整参数,修改 Redis 启动命令:

MALLOC_CONF=background_thread:true,dirty_decay_time:300,stats_print:true redis-server

dirty_decay_time 影响 jemalloc 的回收策略,适当调整可能减少碎片。

(5) 控制大 key
  • 避免存储超大 hashlistset,可以拆分存储。
  • 采用 hash tag 方案,使数据分布在多个 key 上,而不是集中在一个 key 里。
(6) 设置 maxmemory-policy

如果 Redis 用于缓存,可以使用 volatile-lruallkeys-lru 策略,使数据更均衡地被淘汰,减少碎片:

127.0.0.1:6379> CONFIG SET maxmemory-policy allkeys-lru

5. 总结

方法适用场景影响
MEMORY PURGE碎片率 1.2~1.5轻量级,减少 RSS
Redis 重启碎片率 > 1.5影响业务,需备份
RDB 重新加载碎片率 > 1.3需启用持久化
jemalloc 参数调整长期优化需测试优化效果
避免大 key结构设计阶段预防性优化
maxmemory-policy缓存场景影响数据淘汰策略

如果 Redis 的 mem_fragmentation_ratio 过高,可以先尝试 MEMORY PURGE,如果无效则考虑重启 Redis 或优化数据结构。

相关文章:

  • 1998-2022年各地级市第三产业占GDP比重/地级市第三产业占比数据(市辖区)
  • 人工智能 - 通用 AI Agent 之 LangManus、Manus、OpenManus 和 OWL 技术选型
  • 大数据平台上的数据建模与分析:从数据到决策的跃迁
  • 【TI MSPM0】Timer学习
  • SOFABoot-02-模块化隔离方案
  • 2025年十大AI工具对比
  • 人工智能将使勒索软件更加危险
  • 实验3 以太坊交易周期的需求分析
  • 浅谈ai工程落地 - 蒸馏 vs 剪枝 vs 量化
  • 2025.3.22总结
  • 安卓7.0以上App抓包
  • 从零到一:如何训练简版生成式GPT模型,快速实现创意写作
  • Sql Server数据迁移易错的地方
  • 《政务信息化标准体系建设指南》核心要点速读
  • Maya基本操作
  • 【数据分享】我国乡镇(街道)行政区划数据(免费获取/Shp格式)
  • doris:FQDN
  • pyspark学习rdd处理数据方法——学习记录
  • 3.22模拟面试
  • kotlin 函数引用
  • 农行一季度净利润719亿元增2.2%,不良率微降至1.28%
  • 石家庄:城市更新,生活向美
  • 发布亮眼一季度报后,东阿阿胶股价跌停:现金流隐忧引发争议
  • 工信部:加快自动驾驶系统安全要求强制性国家标准研制
  • 监狱法修订草案提请全国人大常委会会议审议
  • 全过程人民民主研究基地揭牌,为推动我国民主政治建设贡献上海智慧