NUMAノードが1つずつある4つのソケットを備えたSQL Serverがあるとします。各ソケットには4つの物理コアがあります。合計512 GBのメモリがあるため、各NUMAノードには128 GBのRAMがあります。
キーテーブルが最初のNUMAノードに読み込まれます。
そのテーブルから多くのトラフィックを読み取っているとしましょう。 NUMAノードを所有するソケットのすべての物理コアのCPU使用率が100%である場合、他のソケットからの非ローカルNUMAアクセスのコストに悪影響がありますか?または、その一方で、非ローカルNUMAアクセスのコストは、そのソケットのビジー状態に関係なくですか?
私の質問が理にかなっているといいのですが。わからない場合はお知らせください。
先週、本番サーバーでデータベースの問題が発生し、処理したビジネスの一部が他のビジネスよりも影響を受けているように見えました。 1分以上かかる論理的な読み取りが少ないクエリがありました。全体のCPU使用率を調べたところ、約60%でした。ソケット固有のCPUメトリックは調べませんでした。 I/Oメトリックは平均でした。
多額の質問:-)関係する要因のいくつかを概説します。どのような状況でも、これらの要因やその他の要因は変化し、興味深い結果を生み出します。
申し訳ありませんが、これをもっと短くすることはできませんでした...
累積CPUミリ秒と論理IO
ワークロードのCPU効率を測定し、スピンロックが発生しやすいケースを探すために、CPU使用率に対する論理IO(またはperfmon用語では「バッファープールページルックアップ」)のグラフを頻繁に使用します。
しかし、SQL Serverはページルックアップとスピンロック以外の多くのアクティビティでCPU時間を累積します。
他の多くのアクティビティは、ページのルックアップに反映されずにかなりのCPU時間を消費します。
私が観察するワークロードでは、これらの「非論理IO集中的ですが、CPUの混乱)アクティビティの主なものは、ソート/ハッシュアクティビティです。
それは理にかなっています:非クラスター化インデックスのないハッシュテーブルに対する2つのクエリの不自然な例を考えてください。 2つのクエリは同じ結果セットを持っていますが、結果セットの1つは完全に順序付けられておらず、2番目の結果セットは選択された複数の列によって順序付けされています。 2番目のクエリは、バッファプール内の同じ数のページを参照する場合でも、より多くのCPU時間を消費すると予想されます。
ワークスペースのメモリの詳細と、許可されたワークスペースの使用量については、以下の投稿をご覧ください。
SQL Serverの論理メモリノードと物理NUMAノードの位置合わせ
SQL Server(NUMA対応の戦略が組み込まれているため)は、デフォルトでサーバー上の各NUMAノードに対してSQLOSメモリノードを作成します。メモリ割り当てが増えると、各割り当てはSQLOSメモリノードの1つによって制御されます。
理想的には、SQLOSメモリノードは物理的なNUMAノードと完全に揃っています。つまり、各SQLOSメモリノードには単一のNUMAノードからのメモリが含まれ、他のSQLOSメモリノードには同じNUMAノードからのメモリも含まれていません。
ただし、その理想的な状況が常に当てはまるわけではありません。
次のCSS SQL Server Engineersブログの投稿(Kinの応答にも含まれています)は、SQLOSメモリノードのNUMAノード間メモリ割り当ての永続化につながる可能性がある動作を詳しく説明しています。これが発生すると、パフォーマンスへの影響が壊滅的になる可能性があります。
永続的なクロスNUMAノード参照の特に痛いケースに対していくつかの修正が行われました。おそらくこれら2つに加えて他のものも同様です。
ワークスペースメモリの割り当て中のスピンロックの競合
ここからが楽しくなります。ワークスペースメモリでの並べ替えとハッシュの作業はCPUを消費しますが、bpoolルックアップ数には反映されないことを既に説明しました。
スピンロック競合は、この特定の楽しみの別の層です。バッファプールからメモリが盗まれ、クエリメモリ許可に対して使用するために割り当てられると、メモリアクセスはスピンロックでシリアル化されます。デフォルトでは、これはNUMAノードレベルでリソースがパーティション分割されて行われます。したがって、ワークスペースメモリを使用する同じNUMAノードでのすべてのクエリは、メモリを許可に対して盗むときに、スピンロックの競合を経験する可能性があります。注意が非常に重要です。これは、実際の付与時に競合ポイントがあった場合と同様に、「クエリごとに1回」の競合リスクではありません。むしろ、メモリが許可に対して盗まれた場合-非常に大きなメモリ許可を持つクエリは、許可の大部分を使用する場合、スピンロック競合の機会が多くなります。
トレースフラグ8048は、コアレベルでリソースをさらにパーティション分割することにより、この競合を解消する優れた機能を果たします。
Microsoftは、「ソケットあたり8コア以上の場合は、トレースフラグ8048を検討する」と述べています。しかし...それは、実際にはソケットあたりのコアの数(複数ある場合)ではなく、単一のNUMAノードで実行されている作業で競合が発生する機会の数です。
接着されたAMDプロセッサ(ソケットあたり12コア、ソケットあたり2 NUMAノード)では、NUMAノードあたり6コアがありました。トレースフラグ8048が有効になるまで、スピンロックコンボイで詰まったCPUが4つ(NUMAノードが8つ、それぞれが6つのコア)のシステムを見ました。
このスピンロックの競合が、わずか4 vCPUのVMでパフォーマンスを引き下げるのを見てきました。トレースフラグ8048は、これらのシステムで有効にされたときに想定されていたものを実行しました。
4コアの周波数に最適化されたCPUがまだ適切にあり、適切なワークロードがあることを考えると、トレースフラグ8048も役立ちます。
CMEMTHREAD待機は、トレースフラグ8048が緩和するタイプのスピンロック競合に付随します。ただし、注意が必要です。CMEMTHREADの待機は、この特定の問題の根本的な原因ではなく、裏付けとなる症状です。累積CMEMTHREAD待機時間がかなり短いため、トレースフラグ8048や9024が展開で遅延した、CMEMTHREADの「待機開始」が高いシステムを確認しました。スピンロックでは、累積待機時間は通常は見た目が間違っています。むしろ、無駄なCPU時間を調べたいと思います。これは主にスピン自体によって表され、次に、潜在的に不要なコンテキストスイッチを表す関連する待機によって表されます。
スケジューラへのタスク割り当て
NUMAシステムでは、特定のNUMAノードに関連付けられている接続エンドポイントがないと想定して、接続はNUMAノード(まあ-実際には、関連付けられているSQLOSスケジューラグループに割り当てられます)ラウンドロビンに分散されます。セッションが並列クエリを実行する場合、単一のNUMAノードからワーカーを使用することを強くお勧めします。うーん... 4つのパスに分割された複雑なクエリを備えた4つのNUMAノードサーバーと、デフォルトで0のMAXDOPを考えます。クエリがMAXDOPワーカースレッドのみを使用した場合でも、NUMAノードの論理CPUごとに4つのワーカースレッドが存在します。しかし、複雑な計画には4つのパスがあります。つまり、NUMAノードの各論理CPUは、16のワーカーをその上に持つことができます。すべて1つのクエリに対してです。
そのため、NUMAノードの1つがハードに機能し、他のノードがローフしている場合があります。
タスクの割り当てには他にもいくつかのニュアンスがあります。ただし、主な留意点は、CPUビジーがNUMAノード全体に必ずしも均等に分散されるわけではないということです。 (bpoolページの挿入(読み取りまたはfirst-page-writes)は、ワーカーがオンになっているスケジューラに関連付けられているSQLOSメモリノードのbpoolに移動することも理解してください。盗まれたページは、「ローカル」SQLOSメモリから優先的に取得されます。ノードも。
Maxdopを0から8以下にすると効果的であることがわかりました。ワークロードプロファイルに応じて(主に、予想される長時間実行される可能性のあるクエリの同時実行数がimoの場合)、MAXDOP = 2に到達することが保証される場合があります。
並列処理のコストしきい値を調整することも役立つ場合があります。私が取り組んでいるシステムは、高コストのクエリで消費される傾向があり、50または100未満のプランに遭遇することはめったにないため、maxdop(ワークロードグループレベルで10倍)を調整することで、コストのしきい値を調整するよりも多くの注目を集めました。
この投稿では、ワークスペースのメモリに関するスピンロック競合と不均一なタスク分散の組み合わせについて説明します。見てください-これらは実際にすべて一緒に織り合わせています:-)
40の同時SQL Server並列クエリ+(2ソケット*ソケットあたり10コア スピンロックコンボイ)==
bpoolでの関連データの配置
これが、NUMAサーバーを扱うときに最も直感的にわかる条件です。また、最も一般的には、ワークロードのパフォーマンスにとってそれほど重要ではありません。
テーブルがNUMAノード3のbpoolに読み込まれ、後でNUMAノード4のクエリがテーブルをスキャンして、NUMAノード全体ですべてのbpoolルックアップを実行するとどうなりますか?
Linchi Sheaがこのパフォーマンスへの影響について素晴らしい記事を書いています:
NUMAノード間でメモリにアクセスすると、追加のメモリ遅延が少し発生します。最適なパフォーマンスのために追加のベースメモリレイテンシを排除する必要のあるワークロードがいくつかあると確信しています-これは、私が使用するシステムでは問題ではありませんでした。
しかし-クロスノードアクセスは、飽和する可能性のある別の転送ポイントももたらします。 NUMAノード間のメモリ帯域幅が飽和するほどアクティビティが多い場合、ノード間のメモリレイテンシが増加します。同じ作業には追加のCPUサイクルが必要になります。
繰り返しますが、メモリ帯域幅が重要な考慮事項であるようなワークロードがあると確信しています。ただし、私のシステムでは、ここに挙げた他の考慮事項の方が重要でした。
物理メモリの配置
これはまれですが、重要な場合は本当に重要です。ほとんどのサーバーでは、メモリのインストールは、ほぼ自然にNUMAノード間で分散されます。ただし、場合によっては、ノード間でメモリのバランスをとるために特別な注意が必要です。一部のシステムのパフォーマンスは、メモリがバランスが取れていない方法でスロット化された場合、完全に破壊される可能性があります。ただし、これは設定して忘れてしまいます。最初の本当に忙しい一日の後とは対照的に、数ヶ月の生産サービスの後にこのような問題を発見するのはかなりまれです:-)
誰かが、おそらく統計が古くなっているためにプランの選択が不十分であると、あなたが見た症状を引き起こす可能性があると主張しました。私の経験ではそうではありませんでした。不十分な計画では、クエリが予想よりも長くかかる場合がありますが、通常、必要以上の論理I/Oが実行されているためです。またはtempdbへの流出が原因です。 tempdbへの大量の流出は、サーバーを監視するときに明らかになるはずです。CPU使用率が高いのではなく、流出に関連するディスク書き込みの測定可能な待機時間が予想されます。
代わりに、あなたが観察した状況がNUMAに関連している場合、私はそれが上記に列挙した要因の組み合わせであると予想します。
ワークスペースメモリの使用(論理IOカウントには表示されません)
これは、永続的な外部メモリ状態が原因でNUMAをまたがるノードである可能性があります(この場合は、関連する修正を探してください)
また、割り当てに対して割り当てが行われるたびに、NUMAノード内でスピンロックの競合が発生する可能性があります(T8048で修正)。
他の並列クエリワーカーによって過負荷になった論理CPU上のワーカーによって実行される可能性があります(必要に応じてmaxdopや並列処理のコストしきい値を調整します)
(coreinfo -v
(sysinternalユーティリティ)の出力で質問を更新して、CPU /ソケットとNUMAディストリビューションのより良いコンテキストを取得してください)
全体のCPU使用率を調べたところ、約60%でした。ソケット固有のCPUメトリックは調べませんでした。 I/Oメトリックは平均でした。
あなたが間違った木を吠えているように私には思えます。 SQL ServerはNUMA
対応です。 クロスNUMAメモリアクセスを実行すると、パフォーマンスが大幅に低下する があります。このクエリを使用して、所有しているNUMA
ノードの数と、どのNUMA
に割り当てられているCPUとコアを確認することもできます。
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分以上かかる論理的な読み取りが少ないクエリがありました。
これは通常、古い統計のために生成された不良クエリプランがある場合に発生します。 統計が更新され、インデックスが適切に最適化されている であることを確認してください。
また、 MAXDOPをより適切な値に設定する を ワーカースレッドの不足を回避する にする必要があります。
cost threshold of parallelism
をデフォルトの5から45などの適切な開始値に設定し、その値を監視して、環境に応じて調整します。
多数のアドホッククエリを実行している場合は、プランキャッシュの肥大化を防ぐためにoptimize for ad hoc workloads
をオン(1に設定)にします。
注意して使用してください:8以上の新しいマシンでSQL Server 2008/2008 R2を実行している場合、 T8048 を使用できます。 NUMAごとに提示されるCPU Nodeおよび SQL Server 2012または2014を使用している場合は修正プログラム があります。
データベースサーバーインスタンスに関する待機統計情報の収集を開始することを強くお勧めします。
純粋にハードウェアの観点から、Nehalemアーキテクチャ以降のメインメモリの管理は、統合メモリコントローラによる管理です。これは、実際のコアが存在する部分とは別のCPUダイの「アンコア」部分にあります。メモリは各CPUに効果的に「有線」で接続されているため、外部メモリアクセスAFAIKは高速パス相互接続(Nehalem以降)を介して行われるため、ローカルNUMAノードのCPUコアの飽和はそのメモリへのリモートアクセスに影響を与えないはずです。
あなたはこのリンクが役に立つかもしれません:
http://cs.nyu.edu/~lerner/spring10/projects/NUMA.pdf
クリス