以前 Windows Azure 仮想マシンで NUMA 構成の環境が利用できます という投稿を書いたのですが、Azure VM ではインスタンスによって複数の NUMA ノードを持つ環境を使用することができます。
XL の場合は以下のような NUMA ノードの構成となっています。
XL の場合の構成は
となっています。
CPU としては NUMA ノードは 2 ノードの構成となり、各 NUMA ノードに対して CPU を 4 コア認識しています。
メモリノードも 2 ノードの構成となり、各メモリノードで 7GB ずつ認識が行われています。
SQL Server は NUMA の構成を意識して稼働するようになっています。
そのため、SSMS からも NUMA ノードを確認することができます。
SQL Server 2012 では SQL Server 向けのメモリ関係のパフォーマンスカウンターが追加されており、
で各メモリノードでどのようにメモリが使用されているかを確認することができます。
今回は max server memory を 12GB に設定しているのですが、その 12 GB を ノード 0 で 7 GB、ノード 1 で 5GB のサイズで確保していることを Total Node Memory から確認をすることができます。
この状態で大量のアドホッククエリをキャッシュするために以下のようなクエリを実行してみます。
SET NOCOUNT ON GO DECLARE @sql nvarchar(max) DECLARE @i int = 1000 DECLARE @cd int WHILE (@i <= 3900) BEGIN SET @cd = 65 WHILE (@cd <= 400) BEGIN SET @sql = N'DECLARE @tmp nvarchar(max);' SET @sql += N'SELECT @tmp = N''' + REPLICATE(NCHAR(@cd), @i) + N'''' SET @sql += N' FROM sys.objects' EXEC (@sql) SET @cd += 1 END SET @i += 1 END
実行しているとアドホッククエリによりプランキャッシュが肥大化していくのですが、途中でキャッシュの上限に達し以下のような状態となります。
今回は 2.7GB 程度はプランをキャッシュしているのですが、各セッションが接続されているメモリノード (node_affinity) に応じたメモリでプランキャッシュが消費されているようです。
# プランキャッシュはノード 0 から必ず消費するかと思っていたのですがそうでもないんですね。
似たようなことを和牛 (A7) で実施してみるとこのような形になります。
プランキャッシュの上限の計算式に当てはめると、56GB の場合は 8GB ぐらいはキャッシュできそうな気がするのですが、6GB 程度で止まっています。
ノード 0 のメモリサイズを基準に考えるとこの程度でいいのかなと思うのですが、この辺の動作がまだきちんと理解できていないのですよね。
NUMA のメモリアクセス状況についてはトレースフラグ 842 (TF842) と sys.dm_os_memory_node_access_stats を使用すると確認することができるのですが、XL / A7 のインスタンスを使用するとこの辺の検証をも可能です。
DBCC TRACEON(842, -1) select * from sys.dm_os_memory_node_access_stats
Sysinternals の coreinfo では NUMA ノードの CPU アクセスのコストも見れますので、NUMA 構成の場合は、Coreinfo でどういう情報が取得可能かということも検証できます。
AzureVM は分課金で停止中の課金が発生しないようになっていますので、使用していないときは停止しておけば無償分の中でもいろいろな検証が可能だと思います。
NUMA 構成のハードウェアを検証用に用意するのはなかなか厳しいですが、Azure VM ですと手軽に検証ができますので、SQL Server の動作を確認したい場合などに結構便利かと。