はじめに
オンプレミスからクラウドにシフトしつつある中、クラウドしか触ったことのないエンジニアも多いと思います。しかし、クラウドと言っても結局は物理サーバ上で仮想化機能を用いてサーバを動かしているだけです。ここで、性能を考慮すると看過することができないものがあります。それがNUMAという概念です。
この記事では、初めにNUMAノードについて簡単に説明した後、NUMAノードを確認するためのコマンド、vNUMAの解説、そしてvNUMAをVMに対してどのように設定するのかを解説します。また、NUMAノードに関わる設定についても例を踏まえながら紹介させていただきたいと思います。
NUMAノードについて
NUMAとは詳しくはNUMAアーキテクチャのことを指します。NUMA(Non-Uniform Memory Access)とは、プロセッサとメモリの組み合わせ(=ノード)がinterconnectと呼ばれるバスで接続された構成のことを言います。こうすることで、旧来のSMP(Symmetric Multiple Processor)と呼ばれるアーキテクチャの弱点を克服したものです。
引用:https://rinchan1968.wordpress.com/2012/12/24/numa%E3%81%AE%E9%81%B8%E6%8A%9E/
仮想マシンを作成する場合、可能な限りこのNUMAノードの中で収まるようにします。具体的には、1CPUに物理CPUが16コア、そのCPUのメモリコントローラーがローカルにアクセスすることができるメモリが128GBの場合は、vCPUの最大数は16、メモリは128GB以内に収めます(ハイパースレッディング無効化の場合)。
ただし、CPUのソケットが2つあり、同じスペックのCPU、メモリを搭載している場合、CPUのコア数は16を超過すること、メモリについては128GBを超過することも可能です。
ただし、interconnectと呼ばれるバスを経由してメモリにアクセスする可能性があるため、パフォーマンスの点では望ましくはありません。
次からは、NUMAノードに関するコマンドを紹介します。
numactl –hardware
わかること
物理サーバのNUMAノードの数と各々のNUMAノードに割り当てられるCPU番号がわかります。
出力例
available: 2 nodes (0-1) node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 node 0 size: xxx MB node 0 free: xxx MB node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 node 1 size: xxx MB node 1 free: xxx MB node distances: node 0 1 0: 10 21 1: 21 10
解説
出力例では
①NUMAノードが2つあること(available: 2 nodes (0-1)からわかります)
②物理CPUが2つあること(node 0 とnode 1があることからわかります)
③物理コア数は各々16個であること(赤文字からわかります)
④ハイパースレッディングが有効化されていること(青文字からわかります)
を確認することができます。
ここで、CPUの番号について補足します。
CPUの番号は若版から物理コア、ハイパースレッディングによる仮想コアとなります。
そのため、CPUのコア数がハイパースレッディング分含めて64個ある場合は
・0-63の合計64個のCPUコアが存在し
・0-31は物理CPU
・32-63はハイパースレッディングによる仮想コア
を意味します。
出力例を改めてみると、NUMAノード0は物理CPUとして0-15、ハイパースレッディングによる仮想コアとして32-47が割り当てられていることが確認できます。
numactl –show
わかること
このコマンドを投入したLinuxサーバの現在のNUMAノードのリソース割り当てステータスを確認することが可能です。NUMAノードとして0と1があり、特定のVMには0のみを使用させたい場合などはnodebindなどの値が0になります。詳しくは解説しませんが、cpuind、nodebind、membindの値は変更可能です。
出力例
preferred node: current physcpubind: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 cpubind: 0 1 nodebind: 0 1 membind: 0 1
numastat
わかること
NUMAノードの構成、NUMAノードを跨ったリソースの配置状況、interleaveを経由したメモリアクセスの有無(とデータ量)を確認することが可能です。
出力例
node0 node1 numa_hit 9420232004 4063219421 numa_miss 0 28397295 numa_foreign 28397295 0 interleave_hit 35904 36149 local_node 9420170597 4063043624 other_node 61404 28573092
virsh vcpuinfo 仮想マシンの名前
わかること
対象の仮想マシンのvCPUがサーバのどのCPUにスケジューリングされているかわかります。また、CPUの状態、CPUの使用時間、CPUアフィニティについてもわかります。
出力例
VCPU: 0 CPU: 41 State: running CPU time: 111111.1s CPU Affinity: yyyyyyyyyyyyyyyy----------------yyyyyyyyyyyyyyyy----------------
※実際はvCPUの数だけ出力されます。
numastat qemu-kvm
わかること
qemu上でエミュレーターされている仮想マシンは全てプロセスIDで区別されます。
このコマンドでは、仮想マシン毎にどのNUMAノードでどれくらいのメモリを使用しているのかわかります。
出力例
Per-node process memory usage (in MBs) PID Node 0 Node 1 Total ------------------ --------------- --------------- --------------- 1111 (qemu-kvm) 65581.35 1.59 65582.95 2222 (qemu-kvm) 22685.86 1938.52 24624.38 3333 (qemu-kvm) 18.05 16408.66 16426.72 4444 (qemu-kvm) 6176.27 2054.08 8230.35 5555 (qemu-kvm) 31722.44 1092.93 32815.37 ------------------ --------------- --------------- --------------- Total 126183.97 21495.79 147679.76
vNUMAとは
vNUMAとは、物理サーバのNUMAノードの構成を仮想マシンに認識させる技術です。何も設定を入れない場合、仮想マシンのOS,ミドルウェア,アプリケーションは割当てられたCPUとメモリは1つのNUMAノードにあるものと思って動作します。しかし、vNUMAの設定を投入すると、OS,ミドルウェア,アプリケーションがNUMAノードの構成を認識することが可能となり、NUMAアーキテクチャに準じた適切なコンピューターリソースの使用を可能とします。
ただし、あくまでも「認識させるだけ」であり、OS,ミドルウェア,アプリケーションが対応しているかは別となります。各製品の公式ドキュメントからサポート対象かどうか、サポート対象となる場合はどういった設定をすればvNUMAを有効にすることが可能か、確認するようにしましょう。
NUTANIXにおけるvNUMAの様々な設定
通常、VMを作成する場合はCLIで下記コマンドを使用します。
・新規作成の場合
nutanix@CVM$ acli vm.create <VMname> num_vcpus=<X> num_cores_per_vcpu=<X> memory=<X>G
・更新の場合
nutanix@CVM$ acli vm.update <VMname> num_vcpus=<X> num_cores_per_vcpu=<X> memory=<X>G
これらのコマンドの引数として、以下の4つを設定することが可能です。
num_vnuma_nodes=<0-4>
・vNUMAノードの数を指定します。
・NUMAノードの構成を仮想マシンに認識させるコマンドとなります。
・同じNUMAノードからCPUとメモリの両方を使用することを保証します。
・NUMAノードが2つある場合は、2をパラメータとして設定します。
extra_flags=numa_pinning=<0/1>
・vCPUとメモリを1つのNUMAノードに固定します。
・1 or 2つのソケットを使用するホストのみ有効となります。
・他のノードに移動しても必ず指定したNUMAノードに固定されます。
・CVMのNUMAノードとの重複は避けてください。つまり、CVMのNUMAノードが0の場合は、NUMAノード1を使用します(2ソケットの場合CVMが1つのNUMAノードに固定されています)。
num_threads_per_core=<number_of_thread>
・通常は、AHVがCPUコアを制御するので、仮想マシンのアプリケーションはCPUがリアル(物理)なのか、ハイパースレッディングによるものか気にしません。
・このコマンドはコア当たりのスレッド数を定義することが可能です。
・アプリケーションが物理CPUかハイパースレッディングによるコアなのか認識できる場合に有効です(例:SAP)。
vcpu_hard_pin=<true | false>
・このオプションで引数を指定した仮想マシンは、物理コアのみを使用するようになります。extra_flags=numa_pinningと併用する場合は、CVMのNUMAノードと重複することはできません。
・num_threads_per_core=<number_of_thread>と併用した場合は、ハイパースレッディングによるコアも使用するようになります。
・SAP HANAをデプロイする場合を除き、使用する場合はNunitaxnのサポートに問い合わせをするよう指示があります。
・NUMAノードのCPUの物理コア数とメモリを超過するVMを作成することは禁止です。
原文(英語)
This flag pins the VM to a given socket and the first physical cores (dependent on the configured vCPU in the VM) and should be used very carefully. If the VM is configured for example with 4 vCPUs (or 1 vCPU with 4 cores) the first 4 x physical cores will be pinned to this VM. By default, the Linux Scheduler in AHV will schedule all cores wherever they are best available. This flag ensures they are pinned on either CPU1 or CPU2 (randomly when hosting the VM). While the VM stays on this CPU, we cannot define which CPU. This flag should be used only for one User VM per node as it pins cores to the same physical cores. On top it should be made sure to give this User VM close to the max of a single NUMA node’s memory, so we won’t start this VM on the same NUMA node as the CVM. If this VM runs on the same NUMA node as the CVM both the CVM and UVM potentially see high scheduling contention. The same is true for multiple User VMs on the opposite NUMA node to the node where the CVM is pinned.
コマンドの実行例
前提
CPUソケットが2つ、物理コア数16、ハイパースレッディング有効化、メモリが1つのNUMAノードにつき128GB(つまり合計で256GB)を搭載したサーバで、①物理コアのみを使用させたい、②NUMAノードは1を使用させたい(0はCVMで使用している場合など)を実現させたいとします。vCPU数は16コア、メモリは128GB未満に収まるものとします。
コマンド
acli vm.update "VMのUUID" num_vcpus=1 num_cores_per_vcpu=16 memory=96G extra_flags=numa_pinning=1 num_vnuma_nodes=1 vcpu_hard_pin=true
補足事項
・電源OFFしていないと設定変更できません。CVMからacli vm.off “UUID”で可能です。
・投入後、問題なければ電源をオンにできます。acli vm.on “UUID”で可能です。
・電源投入成功後、CVMからhostssh “virsh list –title”で対象ゲストVMのドメインIDを検索します。VMが稼働しているAHVにログインし、virsh vcpuinfo “ドメインID”を実行します。CPUが意図したNUMAノードの物理CPUに紐づいているか確認します。
・NUMAノード毎のCPUの配置はnumactl –hardwareで確認できます。
・extra_flags=numa_pinning=1でNUMAノード1を使用させる場合、num_vnuma_nodes=0で投入すると、仮想マシンのvCPUはNUMAノード0の物理コアを使用するもののメモリはNUMAノード1のものを使用します。つまり、意図的にinterconnectを経由させることが可能です。検証用途で使えます。実際の運用ではやめてください。
参考サイト
コメント