CPU利用率是否会影响外部NUMA访问的成本?


21

情境

假设我有一个带有4个套接字的SQL Server,每个套接字有1个NUMA节点。每个插槽具有4个物理核心。总内存为512 GB,因此每个NUMA节点均具有128 GB的RAM。

密钥表被加载到第一个NUMA节点中。

假设我们从该表读取了大量流量。如果拥有NUMA节点的套接字的所有物理核心都具有100%的CPU利用率,这是否会对来自其他套接字的非本地NUMA访问的成本产生负面影响?或者,另一方面,无论本地套接字有多忙,非本地NUMA访问的成本都是多少?

我希望我的问题有道理。请让我知道是否可以尝试澄清。

背景

上周我们的生产服务器中发生数据库问题,某些业务处理似乎受到了更大的影响。我们进行的查询几乎没有逻辑读取,但需要超过1分钟的时间。我们查看的总体CPU利用率约为60%。我们没有查看特定于套接字的CPU指标。I / O指标是平均值。


如果您可以产生类似Kin所提到的内容,将会很有帮助。另外,您将MAXD​​OP设置为什么?
user41207

Answers:


18

一个沉重的问题:-)我将概述其中涉及的一些因素。在任何给定的上下文中,这些因素和其他因素都可以变化并产生有趣的结果。

抱歉,我无法将其缩短很多...

  1. 累积CPU毫秒与逻辑IO
  2. SQL Server逻辑内存节点与物理NUMA节点的对齐
  3. 查询工作空间内存分配中的自旋锁争用
  4. 计划任务分配
  5. 缓冲池中的相关数据放置
  6. 物理内存位置

  1. 累积CPU毫秒与逻辑IO

    为了评估工作负载的CPU效率并寻找容易发生自旋锁的情况,我经常使用逻辑IO的图形(或用perfmon术语“缓冲池页面查找”)针对CPU利用率。

    但是,SQL Server除了页面查找和自旋锁以外,还通过许多活动来累积CPU时间:

    • 计划被编译并重新编译。
    • 执行CLR代码。
    • 执行功能。

    许多其他活动会占用大量CPU时间,而不会在页面查找中反映出来。

    在我观察到的工作负载中,这些“非逻辑IO密集但CPU吞噬”活动中的主要活动是排序/散列活动。

    这是有道理的:考虑一个针对没有哈希表的哈希表的两个查询的人为例子。这两个查询具有相同的结果集,但是其中一个结果集是完全无序的,而第二个结果集是由多个选定列中的一个以上排序的。即使第二个查询将引用缓冲池中相同数量的页面,也将消耗更多的CPU时间。

    这些帖子中提供了有关工作空间内存以及已使用多少授权工作空间的更多信息:


  1. SQL Server逻辑内存节点与物理NUMA节点的对齐

    默认情况下,SQL Server(由于结合了其NUMA感知策略)将为服务器上的每个NUMA节点创建一个SQLOS内存节点。随着内存分配的增长,每个分配都由一个SQLOS内存节点控制。

    理想情况下,SQLOS内存节点与物理NUMA节点完全对齐。也就是说,每个SQLOS内存节点都包含来自单个NUMA节点的内存,没有其他SQLOS内存节点也包含来自同一NUMA节点的内存。

    但是,理想情况并非总是如此。

    以下CSS SQL Server工程师博客文章(也包含在Kin的响应中)详细介绍了行为,这些行为可能导致为SQLOS内存节点持久保留跨NUMA节点的内存分配。发生这种情况时,对性能的影响可能是灾难性的。

    对于持久的跨NUMA节点引用的特别痛苦的情况,已经有一些修复程序。除了这两个之外,可能还有其他:


  1. 工作空间内存分配期间的自旋锁争用

    这是开始变得有趣的地方。我已经描述了工作空间内存中的排序和哈希工作会消耗CPU,但不会反映在bpool查找数中。

    自旋锁竞争是这一特殊乐趣的另一层。当内存从缓冲池中窃取并分配给查询内存授权使用时,内存访问将通过自旋锁进行序列化。默认情况下,这是在NUMA节点级别上分区的资源上进行的。因此,在使用授权工作区窃取内存时,使用工作区内存的同一NUMA节点上的每个查询都可能遇到自旋锁争用。需要特别注意的是:这不是“每个查询一次”的争用风险,因为争用点是在实际授予时。而是,其何时内存针对授权被盗-因此,具有很大内存授权的查询如果使用其大部分授权,将有很多机会进行自旋锁争用。

    跟踪标志8048通过在核心级别进一步划分资源,在缓解此争用方面做得很出色。

    微软说:“如果每个插槽有8个或更多核心,请考虑跟踪标志8048”。但是...实际上并不是每个套接字有多少个内核(只要有多个),而是在单个NUMA节点上完成的工作中有多少竞争的机会。

    在粘合的AMD处理器上(每个插槽12个内核,每个插槽2个NUMA节点),每个NUMA节点有6个内核。我看到一个系统,其中有4个CPU(因此有8个NUMA节点,每个6个内核)被卡在自旋锁队列中,直到启用了跟踪标志8048。

    我已经看到这种自旋锁争用降低了最小到4个vCPU的VM的性能。在那些系统上启用跟踪标记8048后,它应该执行预期的操作。

    考虑到仍然有大约4个经过核心频率优化的CPU,具有适当的工作负载,它们也将从跟踪标志8048中受益。

    CMEMTHREAD等待伴随跟踪标志8048缓解的自旋锁争用类型。但请注意:CMEMTHREAD等待是确证的症状,而不是此特定问题的根本原因。我看到CMEMTHREAD“等待启动”率很高的系统,由于累积的CMEMTHREAD等待时间非常短,因此在部署中延迟了跟踪标志8048和/或9024。对于自旋锁,累积的等待时间通常是错误的。相反,您想查看浪费的CPU时间-主要由旋转本身表示,其次由相关联的等待表示,这些等待表示可能不必要的上下文切换。


  1. 计划任务分配

    在NUMA系统上,假设没有特定的NUMA节点关联的连接端点,则将连接分配给NUMA节点(实际上是实际上分配给与其关联的SQLOS调度程序组)。如果会话执行并行查询,则强烈倾向于使用单个NUMA节点中的工作程序。嗯...考虑一个4 NUMA节点服务器,它的复杂查询分为4个路径,默认为0 MAXDOP。即使查询仅使用MAXDOP工作线程,NUMA节点上的每个逻辑CPU也会有4个工作线程。但是复杂计划中有4条路径-因此NUMA节点上的每个逻辑CPU都可以有16个工作线程-全部用于一个查询!

    这就是为什么有时您会看到一个NUMA节点在工作而其他节点却在闲逛的原因。

    任务分配还有其他一些细微差别。但是主要的收获是,CPU繁忙不一定会在NUMA节点之间平均分配。(也很高兴认识到bpool页面插入(读取或首页写入)将进入与工作程序所在的调度程序相关联的SQLOS内存节点中的bpool。并且被盗页面将优先来自“本地” SQLOS内存节点。

    我发现将maxdop从0提升到不超过8是有帮助的。根据工作负载配置文件(主要基于并发预期潜在长时间运行的查询数),可以保证一直到MAXDOP = 2。

    调整并行性的成本阈值也可能会有所帮助。我使用的系统往往被高成本查询所占用,很少遇到低于50或100的计划,因此通过调整maxdop(在工作负载组级别上通常是),与调整成本阈值相比,我获得了更多的吸引力。


  1. bpool中的相关数据放置

    我认为这是处理NUMA服务器时最直观的条件。通常,它对工作负载性能也不是很重要。

    如果将表读入NUMA节点3上的bpool中,然后在NUMA节点4上执行查询,则扫描该表以执行NUMA节点上的所有bpool查找?

    Linchi Shea对此性能影响发表了出色的文章:

    跨NUMA节点访问内存会导致少量额外的内存延迟。我确定有些工作量需要消除额外的基本内存延迟以实现最佳性能-在我使用的系统上这不是问题。

    但是-跨节点访问也带来了另一个转移点,该转移点可能会饱和。如果活动过多,则NUMA节点之间的内存带宽已饱和,则节点之间的内存延迟将增加。相同的工作将需要更多的CPU周期。

    再说一遍-我敢肯定,内存带宽是一个至关重要的考虑因素。但是,对于我的系统,我列出的其他注意事项更为重要。


  1. 物理内存位置

    这是很少见的,但是当它很重要时,它确实很重要。在大多数服务器上,内存安装几乎自然会在NUMA节点之间达到平衡。但是在某些情况下,需要特别注意平衡节点之间的内存。如果以不平衡的方式插入内存,则某些系统的性能可能会被完全破坏。不过,这是一劳永逸的。经过数月的生产服务,而不是在第一天非常繁忙的一天之后发现这样的问题,这种情况很少见:-)


大完成!

有人指出,糟糕的计划选择(可能是由于过时的统计信息)可能导致您看到的症状。根据我的经验,情况并非如此。糟糕的计划很容易使查询花费比预期更长的时间-但通常是因为执行的逻辑IO超出了必要。还是由于溢出到tempdb。观察服务器时,大量溢出到tempdb应该是明显的-与高CPU相比,人们期望可观的等待时间是与溢出相关的磁盘写入。

相反,如果您观察到的情况与NUMA相关,那么我希望它是上述因素的组合,主要是:

  1. 使用工作区内存(不会以逻辑IO计数显示)

  2. 由于持久的外部内存状况,它可能是跨NUMA节点的(如果是这种情况,请查找相关的修复程序)

  3. 并且每次针对授权进行分配时,都可能在NUMA节点内引发自旋锁争用(T8048修复)

  4. 并且可以由工作程序在其他并行查询工作程序超载的逻辑CPU上执行(必要时调整maxdop和/或并行度的成本阈值)


7

请使用coreinfo -v(sysinternal实用程序)输出更新您的问题,以更好地了解您的CPU /套接字和NUMA分布

我们查看的总体CPU利用率约为60%。我们没有查看特定于套接字的CPU指标。I / O指标是平均值。

在我看来,您在错误的树上吠叫。SQL Server NUMA知道。有做跨NUMA内存访问更小的性能损失。您还可以使用此查询来查看NUMA您拥有多少个节点以及将哪个CPU和内核分配给哪个NUMA

SELECT parent_node_id, scheduler_id, cpu_id
FROM sys.dm_os_schedulers WITH (NOLOCK) 
WHERE [status] = N'VISIBLE ONLINE';

或多少NUMA

select COUNT(distinct Parent_node_id)
from sys.dm_os_schedulers
where [STATUS] = 'VISIBLE ONLINE'
    and Parent_node_ID < 64

我们进行的查询几乎没有逻辑读取,但需要超过1分钟的时间。

当您由于统计数据过时而生成错误的查询计划时,通常会发生这种情况。确保更新了统计信息并正确整理了索引碎片

另外,您需要将MAXD​​OP设置为更合理的值,避免工作线程不足

cost threshold of parallelism默认值5设置为一个良好的起始值(如45),然后监视该值并根据您的环境进行调整。

如果您正在运行大量临时查询,请打开(设置为1)optimize for ad hoc workloads以防止计划缓存膨胀。

谨慎使用:如果您在较新的计算机上运行SQL Server 2008/2008 R2,并且每个NUMA节点上的CPU数量超过8个,则可以使用T8048;如果在SQL Server 2012或2014上,则有一个修补程序

强烈建议您开始收集有关数据库服务器实例的等待统计信息。

请参阅:工作原理:SQL Server(NUMA本地,外部和外部内存块)


1

纯粹从硬件的角度来看,从Nehalem架构开始对主内存的管理是通过集成内存控制器进行管理的,这是在CPU裸片的“非核心”部分,与实际内核所处的部分分开,因为内存实际上是“连接”到每个CPU的,所以外部内存访问AFAIK是通过快速路径互连(再次从Nehalem开始),因此,我要说的是,本地NUMA节点上的CPU内核饱和不会影响对该内存的远程访问。

您可能会发现此链接有用:

http://cs.nyu.edu/~lerner/spring10/projects/NUMA.pdf

克里斯

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.