3

Redis 支持 3 种内存分配器:libc、jemalloc、tcmalloc。当我进行内存使用测试时,我发现使用 libc 分配器时INFO MEMORY中的mem_fragmentation_ratio可能小于 1。使用 jemalloc 或 tcmalloc,此值应大于或等于 1。

谁能解释为什么mem_fragmentation_ratio在 libc 中小于 1?

Redis 版本:2.6.12。中央操作系统 6

更新:

我忘了提到一个可能的原因是交换发生并且mem_fragmentation_ratio将 < 1。

但是当我进行测试时,我会调整交换性,甚至关闭交换。结果是一样的。而且我的redis实例其实并没有占用太多内存。

4

2 回答 2

3

通常,与使用 libc malloc 相比,使用 jemalloc 或 tcmalloc 的碎片更少。这是由于4个因素:

  • jemalloc 和 tcmalloc 的更细粒度的分配类。它减少了内部碎片,尤其是当 Redis 必须分配大量非常小的对象时。

  • 更好的算法和数据结构来防止外部碎片(尤其是对于 jemalloc)。显然,收益取决于您的长期内存分配模式。

  • 支持“malloc 大小”。一些分配器提供了一个 API 来返回分配的内存大小。在 glibc (Linux) 中,malloc 不具备此功能,因此通过显式为每个分配的内存块添加额外前缀来模拟它。它增加了内部碎片。使用 jemalloc 和 tcmalloc(或使用 BSD libc malloc),没有这样的开销。

  • jemalloc(以及带有一些设置更改的 tcmalloc)可以比 glibc 更积极地向操作系统释放内存 - 但同样,它取决于分配模式。

现在,如何获得 mem_fragmentation_ratio 的不一致值?

INFO 文档中所述,mem_fragmentation_ratio 值计算为进程的内存驻留集大小(RSS,由操作系统测量)与 Redis 使用分配器分配的总字节数之间的比率。

现在,如果使用 libc 分配了更多内存(与 jemalloc、tcmalloc 相比),或者如果在您的基准测试期间系统上的某些其他进程使用了​​更多内存,则操作系统可能会换出 Redis 内存。它将减少 RSS(因为 Redis 内存的一部分将不再位于主内存中)。产生的碎片率将小于 1。

换句话说,这个比率只有在你确定 Redis 内存没有被操作系统换出时才有意义(如果不是这样,你无论如何都会遇到性能问题)。

于 2013-08-07T08:55:24.677 回答
1

除了交换,我知道 2 种方法可以使“内存碎片率”小于 1:

  1. 有一个数据很少或没有数据的 redis 实例,但有数千个空闲的客户端连接。从我的测试来看,redis 似乎必须为每个客户端连接分配大约 20 KB 的内存,但其中大部分直到稍后才会真正使用(即不会出现在 RSS 中)。

  2. 有一个主从设置,比如说 8 GB 的repl-backlog-size. 复制开始后将立即分配 8 GB(仅在 master 上用于版本 <4.0,否则在 master 和 slave 上),但内存将仅在我们开始写入 master 时使用。因此,该比率最初将远低于 1,然后随着复制积压工作的填满而越来越接近 1。

于 2020-05-04T11:01:08.127 回答