共计 1371 个字符,预计需要花费 4 分钟才能阅读完成。
作者:任仲禹
爱可生 DBA 团队成员,善于故障剖析和性能优化,文章相干技术问题,欢送大家一起探讨。
本文起源:原创投稿
* 爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。
背景问题
偶尔收到某客户问题“我的 Redis 内存碎片率很低在 0.2 左右,网上说会导致 Redis 性能变慢,我该咋办?”。
官网的计算 Redis 内存碎片率的公式如下:
mem_fragmentation_ratio = used_memory_rss / used_memory
即 Redis 向操作系统中申请的内存
与 分配器调配的内存总量
的比值,两者简略来讲:
- 前者是咱们通过 top 命令看到的 redis 过程 RES 内存占用总量
- 后者由 Redis 内存分配器(如 jemalloc)调配,包含本身内存、缓冲区、数据对象等
两者的比值后果 < 1
示意碎片率低,> 1
为高, 碎片率高的问题百度上 海量 文章有介绍,不多赘述,但碎片率低根本都归咎于应用了 SWAP 而导致 Redis 因拜访磁盘而性能变慢。但,真的是这样吗?
验证
客户生产环境中
- 禁用了 SWAP
- 数据量为 60M 左右
- repl-backlog-size 即复制积压缓冲区配置为 1G
所以我这边设置下 vm.swappiness = 1
将 swap 先关掉,设置 repl-backlog-size=512M,再启个 Redis 空实例。
看下 memory stats
,因为没任何键、复制线程、客户端,所以数据对象占用内存、复制积压缓冲区、客户端相干 buffer 都为 0;此时 Redis 内存分配器调配的内存总量是 863944(启动后初始内存量
startup.allocated+ 初始元数据 dataset.bytes),向操作系统申请的内存为 2789376,碎片率为 3.48。
给测试库启动个从库后,碎片率霎时降为 0.01;
看下实例配置,理论复制积压缓冲区大小与分配器内存调配值能对应上,都为 512M;所以启动复制后,因为调配总内存变大但向操作系统申请的内存无太大变动,所以碎片率取值天然会骤降。
为什么此时 Redis 不向操作系统申请配置指定的 512M 内存?
答案是:只有在 slave 端首次建设复制 / 失连时才会真正向操作系统申请复制积压缓存;并且不是一次性向 OS 申请 512M,而是按需应用;能够简略测试如下。
模仿从库失联
从库执行 debug 命令模仿 Redis 夯死
给主库制作点压力
通过指定命令输入内存应用状况如下。
能看到复制积压缓冲区、复制客户端输入缓冲区逐步耗费内存,但 操作系统理论内存 used_memory_rss 并非一次性打满,而是按需减少。
碎片率小于 1 跟数据量有无关系?
后面通过试验,能够晓得碎片率低并非仅由 SWAP 导致,复制积压缓冲区等配置值过大、键值对象数据极小的状况下也会使比值升高;那么数据质变大会咋样?
继续灌入数据
能够看到 used_memroy
和 used_memory_rss
都会逐步变大,内存碎片率取值将逐步趋于 1。
论断
- Redis 内存碎片率低并非只跟 SWAP 无关,生产环境通常倡议禁用了 SWAP。
- 复制积压缓冲区配置较大、业务数据量较小的状况下极容易造成碎片率
远低于 1
,这是失常景象,无需优化或调整。 - 通常将线上环境复制缓冲区的值
repl-backlog-size
设置的比拟大,目标是避免主库频繁呈现全量复制而影响性能。 - 随着业务数据量增长,Redis 内存碎片率比值会逐步趋于 1。