2024年1月31日 星期三

SQL Server CPU 在 NUMA 節點上,CPU 負載不平衡的處理

最近接到客戶反應,為何 SQL Server 的主機上的 CPU 的負載只有在其中的一個 NUMA 的節點上,所以想請我們協助判斷是否為何有這種情況,如下列的例圖。

在說明如何排查問題時,我們先來介紹一下何為 NUMA 節點,NUMA 全名為 "Non-uniform Memory Access",主要用於加速 CPU 與 Memory 的效能存取,簡單的說,在 CPU 上會放在一個 CPU socket 的插座上,假設底層有 Dual Processor,就代表有二顆 CPU 與二個 CPU 插座,而在 SQL Server 中就會有二個 NUMA 節點,如下圖所示。



進一步的驗證,可以透過系統資訊(MSINFO)與 SQL Server 中的 Error Log 中進行確認。

系統資訊:

Processor(s):              2 Processor(s) Installed.

[01]: Intel64 Family 6 Model 63 Stepping 2 GenuineIntel ~2594 Mhz

[02]: Intel64 Family 6 Model 63 Stepping 2 GenuineIntel ~2594 Mhz


SQL Server Error Log

2024-01-20 21:29:02.16 Server      Node configuration: node 0: CPU mask: 0x0000000000000fff:0 Active CPU mask: 0x0000000000000fff:0. This message provides a description of the NUMA configuration for this computer. This is an informational message only. No user action is required.

2024-01-20 21:29:02.16 Server      Node configuration: node 1: CPU mask: 0x0000000000fff000:0 Active CPU mask: 0x0000000000fff000:0. This message provides a description of the NUMA configuration for this computer. This is an informational message only. No user action is required.

2024-01-06 19:39:03.14 Server      SQL Server detected 2 sockets with 12 cores per socket and 12 logical processors per socket, 24 total logical processors; using 24 logical processors based on SQL Server licensing. This is an informational message; no user action is required.

如上述的資訊,有二個 CPU 插座 (socket),12 核心,24個邏輯核心,所以在 SQL Server 會識別為 2個 NUMA 節點,每個節點有12個核心,總共有 24 個核心可用。

簡單的說,透過 NUMA 節點,彼此間有各自的通道與 IO,記憶體等進行溝通,將有助於流量的隔離與區分,有助於減少彼此間的影響,架構上如下圖所示。

問題排除建議:

1. 首先需要確認此主機是否有其他的程式影響造成 CPU 不平衡的情況發生,或許兇手不完全是 SQL Server,簡單的方式,可以透過工作管理員 (Task Manager),但如果要長期監控,可以透過效能監視器中的 Processor Time 來判斷是否真的就是 SQL Server 所造成。

由上圖的監控上來看,可以知道幾乎就是 SQL Server 的程式所造成的。

2. 由於 SQL Server 上的 NUMA 節點預設是自動設定,強烈的建議千萬不要自已去異動,千萬不用動設定千萬不用動設定千萬不用動設定,很重要,所以說三次,我將相關的設定整理如下。


max degree of parallelism -> 1

Resource_governor_configuration = 0 

affinity mask -> 0

affinity I/O mask -> 0

affinity64 mask -> 0

affinity64 I/O mask -> 0


3. 透過 DMV 查詢是否有系統有修改過 Soft NUMA 的設定,下列的值為 0,所以代表也是沒有修改過。

select softnuma_configuration,* from sys.dm_os_sys_info

參考連結:
https://learn.microsoft.com/zh-tw/sql/database-engine/configure-windows/soft-numa-sql-server?view=sql-server-ver16


4. 預設的情況下,SQL Server 在工作的分配上,都是透過輪詢 (Round-Robin) 的方式進行分派,所以如果上一步沒有進行手動配置就要進一步的看 SQL Server 分配的情況,我們可以透過下列的二個 DMV 來進行查詢。

4-1 確認目前各 NUMA 節點的連線數配置。

select node_affinity,count(*) num from sys.dm_exec_connections
group by node_affinity


4-2 確認在排程上,load_factor 的值是否有異動,通常如果有排程的話,此值會因為排序的關係 值會減少,所以你可以持續查詢確認此值會不斷的變化。

select load_factor, * from sys.dm_os_schedulers

where status = 'VISIBLE ONLINE'

4-3 透過 4-1 的值可以看到,二個節點在分配的數量上,會差一點,這是因為連線時的工作可能有很快就執行完,有的要執行很久,所以基於上述的確認,可以看到還是有輪詢分派,另外平行處理的部份,也可能會影響單邊跑的情況過久,進一步的資訊,也可以透過下列的查詢,看有那些連線執行過久。


select node_affinity,* from sys.dm_exec_connections


4-4 如果需要查詢 Session ID 執行的語法為何,也可以透過下列的語法進行查詢。


select wait_type, * from sys.dm_exec_requests

where session_id > 50


5. 透過上述的方式,可以確認分配的情況,但另一方面,也有可能因為效能問題造成壓力集中在 NUMA 節點 0上,此部份可以參考我的另一篇文章進行收集與確認。

如何進行 SQL Server 效能資料收集與分析 - 以 LogScout, PSSDiag, SQL Nexus 工具為例https://caryhsu.blogspot.com/2023/12/sql-server-logscout-pssdiag-sql-nexus.html
How It Works: Soft NUMA, I/O Completion Thread, Lazy Writer Workers and Memory Nodes
https://techcommunity.microsoft.com/t5/sql-server-support-blog/how-it-works-soft-numa-i-o-completion-thread-lazy-writer-workers/ba-p/316044


經過上述的檢查,最後確認客戶的問題主要在於效能問題上,所以進一步的透過 LogScount 收集並再分析提供給客戶,但基於上述的資訊,可以完整的證明分配的情況,當然如果真的有調整過 Affinity 的相關設定值,也確認一下是否真的有調整的需要,或是也可以開案件給 Microsoft Support 進行討論與確認。