说到服务器的NUMA架构,大家或许都知道。NUMA架构在中大型系统上一直非常盛行,也是高性能的解决方案,尤其在系统延迟方面表现都很优秀。但NUMA架构对服务器的相关性能到底有什么影响,怎样设置会更好呢?本文在此解析一下。
1、什么是NUMA
NUMA(Non Uniform Memory Access Architecture)是一种用于多处理器的电脑记忆体设计,内存访问时间取决于处理器的内存位置。 在NUMA下,处理器访问它自己的本地存储器的速度比非本地存储器(存储器的地方到另一个处理器之间共享的处理器或存储器)快一些。
NUMA架构在逻辑上遵循对称多处理(SMP)架构。 它是在二十世纪九十年代被开发出来的,开发商包括Burruphs (优利系统), Convex Computer(惠普),意大利霍尼韦尔信息系统(HISI)的(后来的Group Bull),Silicon Graphics公司(后来的硅谷图形),Sequent电脑系统(后来的IBM),通用数据(EMC), Digital (后来的Compaq ,HP)。 这些公司研发的技术后来在类Unix操作系统中大放异彩,并在一定程度上运用到了Windows NT中。
NUMA 的主要优点是伸缩性。NUMA 体系结构在设计上已超越了 SMP 体系结构在伸缩性上的限制。通过 SMP,所有的内存访问都传递到相同的共享内存总线。这种方式非常适用于 CPU 数量相对较少的情况,但不适用于具有几十个甚至几百个 CPU 的情况,因为这些 CPU 会相互竞争对共享内存总线的访问。NUMA 通过限制任何一条内存总线上的 CPU 数量并依靠高速互连来连接各个节点,从而缓解了这些瓶颈状况。
2、NUMA的几种架构方案
NUMA 系统通常比一致内存访问系统(UMA)更加经济且性能更高。一致内存访问系统必须平等地为所有 CPU 提供内存,而 NUMA 系统则能够为直接连接到 CPU 的内存提供高速互连,同时为与 CPU 相隔较远的内存提供较为便宜但更高延迟的连接。
使用 NUMA 时,会经常遇到下面几种方案,以SQL SERVER数据库为例。(参阅technet资料)
A. 没有端口到 NUMA 的关联
这是具有硬件 NUMA 和单个 SQL Server 实例的计算机中的默认设置。所有通信流量都通过一个单独的端口输入并采用循环方式分布到任何可用的 NUMA 节点。NUMA 增大了内存和 CPU 访问的区域并增加了 I/O 和惰性编写器线程的数量。在建立连接后会立即将其作用域限定为此节点。它提供了 NUMA 节点间的自动负载平衡。客户端应用程序可以连接到单个端口,而且可以轻松地进行部署。
将一个端口关联到多个用于主要应用程序的硬件 NUMA 节点。将第二个端口关联到另一个用于第二个次要应用程序的硬件 NUMA 节点。用于这两个应用程序的内存和 CPU 资源量非常不平衡,用于主要应用程序的本地内存和 CPU 资源量是用于次要应用程序的三倍。次要应用程序可以是数据库引擎的第二个实例,它在同一数据库引擎实例中,甚至在同一数据库中提供次要的功能。通过向优先使用的连接提供额外资源,它提供了一种线程优先执行的方式。
可以将多个端口映射到同一 NUMA 节点。这样,您就可以为不同的端口配置不同的权限。例如,您可以通过控制对相应 TCP 端点的权限来严格限制由某个端口提供的访问。在此示例中,端口 1450 在 Intranet 上普遍可用。端口 1433 则设置为通过防火墙连接到 Internet,并对它的访问进行严格的限制。两个端口都可以充分、平等、安全地利用 NUMA。
3、如何设置,遵循什么原则
那么在虚拟化场景中,如何设置NUMA呢?原则是什么?
例如一台配置了两颗八核处理器以及128GB内存的服务器,我们需要在其上分配CPU和内存资源并划分虚机。
首先在NUMA架构中,每个处理器能够控制64GB的物理内存,每个处理器的八个核心中的每个核心将对应一个8GB的NUMA节点。这将会如何影响虚拟机性能?由于每个处理器核心访问NUMA节点内内存的速度要比其他节点快,因此当虚拟机内存大小少于或者等于NUMA节点的内存大小时,虚拟机在理论上能够获得最好的性能。如果给虚拟机分配更多的内存,则虚拟机必然要访问其NUMA节点之外的部分内存,这样或多或少会影响其性能。如果应用能够感知NUMA,那就更好了。vSphere使用vNUMA可以创建能够感知NUMA的虚拟机。该虚拟机将会被分割为虚拟NUMA节点,每个vNUMA节点将会被放置到一个不同的物理NUMA节点。尽管虚拟机仍旧在两个NUMA节点之间扩展,但虚拟机内的操作系统和应用能够感知NUMA,资源使用将会得到优化。
NUMA现已经对在数据中心服务器上安装及选择内存的方式带来了很多改变。在给服务器增加物理内存时,我们需要注意增加的内存要在NUMA节点之间进行平衡及匹配以使主板上的每个处理器拥有相同的内存。如果在我们所举例的服务器上配置更多的内存,那么必须在处理器之间平衡这些内存模块。如果增加64GB的内存,那么每个处理器将分配到32GB的内存(每个处理器可支配的内存将增加到96GB,服务器总内存数将达到192GB),每个NUMA节点的内存大小将从8GB增加到12GB。由于每个Socket控制的内存插槽是不同的,因此要确保内存插槽是均匀的。例如192G内存分为12个16G的内存条,那么应该4个插在一个Socket的内存插槽中,另8个插在另两个socket的内存插槽中。在为虚机分配vCPU资源时,也尽可能按照Socket/Core的倍数分配,比如1X1, 1X2, 1X 4, 1X8, 2X1, 2X2, 2X4, 2X8等组合,但不要使用2X3, 2X5, 2X7这种组合。后面的组合会引起跨Socket的内存调用,从而容易导致性能下降。
结合实践,不同的业务对内存会有不同的要求,但最好不要跨NUMA单元去进行调用,尽可能的使每个CPU访问它的直连内存单元。遵循这些简单的原则,就会使性能更好。