Redis 支持 3 种内存分配器:libc、jemalloc、tcmalloc。当我进行内存使用测试时,我发现 INFO MEMORY 中的 mem_fragmentation_ratio 对于 libc 分配器可能小于 1。对于 jemalloc 或 tcmalloc,这个值应该大于或等于 1。
谁能解释为什么 libc 的 mem_fragmentation_ratio 小于 1?
Redis 版本:2.6.12。中央操作系统 6
更新:
我忘了提到一个可能的原因是交换发生并且 mem_fragmentation_ratio 将 < 1。
但是当我进行测试时,我会调整 swapiness,甚至关闭 swap。结果是一样的。而我的 redis 实例实际上不会占用太多内存。
最佳答案
一般来说,与 libc malloc 相比,jemalloc 或 tcmalloc 的碎片更少。这是由于 4 个因素:
jemalloc 和 tcmalloc 的更精细的分配类。它减少了内部碎片,尤其是当 Redis 必须分配大量非常小的对象时。
更好的算法和数据结构来防止外部碎片(尤其是对于 jemalloc)。显然, yield 取决于您的长期内存分配模式。
支持“malloc 大小”。一些分配器提供了一个 API 来返回已分配内存的大小。对于 glibc (Linux),malloc 不具备此功能,因此通过向每个分配的内存块显式添加额外前缀来模拟它。它增加了内部碎片。使用 jemalloc 和 tcmalloc(或使用 BSD libc malloc),没有这样的 开销。
jemalloc(和 tcmalloc 有一些设置更改)可以比 glibc 更积极地向操作系统释放内存 - 但同样,它取决于分配模式。
现在,如何获得不一致的 mem_fragmentation_ratio 值?
如 the INFO documentation 中所述,mem_fragmentation_ratio 值计算为进程的内存驻留集大小(RSS,由操作系统测量)与 Redis 使用分配器分配的字节总数之间的比率。
现在,如果使用 libc 分配了更多内存(与 jemalloc、tcmalloc 相比),或者如果在基准测试期间系统上的某些其他进程使用了更多内存,Redis 内存可能会被操作系统换出。它将减少 RSS(因为 Redis 内存的一部分将不再位于主内存中)。由此产生的碎片率将小于 1。
换句话说,只有当您确定 Redis 内存没有被操作系统换出时,这个比率才有意义(如果不是这样,您无论如何都会遇到性能问题)。
关于memory-management - 为什么 Redis 内存碎片小于 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18097670/