1. Redis内存占用之谜:数据删除后为何内存不降?
第一次遇到Redis内存居高不下的情况时,我正负责一个日活百万级的电商系统。当时监控突然报警显示某个Redis实例内存占用达到5.8GB(总内存6GB),紧急删除了一批缓存数据后,发现used_memory降到了3GB,但通过top命令看到的RSS内存占用依然保持在5.5GB左右。这个现象让我困惑不已——明明数据已经删除,为何内存没有被释放?
通过深入排查,我发现这是Redis内存管理的核心特性之一。Redis作为内存数据库,其内存管理机制与传统的MySQL等磁盘数据库有本质区别。操作系统看到的RSS(Resident Set Size)是Redis进程实际占用的物理内存总量,而used_memory仅是存储数据实际使用的内存量。两者之间的差值主要来自三个方面:
-
内存分配器策略:Redis默认使用jemalloc内存分配器,它采用固定大小的内存块进行分配(如8B、16B、...2KB、4KB等)。当申请1.5KB内存时,jemalloc会分配2KB,剩余的0.5KB就成为无法被其他数据使用的碎片。
-
延迟释放机制:删除key时,Redis不会立即将内存归还给操作系统。这是因为:
- 释放的内存可能与其他有效key共享同一个内存页
- 内存分配器会保留这些空间供后续复用
- 频繁的内存申请释放会导致性能下降
-
Redis自身开销:包括客户端缓冲区、AOF缓冲区、复制积压缓冲区等。在大流量场景下,这些缓冲区可能占用GB级内存。
重要提示:必须设置maxmemory参数!否则当物理内存耗尽时,Redis会因OOM被系统强制杀死。建议设置为物理内存的70%-80%。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 内存碎片详解:从理论到实践
2.1 内存碎片的形成机制
想象你在管理一个大型仓库,所有货物都必须放在统一规格的货架上(比如每个货架2立方米)。当有1.5立方米的货物入库时,你不得不占用整个2立方米的货架,剩余的0.5立方米就浪费了。随着不同尺寸货物的频繁出入库,仓库中会逐渐出现大量无法利用的零散空间——这就是内存碎片的现实类比。
在Redis中,碎片化主要由以下场景触发:
写入阶段:
- 写入10B的字符串,jemalloc分配16B
- 写
