Docker中的Mongodb:numactl –interleave =所有的解释

我正在尝试根据https://hub.docker.com/_/mongo/官方Dockerfile为内存中的MongoDB创buildDockerfile

dockerfile-entrypoint.sh我遇到过:

 numa='numactl --interleave=all' if $numa true &> /dev/null; then set -- $numa "$@" fi 

基本上它numactl --interleave=all原始docker命令,当numactl存在。

但是我不太了解这个NUMA政策。 你能解释一下NUMA的真正意义,什么--interleave=all代表什么?

为什么我们需要使用它来创buildMongoDB实例?

手册页提到 :

libnuma库为Linux内核支持的NUMA(非统一内存访问)策略提供了一个简单的编程接口。 在NUMA体系结构中,某些内存区域与其他内存区域的延迟或带宽不同。

这不适用于所有体系结构,这就是为什么问题14只能在numa机器上调用numa。

如“ 设置默认numa策略”“交错”系统范围 “中所述:

看起来大多数build议显式numactl定义的应用程序都可以创build一个libnuma库调用,或者将numactl合并到一个包装脚本中 。


interleave=all缓解应用遇到的问题类似cassandra (分布式数据库,用于pipe理大量的商品服务器上的大量结构化数据):

默认情况下,Linux试图对内存分配很敏感,以使数据接近运行的NUMA节点。 对于大型数据库types的应用程序,如果优先级是避免磁盘I / O,那么这不是最好的办法。 特别是对于Cassandra,无论如何我们都是multithreading的,没有特别的理由相信一个NUMA节点比另一个节点“更好”。

在NUMA节点间不均匀分配的后果可能包括当内核尝试分配内存时(例如重新启动JVM时)出现过多的页面caching逐出。

有关详情,请参阅“ MySQL交换精神错乱”问题以及NUMA体系结构的影响 “

没有numa

在一个基于NUMA的系统中,内存分为多个节点,系统如何处理并不一定是简单的。
系统的默认行为是在同一个节点上分配内存,因为一个线程被调度运行,这对于less量的内存来说效果很好,但是当你想分配超过一半的系统内存时,它不再是物理内存甚至可以在单个NUMA节点中完成:在双节点系统中,每个节点中只有50%的内存。

http://jcole.us/blog/files/numa-imbalanced-allocation.png

有了Numa:

一个简单的解决scheme是交错分配的内存。 如上所述,使用numactl可以做到这一点:

 # numactl --interleave all command 

我在评论中提到,numa列举了硬件来理解物理布局。 然后把处理器(不是核心)分成“节点”。
对于现代PC处理器,这意味着每个物理处理器只有一个节点,而不pipe存在多less个核心。

正如Hristo Iliev所指出的那样,这简直太过简单了:

具有更多内核的AMD Opteron CPU实际上是双路NUMA系统,在单个物理封装中具有两个具有自己的内存控制器的HT(HyperTransport)互连pipe芯。
此外,具有10个或更多内核的英特尔®Haswell-EP CPU具有两个高速caching一致性环网和两个内存控制器,并且可以以群集模式(cluster-on-die)模式运行,该模式performance为双向NUMA系统。

更聪明的说, NUMA节点是一些内核,可以直接访问某些内存,而无需通过HT, QPI(QuickPath_Interconnect) ,NUMAlink或其他互连

http://jcole.us/blog/files/numa-balanced-allocation.png

为什么不把cassandra和/或mongodb numa知道? 即使有大量的线程架构,他们也可以通过减lessQPIstream量来实现更好的性能。