手册页提到:
libnuma 库为 Linux 内核支持的 NUMA(非统一内存访问)策略提供了一个简单的编程接口。在 NUMA 架构上,某些内存区域的延迟或带宽与其他区域不同。
这不适用于所有架构,这就是为什么第 14 期确保仅在 numa 机器上调用 numa 的原因。
如“将默认 numa 策略设置为“交错”系统范围“中所述:
似乎大多数推荐显式 numactl 定义的应用程序要么进行libnuma 库调用,要么将 numactl 合并到包装脚本中。
这interleave=all
缓解了cassandra(用于管理跨许多商品服务器的大量结构化数据的分布式数据库)等应用程序遇到的问题:
默认情况下,Linux 尝试对内存分配进行智能分配,以便数据靠近运行它的 NUMA 节点。对于大型数据库类型的应用程序,如果优先考虑避免磁盘 I/O,这不是最好的做法。特别是对于 Cassandra,无论如何我们都是多线程的,没有特别的理由相信一个 NUMA 节点比另一个“更好”。
在 NUMA 节点之间分配不均的后果可能包括当内核尝试分配内存时(例如重新启动 JVM)时过度的页面缓存驱逐。
有关更多信息,请参阅“ MySQL“交换疯狂”问题和 NUMA 架构的影响”
没有 numa
在基于 NUMA 的系统中,内存被划分为多个节点,系统应该如何处理这个问题并不一定很简单。
系统的默认行为是在计划运行线程的同一节点中分配内存,这适用于少量内存,但是当您想要分配超过一半的系统内存时,它不再是物理上的甚至可以在单个 NUMA 节点中执行此操作:在双节点系统中,每个节点中只有 50% 的内存。
与努马:
一个简单的解决方案是交错分配的内存。如上所述,可以使用 numactl 执行此操作:
# numactl --interleave all command
我在评论中提到numa 枚举硬件以了解物理布局。然后将处理器(不是内核)划分为“节点”。
对于现代 PC 处理器,这意味着每个物理处理器一个节点,而与存在的内核数量无关。
正如Hristo Iliev指出的那样,这有点过于简单化了:
具有更多内核的 AMD Opteron CPU 实际上是 2 路 NUMA 系统,它们本身具有两个HT(HyperTransport)互连的芯片,在单个物理封装中具有自己的内存控制器。
此外,具有 10 个或更多内核的 Intel Haswell-EP CPU 带有两个缓存一致的环形网络和两个内存控制器,并且可以在芯片上集群模式下运行,这表现为一个双向 NUMA 系统。
更明智的说法是,NUMA 节点是一些无需通过 HT、QPI (QuickPath_Interconnect)、NUMAlink 或其他一些互连即可直接到达某些内存的内核。