仮想化のチューニングと最適化ガイド
仮想環境を最適化する
概要
第1章 はじめに
1.1. KVM のパフォーマンスについて
- KVM を使用する場合、ゲストはホスト上の Linux プロセスとして実行されます。
- 仮想 CPU (vCPU) は通常のスレッドとして実装され、Linux スケジューラーで処理されます。
- ゲストは NUMA や huge page などの機能をカーネルから継承します。
- ホスト内でのディスクおよびネットワーク I/O の設定はパフォーマンスに多大な影響を与えます。
- ネットワークトラフィックは一般的にはソフトウェアベースのブリッジを通過します。
1.2. 仮想化のパフォーマンス関連の特長および改善点
Red Hat Enterprise Linux 7 における仮想化パフォーマンスの改善点
- NUMA の自動負荷分散
- NUMA の自動負荷分散により、Red Hat Enterprise Linux 7 ゲストで必要な手動のチューニングなしに、NUMA ハードウェアシステムで実行されるアプリケーションのパフォーマンスを強化できます。NUMA の自動負荷分散は、スレッドやプロセスなどのタスクを、それらがアクセスするメモリーに近い場所に移動します。NUMA の自動負荷分散に関する詳細は、「NUMA の自動負荷分散」を参照してください。
- マルチキュー virtio-net
- パケットの送信/受信処理の規模をゲストの利用可能な vCPU の数に合わせて調整できるようにするネットワーク手法です。マルチキュー virtio-net についての詳細は、「マルチキュー virtio-net」を参照してください。
- ブリッジのゼロコピー送信
- ゼロコピー送信モードは、ゲストネットワークと外部ネットワーク間での大規模なパケットを送信する際のホスト CPU のオーバーヘッドを、スループットに影響を与えることなく最高 15% 削減します。ブリッジのゼロコピー送信は Red Hat Enterprise Linux 7 仮想マシンで完全にサポートされていますが、デフォルトでは無効にされています。ゼロコピー送信についての詳細は、「ブリッジのゼロコピー送信」を参照してください。
- APIC Virtualization (APICv)
- 新たな Intel プロセッサーは Advanced Programmable Interrupt Controller (APICv) のハードウェア仮想化機能を提供します。APICv により、ゲストの直接的な APIC アクセスが許可され、APIC による割り込みの待機時間や仮想マシンの終了回数が大幅に削減されるため、仮想化された AMD64 および Intel 64 ゲストのパフォーマンスが強化されます。この機能は新規の Intel プロセッサーでデフォルトで使用され、I/O パフォーマンスを向上させます。
- EOI の加速化
- 仮想 APIC 機能なしに、旧式チップセットの高帯域幅 I/O の割り込み終了 (EOI: End-of-interrupt) 処理を加速化します。
- マルチキュー virtio-scsi
- virtio-scsi ドライバーのマルチキュー対応により、ストレージのパフォーマンスとスケーラビリティーが強化されます。これにより、他の vCPU に影響を与えることなく、それぞれの仮想 CPU で別個のキューや割り込みを使用できます。マルチキュー virtio-scsi についての詳細は、「マルチキュー virtio-scsi」を参照してください。
- 準仮想化された Ticketlock
- 準仮想化された ticketlock (pvticketlock) は、オーバーサブスクライブされた CPU を持つ Red Hat Enterprise Linux 7 ホスト上で実行される Red Hat Enterprise Linux 7 ゲスト仮想マシンのパフォーマンスを強化します。
- 準仮想化されたページフォールト
- 準仮想化されたページフォールトは、ゲストがホストによってスワップアウトされるページへのアクセスを試行する際にゲストに挿入されます。これにより、ホストのメモリーがオーバーコミットされ、ゲストのメモリーがスワップアウトされる場合に KVM ゲストのパフォーマンスが向上します。
- 準仮想化された時刻関連の
vsyscallの最適化 gettimeofdayおよびclock_gettimeシステム呼び出しをvsyscallメカニズムによりユーザー領域で実行できます。以前は、これらのシステム呼び出しを実行すると、システムをカーネルモードに切り替えてからユーザー領域に戻す必要がありました。これにより、一部のアプリケーションのパフォーマンスが大幅に向上します。
Red Hat Enterprise Linux における仮想化パフォーマンスの機能
- CPU/カーネル
- NUMA: Non-Uniform Memory Access (非均一なメモリーアクセス)。詳細は「9章NUMA」を参照してください。
- CFS: Completely Fair Scheduler (完全に公平なスケジューラー)。クラスに焦点を置いた新しいスケジューラーです。
- RCU: Read Copy Update (リードコピーアップデート)。共有スレッドデータの処理が向上しました。
- 仮想 CPU (vCPU) の最大数は 160 になります。
- メモリー
- Huge Page およびメモリー集約型環境での各種の最適化。詳細は「8章メモリー」を参照してください。
- ネットワーク
- vhost-net: カーネルベースの高速 virtIO ソリューション
- SR-IOV: ネイティブに近いネットワークパフォーマンスレベルを実現するために導入
- ブロック I/O
- AIO: 他の I/O 動作にオーバーラップするスレッドのサポート
- MSI: PCI バスデバイスの割り込み生成
- ディスク I/O スロットリング: ゲストのディスク I/O 要求を制御し、ホストリソースの過剰使用を防ぎます。詳細は、「ディスク I/O スロットリング」を参照してください。
注記
第2章 パフォーマンス監視ツール
2.1. perf kvm
perf コマンドに kvm オプションを付けて使用します。perf パッケージは perf コマンドを提供します。これは、以下のコマンドを実行してインストールできます。
# yum install perf
perf kvm を使用するには、ゲストの /proc/modules ファイルと /proc/kallsyms ファイルにアクセスできなければなりません。ホストにファイルを転送してからそのファイルでレポートを実行するには、以下の手順 (手順2.1「ゲストの /proc ファイルをホストにコピーする」) を参照してください。
手順2.1 ゲストの /proc ファイルをホストにコピーする
重要
scp などを使用)、コピーしたファイルは空になります。本セクションでは、まず、ゲストのファイルを一時的な場所に保存し (cat コマンドを使用)、その保存先からファイルをホストにコピーして、perf kvm で使用する手順を説明しています。
ゲストにログインしてファイルを保存する
ゲストにログインして、/proc/modulesと/proc/kallsymsを一時的な場所の/tmpに保存します。# cat /proc/modules > /tmp/modules # cat /proc/kallsyms > /tmp/kallsyms
一時ファイルをホストにコピーする
ゲストからログオフしたら、今度は次の例に示すscpコマンドを実行して一時的な場所に保存したファイルをホストにコピーします。必要に応じてホスト名と TCP ポートをご使用の値に置き換えてください。# scp root@GuestMachine:/tmp/kallsyms guest-kallsyms # scp root@GuestMachine:/tmp/modules guest-modules
これでゲストからの 2 つのファイル (guest-kallsymsとguest-modules) がホスト上にコピーされ、perf kvmで使用する準備が整いました。perf kvm でイベントの記録とレポートを実行する
前述の手順で入手したファイルを使って、ゲスト内のイベント、ホスト内のイベントのいずれかまたは両方を記録し、レポートできるようになりました。次のコマンドの例を実行します。# perf kvm --host --guest --guestkallsyms=guest-kallsyms \ --guestmodules=guest-modules record -a -o perf.data
注記
--host と --guest の両方をコマンドに使用すると、出力はperf.data.kvmというファイル名で保存されます。--host だけを使用すると、ファイル名はperf.data.hostになります。同じように、--guest のみを使用すると、そのファイル名はperf.data.guestになります。記録の動作を停止させる場合は Ctrl-C を押します。イベントをレポートする
記録のプロセスで取得したファイルを使って出力を新しいファイル「analyze」にリダイレクトする例を示します。perf kvm --host --guest --guestmodules=guest-modules report -i perf.data.kvm \ --force > analyze
記録したイベントを調べるため、analyzeファイルの内容を表示します。# cat analyze# Events: 7K cycles # # Overhead Command Shared Object Symbol # ........ ............ ................. ......................... # 95.06% vi vi [.] 0x48287 0.61% init [kernel.kallsyms] [k] intel_idle 0.36% vi libc-2.12.so [.] _wordcopy_fwd_aligned 0.32% vi libc-2.12.so [.] __strlen_sse42 0.14% swapper [kernel.kallsyms] [k] intel_idle 0.13% init [kernel.kallsyms] [k] uhci_irq 0.11% perf [kernel.kallsyms] [k] generic_exec_single 0.11% init [kernel.kallsyms] [k] tg_shares_up 0.10% qemu-kvm [kernel.kallsyms] [k] tg_shares_up [output truncated...]
2.2. 仮想パフォーマンスの監視ユニット (vPMU: Virtual Performance Monitoring Unit)
arch_perfmon フラグをチェックします。
# cat /proc/cpuinfo|grep arch_perfmoncpu mode を host-passthrough として指定します。
# virsh dumpxml guest_name |grep "cpu mode"
<cpu mode='host-passthrough'>perf コマンドを実行して仮想マシンのパフォーマンス統計を表示します。
2.3. 仮想マシンマネージャーでのパフォーマンス監視
2.3.1. 仮想マシンマネージャーでのパフォーマンス概要の表示
- 仮想マシンマネージャーのメインウィンドウで表示する仮想マシンを強調表示します。

図2.1 表示する仮想マシンの選択
- 仮想マシンマネージャーの 編集 メニューから 仮想マシンの詳細 を選択します。仮想マシンの詳細ウィンドウを開く時にコンソールが表示される場合があります。その場合には、表示 をクリックしてから 詳細 を選択します。デフォルトでは最初に 概要 ウィンドウが開きます。
- 左側のナビゲーションペインから 性能 (Performance) を選択します。性能 (Performance) ビューでは、CPU およびメモリーの使用率ならびにディスクおよびネットワークの I/O など、ゲストのパフォーマンスに関する要約が表示されます。

図2.2 ゲストのパフォーマンス詳細の表示
2.3.2. パフォーマンスの監視
virt-manager の設定ウィンドウで修正することができます。
- 編集 メニューから 設定 を選択します。設定 ウィンドウが表示されます。
- ポーリング タブで、秒単位の時間または統計ポーリングオプションを指定します。

図2.3 パフォーマンス監視の設定
2.3.3. ゲストの CPU 使用率の表示
- 表示 メニューから グラフ に続いて 仮想マシン CPU 使用率 (Guest CPU Usage) のチェックボックスを選択します。
- 仮想マシンマネージャーがシステム上の全仮想マシンの CPU 使用率グラフを表示します。

図2.4 ゲストの CPU 使用率グラフ
2.3.4. ホストの CPU 使用率の表示
- 表示 メニューから グラフ に続いて ホスト CPU 使用率 (Host CPU Usage) のチェックボックスを選択します。
- 仮想マシンマネージャーがシステム上のホストの CPU 使用率グラフを表示します。

図2.5 ホストの CPU 使用率グラフ
2.3.5. ディスク I/O の表示
- ディスク I/O の統計値収集の設定が有効になっていることを確認します。編集 メニューから 設定 を選択し、ポーリング タブをクリックします。
- ディスク I/O の取得 のチェックボックスを選択します。

図2.6 ディスク I/O の有効化
- ディスク I/O の表示を有効にするには、表示 メニューから グラフ に続いて ディスク I/O のチェックボックスを選択します。
- 仮想マシンマネージャーがシステム上の全仮想マシンのディスク I/O のグラフを表示します。

図2.7 ディスク I/O の表示
2.3.6. ネットワーク I/O の表示
- ネットワーク I/O の統計値収集の設定が有効になっていることを確認します。これを実行するには、編集 メニューから 設定 を選択し、ポーリング タブをクリックします。
- ネットワーク I/O の取得 (Poll Network I/O) のチェックボックスを選択します。

図2.8 ネットワーク I/O の有効化
- ネットワーク I/O の統計値を表示するには、表示 メニューから グラフ に続いて ネットワーク I/O のチェックボックスを選択します。
- 仮想マシンマネージャーがシステム上の全仮想マシンのネットワーク I/O のグラフを表示します。

図2.9 ネットワーク I/O の表示
2.3.7. メモリー使用率の表示
- ネットワーク I/O の統計値収集の設定が有効になっていることを確認します。編集 メニューから 設定 を選択し、ポーリング タブをクリックします。
- メモリーの統計を取得する (Poll Memory stats) チェックボックスを選択します。

図2.10 メモリー使用率の有効化
- メモリー使用率を表示するには、表示 メニューから グラフ に続いて メモリーの使用率 チェックボックスを選択します。
- 仮想マシンマネージャーがシステム上のすべての仮想マシンについてのメモリー使用率 (メガバイト単位) を一覧表示します。

図2.11 メモリー使用率の表示
第3章 virt-manager を使用した仮想化パフォーマンスの最適化
3.1. オペレーティングシステムの詳細とデバイス
3.1.1. ゲスト仮想マシンの詳細の指定

図3.1 OS の種類とバージョンを指定する
3.1.2. 未使用のデバイスの削除

図3.2 未使用のデバイスを削除する
3.2. CPU パフォーマンスのオプション

図3.3 CPU パフォーマンスのオプション
3.2.1. オプション: 使用できる CPU

図3.4 CPU のオーバーコミット
重要
3.2.2. オプション: CPU 構成

図3.5 CPU 構成のオプション
注記
注記
virsh capabilities コマンドを実行し、CPU タイプおよび NUMA 機能を含むシステムの仮想化機能を表示します。
3.2.3. オプション: CPU トポロジー

図3.6 CPU トポロジーのオプション
注記
3.3. 仮想ディスクパフォーマンスのオプション

図3.7 仮想ディスクパフォーマンスのオプション
重要
第4章 tuned と tuned-adm
virtual-guestthroughput-performanceプロファイルに基づき、virtual-guestは仮想メモリーの スワップアウト処理頻度も軽減します。virtual-guestプロファイルは Red Hat Enterprise Linux 7 ゲスト仮想マシンを作成する際に自動的に選択されます。これは仮想マシンに推奨されるプロファイルです。このプロファイルは Red Hat Enterprise Linux 6.3 以降で利用できますが、仮想マシンのインストール時に手動で選択する必要があります。virtual-hostthroughput-performanceプロファイルに基づき、virtual-hostも仮想メモリーのスワップアウト処理頻度を減らし、ダーティーページのより集中的なライトバックを可能にします。このプロファイルは、KVM および Red Hat Virtualization (RHV) ホストの両方を含む仮想化ホストのプロファイルとして推奨されます。
tuned サービスが有効にされます。
# tuned-adm list
Available profiles:
- balanced
- desktop
- latency-performance
- network-latency
- network-throughput
- powersave
- sap
- throughput-performance
- virtual-guest
- virtual-host
Current active profile: throughput-performancetuned.conf man ページを参照してください。
tuned-adm activetuned-adm profile profile_namevirtual-host プロファイルに切り替えるには、以下を実行します。
tuned-adm profile virtual-host重要
tuned-adm off注記
第5章 ネットワーク
5.1. ネットワークチューニングのヒント
- 単一ネットワークでのトラフィック混雑を避けるため複数のネットワークを使用します。たとえば、管理専用のネットワーク、バックアップ専用のネットワーク、ライブマイグレーション専用のネットワークなどを設けます。
- Red Hat では、同じネットワークセグメントで複数のインターフェースを使用しないことを推奨しています。
arp_filterを使用することで ARP 変動を防ぐことができます。ARP 変動はホストおよびゲストのいずれでも発生する可能性のある望ましくない状況で、マシンが複数のネットワークインターフェースから ARP 要求に応答してしまう原因となります。この設定を永続化するには、echo 1 > /proc/sys/net/ipv4/conf/all/arp_filterを実行するか、または/etc/sysctl.confを編集してください。
注記
5.2. Virtio と vhost_net

図5.1 Virtio および vhost_net アーキテクチャー
5.3. デバイスの割り当てと SR-IOV

図5.2 デバイスの割り当てと SR-IOV
5.4. ネットワークチューニングのヒント
重要
5.4.1. ブリッジのゼロコピー送信
experimental_zcopytx カーネルモジュールパラメーターを 1 に設定します。
注記
experimental_zcopytx を 0 に設定することでゼロコピー送信モードを無効にできます。
5.4.2. マルチキュー virtio-net
- トラフィックパケットのサイズが比較的大きい。
- ゲスト間、ゲストとホスト間、またはゲストと外部システム間でトラフィックが実行されている状態で、ゲストが多くの接続で同時にアクティブである。
- キューの数は vCPU の数に等しい。これは、特定のキューを特定の vCPU に対してプライベートにするため、マルチキューサポートが RX 割り込みの親和性および TX キュー選択を最適化するためです。
注記
5.4.2.1. マルチキュー virtio-net の設定
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
<driver name='vhost' queues='N'/>
</interface># ethtool -L eth0 combined M注記
/etc/libvirt/qemu.conf ファイルの max_files 変数を 2048 に変更することが推奨されます。デフォルト制限の 1024 ではマルチキューには不十分であり、マルチキューの設定時にゲストが起動できなくなります。
5.5. ネットワークパケットのバッチ処理
# ethtool -C $tap rx-frames Ntun/tap の rx バッチ処理をサポートするには、ドメイン XML ファイルに以下のようなスニペットを追加します。
...
<devices>
<interface type='network'>
<source network='default'/>
<target dev='vnet0'/>
<coalesce>
<rx>
<frames max='7'/>
</rx>
</coalesce>
</interface>
</devices>
第6章 I/O スケジューリング
6.1. I/O スケジューリング
6.2. Red Hat Enterprise Linux を仮想化ホストとして使用する場合の I/O スケジューリング
cfq スケジューラーが理想的です。このスケジューラーは、ほとんどすべての負荷に対して適切に機能します。
deadline スケジューラーの使用によりメリットが得られることがあります。チューニングされたプロファイル virtual-host でも、deadline スケジューラーが使用されます。
6.3. Red Hat Enterprise Linux を仮想化ゲストとして使用する場合の I/O スケジューリング
- Red Hat Enterprise Linux ゲストでは、通常
noopスケジューラーにより大きなメリットが得られます。このnoopスケジューラーにより、ホストマシンまたはスーパーバイザーは I/O 要求を最適化することができます。noopスケジューラーでは、ゲストオペレーティングシステムからの個々の I/O 要求を 1 つの大きな要求にまとめてから、ハイパーバイザーに I/O 要求を渡すことができます。ただし、noopは最小限のゲスト CPU サイクル数により I/O スケジューリングを実施しようとします。ホスト/ハイパーバイザーは全ゲストからの要求の全体像を把握し、異なる手段を使用して I/O 処理を行います。注記
Red Hat Enterprise Linux 7.2 およびそれ以降のバージョンでは、virtio-blkは必ずnoopを使用します。これは、blk-mqが使用されるためです。 - 負荷の I/O およびストレージデバイスのマウント状況によっては、
deadline等のスケジューラーの方が有効な場合があります。最も有効なスケジューラーを把握するには、パフォーマンステストが必要です。 - iSCSI、SR-IOV、または物理デバイスのパススルーによりストレージにアクセスするゲストの場合は、
noopスケジューラーを使用するべきではありません。これらの手段では、ホストはベースとなる物理デバイスに対する I/O 要求を最適化することができません。
注記
deadline 等のスケジューラーを使用することで、メリットが得られる場合もあります。
6.4. I/O スケジューラーの設定
6.4.1. Red Hat Enterprise Linux 5 および 6 における I/O スケジューラーの設定
elevator カーネルパラメーターを使用して起動時に選択することができます。
grub.conf スタンザの例では、システムは noop スケジューラーを使用するように設定されます。この例は VMware ESX のケースです。
title Red Hat Enterprise Linux Server (2.6.18-8.el5) root (hd0,0) kernel /vmlinuz-2.6.18-8.el5 ro root=/dev/vg0/lv0 elevator=noop initrd /initrd-2.6.18-8.el5.img
6.4.2. Red Hat Enterprise Linux 7 における I/O スケジューラーの設定
/etc/grub2.cfg に追加して、I/O スケジューラーの変更を起動後も維持することができます。
# vi /etc/grub2.cfg
linux16 /vmlinuz-kernel-version root=/dev/mapper/vg0-lv0 ro rd.lvm.lv=vg0/lv0 vconsole.keymap=us vconsole.font=latarcyrheb-sun16 rhgb quiet elevator=deadline
initrd16 /initramfs-kernel-version.img
第7章 ブロック I/O
7.1. ブロック I/O チューニング
virsh blkiotune コマンドを使うと、管理者はゲスト仮想マシンのブロック I/O パラメーターをゲスト XML 設定の <blkio> 要素に手動で設定したり、表示したりすることができます。
<blkio> パラメーターを表示するには、以下を実行します。
# virsh blkiotune virtual_machine
<blkio> パラメーターを設定するには、以下のコマンドを参照し、ご使用の環境に応じて値を置き換えます。
# virsh blkiotune virtual_machine [--weight number] [--device-weights string] [--config] [--live] [--current]weight- I/O ウェイト値 (100 から 1000 の範囲内)。
device-weights形式で 1 つ以上の device/weight のペアを一覧表示する単一文字列です。それぞれのウェイトは 100-1000 の範囲内にあるか、またはデバイスごとの一覧からデバイスを削除するには値は 0 である必要があります。文字列に一覧表示されているデバイスのみが変更されます。他のデバイスの既存のデバイスごとのウェイトは変更されません。/path/to/device,weight,/path/to/device,weightconfig- 次回の起動時に変更を有効にするには、
オプションを追加します。--config live- 実行中の仮想マシンに変更を適用するには、
オプションを追加します。--live注記
オプションは、ハイパーバイザーがこのアクションをサポートするように要求します。すべてのハイパーバイザーがメモリー上限のライブの変更を許可する訳ではありません。--live current- 変更を現在の仮想マシンに適用するには、
オプションを追加します。--current
注記
virsh blkiotune コマンド使用の詳細については、virsh help blkiotune コマンドを使用してください。
7.2. キャッシュ
表7.1 キャッシュオプション
| キャッシュオプション | 説明 |
|---|---|
| Cache=none | ゲストからの I/O はホストではキャッシュされませんが、ライトバックディスクキャッシュに保持することができます。大規模な I/O 要件のあるゲストにはこのオプションを使用します。一般的に、このオプションは移行に対応する最適で唯一のオプションとなります。 |
| Cache=writethrough | ゲストからの I/O はホストにはキャッシュされ、物理的な媒体に書き込むことができます。このモードを使用すると速度の低下が生じ、ゲスト数の規模が一定以上になると問題が発生する傾向にあります。I/O 要求が低い少数のゲストへの使用に適しています。ゲスト移行の必要性がなく、ライトバックキャッシュに対応していないゲストに推奨されるモードです(Red Hat Enterprise Linux 5.5 以前)。 |
| Cache=writeback | ゲストからの I/O がホストでキャッシュされます。 |
| Cache=directsync | writethrough と似ていますが、ゲストからの I/O はホストページのキャッシュをバイパスします。 |
| Cache=unsafe | ホストはすべてのディスク I/O をキャッシュする可能性がありますが、ゲストからの同期要求は無視されます。 |
| Cache=default | キャッシュモードが指定されない場合、システムのデフォルト設定が選択されます。 |
driver タグ内で cache 設定を編集し、キャッシュオプションを指定します。たとえば、キャッシュを writeback として設定するには、以下を実行します。
<disk type='file' device='disk'>
<driver name='qemu' type='raw' cache='writeback'/>
7.3. I/O モード
表7.2 I/O モードのオプション
| I/O モードのオプション | 説明 |
|---|---|
| IO=native | Red Hat Virtualization (RHV) 環境のデフォルトです。このモードは直接 I/O オプションが設定されたカーネルの非同期 I/O を参照します。 |
| IO=threads | デフォルトは、ホストユーザーモードベースのスレッドです。 |
| IO=default | Red Hat Enterprise Linux 7 におけるデフォルトはスレッドモードです。 |
driver タグ内で io 設定を編集し、native、threads、または default を指定します。たとえば、I/O モードを threads に設定するには、以下を実行します。
<disk type='file' device='disk'>
<driver name='qemu' type='raw' io='threads'/>
7.4. ブロック I/O のチューニング方法
7.4.1. ディスク I/O スロットリング
virsh blkdeviotune コマンドを使用して仮想マシンの I/O 制限を設定します。以下の例を参照してください。
# virsh blkdeviotune virtual_machine device --parameter limit
<target dev='name'/>) またはソースファイル (<source file='name'/>) を指定します。ディスクデバイス名の一覧については、virsh domblklist コマンドを使用します。
total-bytes-sec- 秒あたりのバイト単位の合計スループット制限
read-bytes-sec- 秒あたりのバイト単位の読み込みスループット制限
write-bytes-sec- 秒あたりのバイト単位の書き込みスループット制限
total-iops-sec- 秒あたりの合計 I/O 回数の制限
read-iops-sec- 秒あたりの読み込み I/O 回数の制限
write-iops-sec- 秒あたりの書き込み I/O 回数の制限
virtual_machine 上の vda を 1 秒あたり 1000 I/O 操作および 1 秒あたり 50 MB スループットにスロットリングするには、以下のコマンドを実行します。
# virsh blkdeviotune virtual_machine vda --total-iops-sec 1000 --total-bytes-sec 52428800
7.4.2. マルチキュー virtio-scsi
7.4.2.1. マルチキュー virtio-scsi の設定
<controller type='scsi' index='0' model='virtio-scsi'>
<driver queues='N' />
</controller>第8章 メモリー
8.1. メモリーチューニングのヒント
- 使用する量よりも多くのリソースをゲストに割り当てない。
- (可能な場合) リソースが NUMA ノードに十分にある場合はゲストを単一の NUMA ノードに割り当てます。NUMA の使用についての詳細は、「9章NUMA」を参照してください。
8.2. 仮想マシン上でのメモリーチューニング
8.2.1. メモリー監視ツール
topvmstatnumastat/proc/
注記
8.2.2. virsh を使用したメモリーチューニング
<memtune> 要素により、管理者はゲスト仮想マシンのメモリー設定を手動で設定することができます。<memtune> が省略される場合、デフォルトのメモリー設定が適用されます。
virsh memtune コマンドを使って、仮想マシン内の <memtune> 要素にメモリーパラメーターを表示または設定します。ご使用の環境に応じて値を置き換えます。
# virsh memtune virtual_machine --parameter size
hard_limit- 仮想マシンが使用できる最大メモリーです。この値はキビバイト (1024 バイトのブロック) で表されます。
警告
この値の設定が低すぎると、仮想マシンがカーネルによって kill される可能性があります。 soft_limit- これは、メモリー競合中に強制するメモリーの制限です。この値はキビバイト (1024 バイトのブロック) で表されます。
swap_hard_limit- これは、仮想マシンが使用できる最大メモリーに swap を足したものです。この値はキビバイト (1024 バイトのブロック) で表されます。
swap_hard_limitの値はhard_limit値よりも大きくなければなりません。 min_guarantee- これは、仮想マシンへの割り当てを保証できる最小メモリーです。この値はキビバイト (1024 バイトのブロック) で表されます。
注記
virsh memtune コマンドの使用方法についての詳細は、# virsh help memtune を参照してください。
<memoryBacking> 要素には、仮想メモリーページがホストページで保護される方法に影響を与えるいくつかの要素が含まれる場合があります。
locked を設定すると、ホストがゲストに属するメモリーページをスワップアウトすることを回避します。ホストのメモリーで仮想メモリーページをロックするには、以下をゲスト XML に追加します。
<memoryBacking>
<locked/>
</memoryBacking>重要
locked を設定する際、<memtune> 要素の hard_limit には、ゲストに設定された最大メモリーにプロセス自体で消費されたメモリーを足したものを設定する必要があります。
nosharepages を設定すると、ホストがゲスト間で使用される同じメモリーをマージすることを避けられます。ハイパーバイザーに対してゲストの共有ページを無効にするよう指示するには、以下をゲストの XML に追加します。
<memoryBacking>
<nosharepages/>
</memoryBacking>8.2.3. Huge Page および Transparent Huge Page (THP)
8.2.3.1. Transparent Huge Page の設定
# cat /sys/kernel/mm/transparent_hugepage/enabled
# echo always > /sys/kernel/mm/transparent_hugepage/enabled
これにより、/sys/kernel/mm/transparent_hugepage/enabled が always に設定されます。
# echo never > /sys/kernel/mm/transparent_hugepage/enabled8.2.3.2. 静的 Huge Page の設定
virsh edit を使用してゲスト XML 設定に以下を追加します。
<memoryBacking>
<hugepages/>
</memoryBacking><memoryBacking> 要素に huge page サイズ、ユニット、およびゲスト NUMA ノードセットを指定します。詳細情報および設定例については、「ホストの Huge Page の複数のゲスト NUMA ノードへの割り当て」を参照してください。
cat /proc/sys/vm/nr_hugepages
手順8.1 huge page の設定
- 現在の huge page の値を確認します。
# cat /proc/meminfo | grep HugeAnonHugePages: 2048 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB - Huge page は 2MB 単位で設定されます。huge page の数を 25000 に設定するには、以下のコマンドを使用します。
echo 25000 > /proc/sys/vm/nr_hugepages注記
設定を永続化するには、以下の行をゲストマシンの/etc/sysctl.confファイルに追加します。ここで、X を Huge Page の数値に置き換えます。# echo 'vm.nr_hugepages = X' >> /etc/sysctl.conf # sysctl -p
次に、transparent_hugepage=neverをゲストの/etc/grub2.cfgファイル内の/kernel行の末尾に追加することで、これをカーネル起動パラメーターに追加します。 - huge page をマウントします。
# mount -t hugetlbfs hugetlbfs /dev/hugepages - libvirtd を再起動してから、以下のコマンドを使って仮想マシンを再起動します。
# systemctl start libvirtd# virsh start virtual_machine /proc/meminfoの変更を検証します。# cat /proc/meminfo | grep HugeAnonHugePages: 0 kB HugePages_Total: 25000 HugePages_Free: 23425 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
8.2.3.3. 起動時またはランタイム時におけるゲストの 1 GB Huge Page の有効化
手順8.2 起動時の 1 GB Huge Page の割り当て
- 起動時に Huge Page の異なるサイズを割り当てるには、Huge Page の数を指定して以下のコマンドを使用します。この例では、4 1 GB の Huge Page と 1024 2 MB の Huge Page を割り当てます。
'default_hugepagesz=1G hugepagesz=1G hugepages=4 hugepagesz=2M hugepages=1024'
このコマンド行を変更して起動時に割り当てる Huge Page の異なる数を指定できます。注記
次の 2 つの手順も、初めて起動時に 1 GB の Huge Page を割り当てる際に実行する必要があります。 - ホストに 2 MB および 1 GB の Huge Page をマウントします。
# mkdir /dev/hugepages1G # mount -t hugetlbfs -o pagesize=1G none /dev/hugepages1G # mkdir /dev/hugepages2M # mount -t hugetlbfs -o pagesize=2M none /dev/hugepages2M
- ゲスト上で 1GB huge page の使用を有効にするために libvirtd を再起動します。
# systemctl restart libvirtd
手順8.3 ランタイム時の 1 GB Huge Page の割り当て
- ランタイム時に Huge Page の異なるサイズを割り当てるには、以下のコマンドを使用します。その際、Huge Page の数や、それらのページの割り当て元となる NUMA ノード、および Huge Page サイズの値を置き換えます。
# echo 4 > /sys/devices/system/node/node1/hugepages/hugepages-1048576kB/nr_hugepages # echo 1024 > /sys/devices/system/node/node3/hugepages/hugepages-2048kB/nr_hugepages
このサンプルコマンドにより、node1から 4.1 GB の Huge Page とnode3から 1024 2 MB の huge page が割り当てられます。上記のコマンドを使用すると、これらの huge page 設定をホストシステムの空きメモリーの量に応じていつでも変更できます。注記
次の 2 つの手順も、初めてランタイム時に 1 GB の Huge Page を割り当る際に実行する必要があります。 - ホストに 2 MB および 1 GB の Huge Page をマウントします。
# mkdir /dev/hugepages1G # mount -t hugetlbfs -o pagesize=1G none /dev/hugepages1G # mkdir /dev/hugepages2M # mount -t hugetlbfs -o pagesize=2M none /dev/hugepages2M
- ゲスト上で 1GB huge page の使用を有効にするために libvirtd を再起動します。
# systemctl restart libvirtd
注記
8.3. KSM (Kernel Same-page Merging)
qemu-kvm プロセスからのメモリーしか継承しません。同じオペレーティングシステムやアプリケーションを複数のゲストが実行している場合、ゲストの実行時にゲストのオペレーティングシステムイメージのコンテンツが共有されるようになります。KSM の機能によって KVM は同一ゲストのメモリー領域が共有されるよう要求することができるようになります。
注記
/sys/kernel/mm/ksm/merge_across_nodes 調整可能パラメーターを 0 に変更し、複数の NUMA ノード間でのページのマージを防ぎます。これは、virsh node-memory-tune --shm-merge-across-nodes 0 コマンドを使って実行できます。多量のノード間マージが実行されると、カーネルメモリーのアカウンティング統計は相反する結果となる可能性があります。そのため、numad も KSM デーモンが多量のメモリーをマージした後に混乱する可能性があります。システムに大量の空きメモリーがある場合、KSM デーモンをオフにし、無効にすることでパフォーマンスを向上させることができます。NUMA の詳細は、「9章NUMA」を参照してください。
重要
ksmサービス は、KSM カーネルスレッドの起動と停止を行います。ksmtunedサービス は、ksmサービスの制御と調整を行い、same-page merging を動的に管理します。ksmtunedはksmサービスを起動し、メモリー共有が必要ない場合にはksmサービスを停止します。新規のゲストが作成された場合またはゲストが破棄された場合には、retuneパラメーターでksmtunedに実行の指示を出さなければなりません。
注記
8.3.1. KSM サービス
ksmサービスは qemu-kvm パッケージに含まれています。ksmサービスを起動していない場合、Kernel same-page merging (KSM) により 2000 ページしか共有されません。このデフォルト値では、メモリー節約で得られる利点が限られます。ksmサービスを起動すると、KSM により最大でホストシステムのメインメモリーの 50% まで共有されるようになります。ksmサービスを起動して KSM がより多くのメモリーを共有できるようにしてください。
# systemctl start ksm
Starting ksm: [ OK ]ksm サービスをデフォルトのスタートアップ順序に追加することができます。systemctl コマンドを使って ksm サービスを永続化します。
# systemctl enable ksm
8.3.2. KSM チューニングサービス
ksmtuned サービスは、ksm をループおよび調整して kernel same-page merging (KSM) の設定を微調整します。また、ゲスト仮想マシンが作成または破棄された場合は、そのことが libvirt によって ksmtuned サービスに通知されます。ksmtuned サービスにオプションはありません。
# systemctl start ksmtuned
Starting ksmtuned: [ OK ]ksmtuned サービスは retune パラメーターを使って調整することができます。パラメーターの指示によって ksmtuned は手動によるチューニング機能を実行します。
/etc/ksmtuned.conf ファイルは ksmtuned サービスの設定ファイルになります。デフォルトの ksmtuned.conf ファイルの出力を以下に示します。
# Configuration file for ksmtuned. # How long ksmtuned should sleep between tuning adjustments # KSM_MONITOR_INTERVAL=60 # Millisecond sleep between ksm scans for 16Gb server. # Smaller servers sleep more, bigger sleep less. # KSM_SLEEP_MSEC=10 # KSM_NPAGES_BOOST - is added to the `npages` value, when `free memory` is less than `thres`. # KSM_NPAGES_BOOST=300 # KSM_NPAGES_DECAY - is the value given is subtracted to the `npages` value, when `free memory` is greater than `thres`. # KSM_NPAGES_DECAY=-50 # KSM_NPAGES_MIN - is the lower limit for the `npages` value. # KSM_NPAGES_MIN=64 # KSM_NPAGES_MAX - is the upper limit for the `npages` value. # KSM_NPAGES_MAX=1250 # KSM_THRES_COEF - is the RAM percentage to be calculated in parameter `thres`. # KSM_THRES_COEF=20 # KSM_THRES_CONST - If this is a low memory system, and the `thres` value is less than `KSM_THRES_CONST`, then reset `thres` value to `KSM_THRES_CONST` value. # KSM_THRES_CONST=2048 # uncomment the following to enable ksmtuned debug information # LOGFILE=/var/log/ksmtuned # DEBUG=1
/etc/ksmtuned.conf ファイルの npages により、ksmd デーモンが非アクティブになるまでに ksm がスキャンするページ数が設定されます。この値は、/sys/kernel/mm/ksm/pages_to_scan ファイルでも設定されます。
KSM_THRES_CONST の値は、ksm をアクティブ化する際のしきい値として使われる、利用可能なメモリー容量を表します。以下のいずれかの状況になった場合に、ksmd がアクティブ化されます。
- 空きメモリー容量が
KSM_THRES_CONSTで設定されたしきい値を下回った場合 - コミットしたメモリー容量と
KSM_THRES_CONSTのしきい値の合計が、総メモリー容量を超えた場合
8.3.3. KSM の変数とモニタリング
/sys/kernel/mm/ksm/ ディレクトリーに格納します。このディレクトリー内のファイルはカーネルによって更新されるため、KSM の使用状況と統計値の正確な記録となります。
/etc/ksmtuned.conf ファイルでも設定可能です。
/sys/kernel/mm/ksm/ に含まれるファイル:
- full_scans
- 実行された完全スキャン数
- merge_across_nodes
- 異なる NUMA ノードからページをマージできるかどうかを指定します。
- 共有されたページの合計数
- pages_sharing
- 現在共有されているページ数
- pages_to_scan
- スキャンされなかったページ数
- 共有されなくなったページ数
- pages_volatile
- 揮発性のページ数
- run
- KSM プロセスが実行しているかどうか
- sleep_millisecs
- スリープのミリ秒数
virsh node-memory-tune コマンドを使用して手動で調整できます。たとえば、共有メモリーサービスがスリープ状態になる前にスキャンするページの数を指定します。
# virsh node-memory-tune --shm-pages-to-scan number
/etc/ksmtuned.conf ファイルに DEBUG=1 の行を追加すると、KSM チューニングのアクティビティーが /var/log/ksmtuned ログファイルに格納されます。LOGFILE パラメーターを使用するとログファイルの場所を変更することができます。ただし、ログファイルの場所の変更は、SELinux 設定に特殊な構成を必要とする場合があるためお勧めできません。
8.3.4. KSM の非アクティブ化
ksmtuned と ksm サービスを停止して、KSM を非アクティブ化することができます。ただし、再起動後は元に戻ります。KSM を非アクティブ化するには、ターミナルから root として以下のコマンドを実行します。
# systemctl stop ksmtuned Stopping ksmtuned: [ OK ] # systemctl stop ksm Stopping ksm: [ OK ]
ksmtuned と ksm を停止すると KSM は非アクティブ化されますが、再起動後は元に戻ります。KSM を完全に非アクティブ化するには、systemctl コマンドを使用します。
# systemctl disable ksm
# systemctl disable ksmtuned# echo 2 >/sys/kernel/mm/ksm/run
khugepaged デーモンは KVM ゲストの物理メモリーに Transparent Hugepage を再ビルドできます。# echo 0 >/sys/kernel/mm/ksm/run を使用すると、KSM は停止しますが、以前に作成されたすべての KSM ページは共有されたままです (これは # systemctl stop ksmtuned コマンドと同じです)。
第9章 NUMA
9.1. NUMA メモリー割り当てのポリシー
Strict- Strict ポリシーでは、目的のノードでメモリーを割り当てられない場合は割り当てに失敗することになります。メモリーモード属性を定義せずに NUMA ノードセットのリストを指定すると、デフォルトで
strictモードが選択されます。 Interleave- メモリーページはノードセットで指定されたノード全体に割り当てられますが、割り当てはラウンドロビン方式で行われます。
Preferred- 単一の優先メモリーノードからのみメモリーの割り当てが行われます。十分なメモリーが使用できない場合には、他のノードからメモリーを割り当てることができます。
<memory mode> 要素の値にそのポリシーを設定します。
<numatune>
<memory mode='preferred' nodeset='0'>
</numatune>重要
strict モードにおいてメモリーがオーバーコミットされ、ゲストに十分な Swap 領域がない場合、カーネルはゲストのプロセスの一部を強制終了して追加のメモリーを取得します。この状況を回避するために、Red Hat では preferred ポリシーによる割り当てを使用し、単一のノードセットを指定する (例: nodeset=「0」) ことを推奨します。
9.2. NUMA の自動負荷分散
- Periodic NUMA unmapping of process memory (プロセスメモリーの定期的な NUMA マッピング解除)
- NUMA hinting fault (NUMA ヒンティングフォールト)
- Migrate-on-Fault (MoF) - メモリーを使用するプログラムが実行される場所にメモリーを移動します。
- task_numa_placement - 実行中のプログラムをそれらのメモリーの近くに移動します。
9.2.1. NUMA の自動負荷分散の設定
# numactl --hardwareは複数のノードを表示します。# cat /sys/kernel/debug/sched_featuresにより、フラグにNUMAが表示されます。
# echo 0 > /proc/sys/kernel/numa_balancing# echo 1 > /proc/sys/kernel/numa_balancing9.3. libvirt の NUMA チューニング
numastat ツールを使用して、プロセスおよびオペレーティングシステムの NUMA ノードごとのメモリー統計を表示します。
numastat ツールは、複数の NUMA ノード間のメモリー配置が最適ではない 4 つの仮想マシンを示しています。
# numastat -c qemu-kvm
Per-node process memory usage (in MBs)
PID Node 0 Node 1 Node 2 Node 3 Node 4 Node 5 Node 6 Node 7 Total
--------------- ------ ------ ------ ------ ------ ------ ------ ------ -----
51722 (qemu-kvm) 68 16 357 6936 2 3 147 598 8128
51747 (qemu-kvm) 245 11 5 18 5172 2532 1 92 8076
53736 (qemu-kvm) 62 432 1661 506 4851 136 22 445 8116
53773 (qemu-kvm) 1393 3 1 2 12 0 0 6702 8114
--------------- ------ ------ ------ ------ ------ ------ ------ ------ -----
Total 1769 463 2024 7462 10037 2672 169 7837 32434
numad を実行して、ゲストの CPU とメモリーリソースを自動的に調整します。
numastat -c qemu-kvm を再び実行して実行中の numad の結果を表示します。以下の出力は、リソースが調整されていることを示しています。
# numastat -c qemu-kvm
Per-node process memory usage (in MBs)
PID Node 0 Node 1 Node 2 Node 3 Node 4 Node 5 Node 6 Node 7 Total
--------------- ------ ------ ------ ------ ------ ------ ------ ------ -----
51747 (qemu-kvm) 0 0 7 0 8072 0 1 0 8080
53736 (qemu-kvm) 0 0 7 0 0 0 8113 0 8120
53773 (qemu-kvm) 0 0 7 0 0 0 1 8110 8118
59065 (qemu-kvm) 0 0 8050 0 0 0 0 0 8051
--------------- ------ ------ ------ ------ ------ ------ ------ ------ -----
Total 0 0 8072 0 8072 0 8114 8110 32368
注記
-c を指定して numastat を実行することにより、簡易出力が表示されます。-m オプションを追加することにより、システム全体でのメモリー情報のノード別の内訳が出力に追加されます。詳細は、numastat の man ページを参照してください。
9.3.1. ホスト NUMA ノードごとのメモリー監視
nodestats.py スクリプトを使用して、ホスト上の各 NUMA ノードの合計メモリーと空きメモリーを報告できます。また、このスクリプトは実行中の各ドメインの特定のホストノードに対して厳密にバインドされているメモリーの量をレポートします。以下は例になります。
# /usr/share/doc/libvirt-python-2.0.0/examples/nodestats.py
NUMA stats
NUMA nodes: 0 1 2 3
MemTotal: 3950 3967 3937 3943
MemFree: 66 56 42 41
Domain 'rhel7-0':
Overall memory: 1536 MiB
Domain 'rhel7-1':
Overall memory: 2048 MiB
Domain 'rhel6':
Overall memory: 1024 MiB nodes 0-1
Node 0: 1024 MiB nodes 0-1
Domain 'rhel7-2':
Overall memory: 4096 MiB nodes 0-3
Node 0: 1024 MiB nodes 0
Node 1: 1024 MiB nodes 1
Node 2: 1024 MiB nodes 2
Node 3: 1024 MiB nodes 3MemTotal) が含まれる 4 つのホスト NUMA ノードを示しています。ほぼすべてのメモリーが各ドメインで消費されています (MemFree)。4 つのドメイン (仮想マシン) が実行されています。ドメイン 'rhel7-0' には、特定のホスト NUMA ノードにピニングされていない 1.5GB メモリーがあります。ドメイン 'rhel7-2' には 4GB メモリーがあり、4 つの NUMA ノードはホストノードに 1:1 でピニングされています。
nodestats.py スクリプトを作成します。サンプルスクリプトは、/usr/share/doc/libvirt-python-version/examples/nodestats.py の libvirt-python パッケージファイルにあります。rpl -ql libvirt-python コマンドを使用して、スクリプトへの実際のパスを表示することができます。
9.3.2. NUMA の vCPU ピニング
注記
numatune と組み合わせることにより、NUMA ミスが回避されます。NUMA ミスによるパフォーマンスへの影響は大きく、通常はパフォーマンスが 10% 以上低下します。vCPU ピニングと numatune は一緒に設定する必要があります。
注記
重要
<vcpu cpuset='0-7'>8</vcpu>
<cputune>
<vcpupin vcpu='0' cpuset='0'/>
<vcpupin vcpu='1' cpuset='1'/>
<vcpupin vcpu='2' cpuset='2'/>
<vcpupin vcpu='3' cpuset='3'/>
<vcpupin vcpu='4' cpuset='4'/>
<vcpupin vcpu='5' cpuset='5'/>
<vcpupin vcpu='6' cpuset='6'/>
<vcpupin vcpu='7' cpuset='7'/>
</cputune><vcpupin> がないことを示しています。したがって、vCPU5 は親タグの <vcpu> で指定しているように物理 CPU の 0 から 7 に固定される可能性があります。
<vcpu cpuset='0-7'>8</vcpu>
<cputune>
<vcpupin vcpu='0' cpuset='0'/>
<vcpupin vcpu='1' cpuset='1'/>
<vcpupin vcpu='2' cpuset='2'/>
<vcpupin vcpu='3' cpuset='3'/>
<vcpupin vcpu='4' cpuset='4'/>
<vcpupin vcpu='6' cpuset='6'/>
<vcpupin vcpu='7' cpuset='7'/>
</cputune>重要
<vcpupin>、<numatune>、および <emulatorpin> を共に設定する必要があります。<numatune> タグの詳細は、「ドメインプロセス」を参照してください。<emulatorpin> タグの詳細は、「emulatorpin の使用」を参照してください。
9.3.3. ドメインプロセス
<numatune> タグ内にこれらを設定する方法は、以下の XML 設定例を参照してください。
<numatune>
<memory mode='strict' placement='auto'/>
</numatune>
<numatune>
<memory mode='strict' nodeset='0,2-3'/>
</numatune><vcpu> タグ内にこれらを設定する方法については、以下の XML 設定例を参照してください。
<vcpu placement='auto'>8</vcpu>
<vcpu placement='static' cpuset='0-10,ˆ5'>8</vcpu>
<vcpu> および <numatune> に使用する配置モード間には暗黙的な継承ルールがあります。
<numatune>の配置モードは<vcpu>と同じ配置モードにデフォルト設定されます。または、<nodeset>を指定した場合はstatic に設定されます。- 同様に、
<vcpu>の配置モードでは<numatune>と同じ配置モードにデフォルト設定されます。または、<cpuset>を指定した場合は static に設定されます。
<vcpu placement='auto' current='8'>32</vcpu>
注記
9.3.4. ドメインの vCPU スレッド
<cputune> タグ内に各 vcpu スレッドのピニングポリシーを設定します。
<cputune>
<vcpupin vcpu="0" cpuset="1-4,ˆ2"/>
<vcpupin vcpu="1" cpuset="0,1"/>
<vcpupin vcpu="2" cpuset="2,3"/>
<vcpupin vcpu="3" cpuset="0,4"/>
</cputune>注記
<cputune> の詳細は、以下の URL を参照してください: http://libvirt.org/formatdomain.html#elementsCPUTuning
4 available nodes (0-3) Node 0: CPUs 0 4, size 4000 MiB Node 1: CPUs 1 5, size 3999 MiB Node 2: CPUs 2 6, size 4001 MiB Node 3: CPUs 0 4, size 4005 MiB
<cputune> <vcpupin vcpu="0" cpuset="1"/> <vcpupin vcpu="1" cpuset="5"/> <vcpupin vcpu="2" cpuset="2"/> <vcpupin vcpu="3" cpuset="6"/> </cputune> <numatune> <memory mode="strict" nodeset="1-2"/> </numatune> <cpu> <numa> <cell id="0" cpus="0-1" memory="3" unit="GiB"/> <cell id="1" cpus="2-3" memory="3" unit="GiB"/> </numa> </cpu>
9.3.5. emulatorpin の使用
<cputune> 内で <emulatorpin> タグを使用する方法があります。
<emulatorpin> タグは、エミュレーター (vCPU を含まないドメインのサブセット) が固定されるホスト物理 CPU を指定します。<emulatorpin> タグは、エミュレーターのスレッドプロセスに正確な親和性 (アフィニティー) を設定する方法を提供します。結果として vhost スレッドは物理 CPU およびメモリーの同じサブセットで実行されるため、キャッシュの局所性 (ローカリティー) によるメリットがあります。たとえば、以下のようになります。
<cputune>
<emulatorpin cpuset="1-3"/>
</cputune>注記
<emulatorpin> を手動で調整する必要性を軽減します。NUMA の自動負荷分散についての詳細は、「NUMA の自動負荷分散」を参照してください。
9.3.6. virsh による vCPU ピニングのチューニング
重要
virsh コマンドの例では、ID が 1 となる vcpu スレッド rhel7 を物理 CPU 2 に固定します。
% virsh vcpupin rhel7 1 2
virsh コマンドで 現在の vcpu ピニング設定を取得することもできます。以下は例になります。
% virsh vcpupin rhel7
9.3.7. virsh を使用したドメインプロセスの CPU ピニングのチューニング
重要
emulatorpin オプションでは、各ドメインプロセスに関連付けられたスレッドに CPU アフィニティーの設定を適用します。詳細のピニングを実行するには、virsh vcpupin (前述) と virsh emulatorpin の両方を各ゲストに使用する必要があります。例を示します。
% virsh emulatorpin rhel7 3-4
9.3.8. virsh を使用したドメインプロセスのメモリーポリシーのチューニング
% virsh numatune rhel7 --nodeset 0-10
virsh の man ページを参照してください。
9.3.9. ゲスト NUMA トポロジー
<cpu> タグ内にある <numa> タグを使って指定できます。以下の例を参照し、値を適宜置き換えてください。
<cpu>
...
<numa>
<cell cpus='0-3' memory='512000'/>
<cell cpus='4-7' memory='512000'/>
</numa>
...
</cpu><cell> 要素は NUMA セルまたは NUMA ノードを指定します。cpus は、ノードの一部である CPU または CPU の範囲を指定します。memory はノードメモリーをキビバイト単位で指定します (1024 バイトのブロック)。それぞれのセルまたはノードには、0 から始まる昇順で cellid または nodeid が割り当てられます。
重要
9.3.10. ホストの Huge Page の複数のゲスト NUMA ノードへの割り当て
<memoryBacking> 要素に huge page サイズおよびゲスト NUMA ノードセットを指定します。page size および unit はホストからの huge page のサイズを参照します。nodeset は huge page が割り当てられるゲスト NUMA ノード (またはいくつかのノード) を指定します。
<memoryBacking>
<hugepages/>
<page size="1" unit="G" nodeset="0-3,5"/>
<page size="2" unit="M" nodeset="4"/>
</hugepages>
</memoryBacking>注記
strict メモリーノードを使用する場合、NUMA ノードに利用可能な huge page が十分にない場合はゲストが起動に失敗します。<numatune> 内の strict メモリーモードオプションの設定例については、「ドメインプロセス」を参照してください。
9.3.11. PCI デバイスの NUMA ノードの局所性 (ローカリティー)
/sys/devices/pci*/*/numa_node の sysfs ファイルに表示されます。これらの設定を検証する 1 つの方法は、lstopo ツールを使用して sysfs データをレポートする方法です。
# lstopo-no-graphics
Machine (126GB)
NUMANode L#0 (P#0 63GB)
Socket L#0 + L3 L#0 (20MB)
L2 L#0 (256KB) + L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0 + PU L#0 (P#0)
L2 L#1 (256KB) + L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1 + PU L#1 (P#2)
L2 L#2 (256KB) + L1d L#2 (32KB) + L1i L#2 (32KB) + Core L#2 + PU L#2 (P#4)
L2 L#3 (256KB) + L1d L#3 (32KB) + L1i L#3 (32KB) + Core L#3 + PU L#3 (P#6)
L2 L#4 (256KB) + L1d L#4 (32KB) + L1i L#4 (32KB) + Core L#4 + PU L#4 (P#8)
L2 L#5 (256KB) + L1d L#5 (32KB) + L1i L#5 (32KB) + Core L#5 + PU L#5 (P#10)
L2 L#6 (256KB) + L1d L#6 (32KB) + L1i L#6 (32KB) + Core L#6 + PU L#6 (P#12)
L2 L#7 (256KB) + L1d L#7 (32KB) + L1i L#7 (32KB) + Core L#7 + PU L#7 (P#14)
HostBridge L#0
PCIBridge
PCI 8086:1521
Net L#0 "em1"
PCI 8086:1521
Net L#1 "em2"
PCI 8086:1521
Net L#2 "em3"
PCI 8086:1521
Net L#3 "em4"
PCIBridge
PCI 1000:005b
Block L#4 "sda"
Block L#5 "sdb"
Block L#6 "sdc"
Block L#7 "sdd"
PCIBridge
PCI 8086:154d
Net L#8 "p3p1"
PCI 8086:154d
Net L#9 "p3p2"
PCIBridge
PCIBridge
PCIBridge
PCIBridge
PCI 102b:0534
GPU L#10 "card0"
GPU L#11 "controlD64"
PCI 8086:1d02
NUMANode L#1 (P#1 63GB)
Socket L#1 + L3 L#1 (20MB)
L2 L#8 (256KB) + L1d L#8 (32KB) + L1i L#8 (32KB) + Core L#8 + PU L#8 (P#1)
L2 L#9 (256KB) + L1d L#9 (32KB) + L1i L#9 (32KB) + Core L#9 + PU L#9 (P#3)
L2 L#10 (256KB) + L1d L#10 (32KB) + L1i L#10 (32KB) + Core L#10 + PU L#10 (P#5)
L2 L#11 (256KB) + L1d L#11 (32KB) + L1i L#11 (32KB) + Core L#11 + PU L#11 (P#7)
L2 L#12 (256KB) + L1d L#12 (32KB) + L1i L#12 (32KB) + Core L#12 + PU L#12 (P#9)
L2 L#13 (256KB) + L1d L#13 (32KB) + L1i L#13 (32KB) + Core L#13 + PU L#13 (P#11)
L2 L#14 (256KB) + L1d L#14 (32KB) + L1i L#14 (32KB) + Core L#14 + PU L#14 (P#13)
L2 L#15 (256KB) + L1d L#15 (32KB) + L1i L#15 (32KB) + Core L#15 + PU L#15 (P#15)
HostBridge L#8
PCIBridge
PCI 1924:0903
Net L#12 "p1p1"
PCI 1924:0903
Net L#13 "p1p2"
PCIBridge
PCI 15b3:1003
Net L#14 "ib0"
Net L#15 "ib1"
OpenFabrics L#16 "mlx4_0"
- NIC
em*およびディスクsd*は NUMA ノード 0 およびコア 0、2、4、6、8、10、12、14 に接続されます。 - NIC
p1*およびib*は NUMA ノード 1 およびコア 1、3、5、7、9、11、13、15 に接続されます。
9.4. NUMA 対応 KSM (Kernel SamePage Merging)
sysfs /sys/kernel/mm/ksm/merge_across_nodes パラメーターを使用して、複数の異なる NUMA ノード間でのページのマージを制御します。デフォルトで、すべてのノードのページは 1 つにマージできます。このパラメーターが 0 (ゼロ) に設定されると同じノードのページのみがマージされます。
重要
<memoryBacking>
<nosharepages/>
</memoryBacking><memoryBacking> 要素を使用してメモリー設定を調整する方法についての詳細は、「virsh を使用したメモリーチューニング」を参照してください。
付録A 改訂履歴
| 改訂履歴 | |||
|---|---|---|---|
| 改訂 1.0-27.1 | Sun Sep 24 2017 | ||
| |||
| 改訂 1.0-27 | Mon Jul 27 2017 | ||
| |||
| 改訂 1.0-24 | Mon Oct 17 2016 | ||
| |||
| 改訂 1.0-22 | Mon Dec 21 2015 | ||
| |||
| 改訂 1.0-19 | Thu Oct 08 2015 | ||
| |||
