插入20万个key再交替删除一半,对比used_memory和used_memory_rss的变化,看内存碎片是怎么在Redis进程里产生的。
used_memory是Redis自己统计的"逻辑上在用"的内存,used_memory_rss是操作系统报告的物理内存占用。
操作插入20万个key(值大小随机50~500字节) INFO memory | used_memory / used_memory_rss / mem_fragmentation_ratio 交替删除偶数下标的10万个key(每隔一个删一个) INFO memory | 再看一次
刚写满数据的时候,逻辑内存和物理内存贴得很近。
结果(插入20万个key之后)used_memory: 71461408 字节 (≈71.46MB) used_memory_rss: 77512704 字节 (≈77.51MB) mem_fragmentation_ratio: 1.14
1.14的碎片率是健康区间(一般认为1~1.5算正常)——物理内存比逻辑内存多了大约6MB,这部分是正常的分配器预留和元数据开销,不算浪费。
按"每隔一个删一个"的方式删掉10万个key,制造的内存空洞。
结果(交替删除10万个key之后)DBSIZE: 100000(逻辑上只剩一半key了) used_memory: 37465536 字节 (≈37.47MB,几乎正好减半) used_memory_rss: 81051648 字节 (≈81.05MB,不降反升!) mem_fragmentation_ratio: 2.07(从1.14涨到2.07)
Redis自己统计的 used_memory 老老实实地减半了——逻辑上确实只剩10万个key在用内存。但操作系统报告的 used_memory_rss 一点没降,反而比删除前还高了一点。碎片率从1.14飙升到2.07,意味着"操作系统分配给Redis进程的物理内存"里,超过一半其实已经是没人在用的空洞。
每一步都是本文上面用INFO memory拿到的原始数字。
INFO memory:对比used_memory / used_memory_rss / mem_fragmentation_ratio