Redis 内存碎片
本文将介绍内存碎片的概念,说明 Redis 为什么会产生内存碎片,并介绍如何处理。
一、什么是内存碎片?
内存碎片是指内存中小且不连续的内存空间。
内存碎片的空间过小,导致它们无法被应用程序申请利用,但它们又实际占用了内存空间,因此会影响内存的使用率。
二、Redis 的内存碎片
Redis 中内存碎片出现的原因主要有:
- 操作系统的内存分配机制
- 键值对的增删改查
1. 操作系统的内存分配机制
内存分配器并不会完全按照应用程序申请的内存空间分配,而是按固定大小分配内存。
这种分配方式的目的是为了减少分配次数。
例如应用程序需要 20 个字节的空间,直接分配 32 个字节,当应用还需要写入 5 个字节时,不再需要二次分配
在这种分配机制下,Redis 会在每次申请都会获得更大一些的内存空间,使其 “占据” 一部分暂时不会使用的空间。
2. 键值对的增删改查
键值对的增删改查会导致空间的扩容和释放,在这一过程中,便可能导致内存中出现许多不连续的内存碎片。
三、Redis 内存碎片判断
Redis 支持查询内存使用的详细情况:
1 |
|
mem_fragmentation_ratio
指标即是 Redis 当前的内存碎片率。
mem_fragmentation_ratio
是 used_memory_rss
和 used_memory
相除的结果。其中, used_memory_rss
是操作系统实际分配给 Redis 的物理内存空间, used_memory
是 Redis 为了保存数据实际申请使用的空间。
mem_fragmentation_ratio
大于 1 但小于1.5 是合理的mem_fragmentation_ratio
大于 1.5 时,表示内存碎片率已经超过 50%,应该采取措施降低内存碎片率
四、Redis 内存碎片处理
1. 重启 Redis 实例
一个简单粗暴的做法是重启 Redis 实例。
这个方法的后果是:
- 如果 Redis 中的数据没有持久化,数据会丢失
- 即使 Redis 中的数据已持久化,重启后也需要恢复时间
2. 内存碎片自动清理
从 4.0-RC3 版本以后,Redis 自身提供了一种内存碎片自动清理的方法。
这个方法简单来说就是 “搬家让位,合并空间”。
需要注意的是:碎片清理是有代价的。
碎片清理时需要拷贝数据、释放空间,这会带来时间开销。Redis 是单线程,数据拷贝将会影响 Redis 对请求的处理。
可以通过设置与内存碎片自动清理的参数,在适时碎片清理的同时避免对 Redis 的性能影响。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 启用自动内存碎片清理
config set activedefrag yes
# 内存碎片的字节数达到 100MB 时,开始清理
active-defrag-ignore-bytes 100mb
# 内存碎片空间占操作系统分配给 Redis 的总空间比例达到 10% 时,开始清理
active-defrag-threshold-lower 10
# 自动清理过程所用 CPU 时间的比例不低于 25%,保证清理能正常开展
active-defrag-cycle-min 25
# 自动清理过程所用 CPU 时间的比例不高于 75%,一旦超过,就停止清理,从而避免在清理时,大量的内存拷贝阻塞 Redis,导致响应延迟升高
active-defrag-cycle-max 75
参考
- Redis
- Redis 教程 | 菜鸟教程
- Redis数据库学习教程(快速入门版)
- Redis 核心技术与实战