大家好,这里是编程Cookbook。本文详细介绍Redis数据库的内存分配器,这是redis为什么这么快的原因,以及其作为内存数据库的内存管理策略。

目录
Redis 的内存分配器 内存分配器的作用 Redis 支持的内存分配器 Redis 内存分配器的选择 Redis 内存管理机制 内存预分配 内存碎片 内存淘汰机制 压缩内存结构 Redis 内存优化建议 Redis 内存监控 开启最大内存限制 分布式存储
Redis 的内存分配器
Redis 的内存管理设计对性能和内存利用率有重要影响。其内存分配依赖底层的内存分配器和自身的一些优化机制。
内存分配器的作用
Redis 是一个基于内存的数据库,需要频繁地进行内存分配和释放操作。内存分配器的性能和设计直接影响 Redis 的整体性能。
内存分配器的主要职责: 高效分配和释放内存。 尽量减少内存碎片。 提供线程安全的并发支持(多线程场景)。
Redis 支持的内存分配器
Redis 支持多种内存分配器,常见的有以下三种:
| jemalloc | Redis 默认 | ||
| libc | 操作系统默认 | ||
| tcmalloc |
Redis 的内存分配器设计和优化是其性能的重要保障。正确选择分配器并监控内存使用,可进一步提升系统稳定性和效率。
jemalloc
默认分配器: 自 Redis 3.0 起,默认使用 jemalloc( jemalloc
是一款高性能内存分配器)。特点: 减少内存碎片:将内存分配按大小分类管理,分配和释放更加高效。 并发优化:支持多线程并发分配,适合高并发场景。 内存使用稳定:分配和释放的内存模式减少了碎片化问题。 优点: 在高并发场景下性能优异。 适合 Redis 的长连接、多命令操作模式。 缺点: 对小对象内存的利用率可能不如其他分配器(如 tcmalloc)。
libc
简介: 标准 C 库中提供的默认内存分配器。 特点: 实现简单,系统默认支持。 内存碎片化问题较严重,不适合 Redis 的高并发场景。 使用场景: 适合非高性能需求的场景。 优点: 开发和使用简单,无需额外配置。 缺点: 在高并发场景下性能较差。 内存碎片化问题明显,不适合 Redis 的长时间运行场景。
tcmalloc
简介:
Google 开发的高效内存分配器。 特点:
性能比 jemalloc 更高,但对小对象分配的内存利用率不如 jemalloc。 适用于极高并发场景。每个线程有独立的内存分配缓存,减少线程间的锁竞争。 使用场景:
在一些高并发业务中,可能会替代 jemalloc。 优点:
高性能,适合 Redis 在超高并发下的使用。 缺点:
对小对象内存管理不如 jemalloc 精细,可能会浪费内存。
Redis 内存分配器的选择
Redis 默认使用 jemalloc
,兼顾性能和碎片化控制,是推荐的内存分配器。
选择其他分配器步骤
更改编译选项: 在 Redis 源码目录下,编译时指定 MALLOC
参数即可选择内存分配器。示例: make MALLOC=libc # 使用 libc malloc
make MALLOC=tcmalloc # 使用 tcmalloc查看当前分配器: 编译完成后,通过 ldd redis-server
命令查看当前分配器:ldd redis-server | grep malloc
jemalloc 的优势
作为默认分配器,jemalloc 在 Redis 中表现优异,具体优势包括:
jemalloc的优势体现在减小内存碎片方面。 jemalloc 在 64 位系统中,将内存空间划分为小、大、巨大三个范围; 每个范围内又划分了许多小的内存块单位; 当 Redis 存储数据时,会选择大小最合适的内存块进行存储。size单位是字节。

1. 减少内存碎片
jemalloc 按内存块大小将内存分为不同类别(class),分配时选择最合适的类别,避免内存碎片化。
2. 线程本地缓存
jemalloc 为每个线程维护独立的分配缓存,减少线程间竞争。
3. 内存分配效率高
jemalloc 的分配算法更适合 Redis 的高并发特性,可以快速分配和释放内存。
4. 内存统计
jemalloc 提供了详细的内存统计工具,可通过 Redis 的 DEBUG
命令查看:redis-cli DEBUG malloc-stats
Redis 内存管理机制
除了底层的内存分配器,Redis 还采用了多种机制优化内存使用:
内存预分配
Redis 会为某些数据结构(如 SDS)预先分配一定的内存,避免频繁的内存分配操作。 优势: 提升性能,减少频繁分配和释放内存的开销。 动态扩容:当内存不足时,会按一定比例扩展,减少扩容次数。
内存碎片
问题: Redis 在分配和释放内存时,会出现碎片化问题。 指标: jemalloc 内置了优化机制,通过内存池减少碎片。 提供 INFO MEMORY
命令,可通过mem_fragmentation_ratio
指标监控内存碎片率。mem_fragmentation_ratio:1.05 # 碎片率 1.05,表示有 5% 的碎片低于 1.2:正常。 高于 1.5:可能存在严重碎片,需分析和优化。 优化方案: 如果发现碎片率过高(如超过 1.5),可以尝试以下几种优化方法: 重启 Redis:重启 Redis 会清理内存中的碎片,重新进行内存分配。 调整 jemalloc 配置:优化 jemalloc 的参数设置,以提高内存使用效率。 定期清理空闲内存:在 Redis 长时间运行后,可以使用 redis-cli memory purge
手动触发 jemalloc 的内存清理操作,减少碎片化。
内存淘汰机制
当 Redis 内存占用达到上限时,会根据设置的淘汰策略移除一些数据。
常见策略:
针对设置了过期时间的键
volatile-lru
:仅对设置了过期时间的键,淘汰最近最少使用的键。volatile-ttl
:仅对设置了过期时间的键,淘汰剩余时间最短的键。volatile-random
:仅对设置了过期时间的键,随机淘汰。volatile-lfu
:仅对设置了过期时间的键,淘汰访问频率最低的键。针对所有键
allkeys-lru
:对所有键,淘汰最近最少使用的键。allkeys-random
:对所有键,随机淘汰。allkeys-lfu
:对所有键,淘汰访问频率最低的键。无淘汰策略
noeviction
:不进行淘汰,当内存超限时直接返回错误。
压缩内存结构
Redis 内部使用紧凑型数据结构(如 ziplist、intset)来节省内存。 特点: 小规模数据(如小列表、小哈希)会使用压缩存储结构,减少内存开销。
Redis 内存优化建议
Redis 内存监控
Redis 提供了多种命令监控内存使用情况:
查看内存使用情况:
INFO MEMORY输出示例:
used_memory:1048576 # 已使用的内存
used_memory_peak:2097152 # 内存峰值
mem_fragmentation_ratio:1.02 # 内存碎片率查看键的内存占用:
MEMORY USAGE key查看内存分配统计: 使用 jemalloc 的
jemalloc.stats.print
。redis-cli -p 6379 debug jemalloc stats
开启最大内存限制
配置 maxmemory
参数,避免超出物理内存,报OOM(Out of Memory)错误。
分布式存储
在高内存使用场景下,采用 Redis Cluster 扩展容量。
热门文章回顾
欢迎订阅我们的Cookbook知识合集,目前《MySQL数据库》合集已基本更新完成,欢迎点击下方图片进入合集目录。

文章转载自编程Cookbook,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




