Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

仮想化のチューニングと最適化ガイド

Red Hat Enterprise Linux 7

RHEL でホストシステムおよび仮想化ゲストに KVM パフォーマンス機能を使用

Jiri Herrmann

Red Hat Customer Content Services

Yehuda Zimmerman

Red Hat Customer Content Services

Dayle Parker

Red Hat Customer Content Services

Scott Radvan

Red Hat Customer Content Services

Red Hat Subject Matter Experts

概要

『Red Hat Enterprise Linux 仮想化のチューニングと最適化ガイド』では、KVM と仮想化のパフォーマンスについて説明しています。本ガイドでは、ホストシステムおよび仮想化ゲストに KVM パフォーマンス機能およびオプションを完全に使用するためのヒントと提案を確認できます。

第1章 はじめに

1.1. 仮想化におけるパフォーマンス最適化のについて

KVM Virtualization では、ゲストはホストマシンのプロセスによって表されます。つまり、ゲストの仮想ハードウェアの機能や機能をエミュレートするために、ホストの電源、メモリー、その他のリソースの処理が使用されます。
ただし、ゲストハードウェアは、ホストよりもリソースを使用することの影響を軽減することができます。したがって、ゲストが想定される速度でタスクを実行するために、割り当てられたホストリソースの量を調整する必要がある場合があります。また、さまざまな種類の仮想ハードウェアがオーバーヘッドレベルが異なる可能性があるため、適切な仮想ハードウェア構成がゲストのパフォーマンスに大きく影響する可能性があります。最後に、状況に応じて、特定の設定により、仮想マシンがホストリソースをより効果的に使用できるようになります。

1.2. KVM パフォーマンスアーキテクチャーの概要

KVM は、システムパフォーマンスだけでなk、プロセスやスレッドの管理に関連するため、以下に KVM の概要を示します。
  • KVM を使用すると、ゲストはホストの Linux プロセスとして実行します。
  • 仮想 CPU (vCPU) は通常のスレッドとして実装され、Linux スケジューラーで処理されます。
  • ゲストは NUMA や Huge Page などの機能を、カーネルから自動的に継承しません。
  • ホスト内でのディスクおよびネットワーク I/O の設定はパフォーマンスに多大な影響を与えます。
  • ネットワークトラフィックは一般的にはソフトウェアベースのブリッジを通過します。
  • デバイスとそのモデルによっては、その特定のハードウェアのエミュレーションに大きなオーバーヘッドがある可能性があります。

1.3. 仮想化のパフォーマンス機能と改善

Red Hat Enterprise Linux 7 での仮想化パフォーマンスの改善

以下の機能により、Red Hat Enterprise Linux 7 の仮想化パフォーマンスが向上します。
NUMA の自動負荷分散
NUMA の自動分散により、Red Hat Enterprise Linux 7 ゲストの手動チューニングが必要で、NUMA ハードウェアシステムで実行されるアプリケーションのパフォーマンスが向上します。NUMA バランシングは自動的に、タスク(スレッドまたはプロセス)を移動し、アクセスしているメモリーに近いタスクに移動します。これにより、ゼロ設定での優れたパフォーマンスが可能になります。ただし、場合によっては、より正確なゲスト設定を提供するか、CPU とメモリーのアフィニティーをホストするようにゲストを設定すると、結果がより適しています。
VirtIO モデル
virtio モデルを持つ仮想ハードウェアには、その特定の機能を持つハードウェアをエミュレートするオーバーヘッドはありません。virtio デバイスには、仮想化環境で使用するように設計されているという点で低いオーバーヘッドが発生します。ただし、ゲストオペレーティングシステムがすべてこのようなモデルに対応しているわけではありません。
マルチキュー virtio-net
ゲストで利用可能な仮想 CPU の数とスケーリングするパケット送信/受信処理を可能にするネットワークアプローチ。
マルチキュー virtio-net 「Multi-Queue virtio-net」
ブリッジ Zero Copy Transmit
ゼロコピー送信モードは、スループットに影響を与えずに最大 15% まで、ゲストネットワークと外部ネットワーク間で大きなパケットを送信するホストの CPU オーバーヘッドを減らします。ブリッジゼロコピー送信は、Red Hat Enterprise Linux 7 仮想マシンで完全にサポートされていますが、デフォルトでは無効化されています。
APIC Virtualization(APICv)
新しい Intel プロセッサーは、Advanced Programmable Interrupt Controller(APICv)のハードウェアの仮想化を提供します。APICv は、ゲストが APIC に直接アクセスできるようにすることで、仮想化 AMD64 および Intel 64 のゲストのパフォーマンスを強化し、割り込みの遅延を深め切り下げ、APIC が原因の仮想マシン数を終了させます。この機能は、新しい Intel プロセッサーでデフォルトで使用され、I/O パフォーマンスを向上します。
EOI Acceleration
仮想 APIC 機能を使用しない古いチップセットで、高帯域幅の I/O の割り込み(end-of-interrupt acceleration)
マルチキュー virtio-scsi
virtio-scsi ドライバーでのマルチキューサポートが提供するストレージパフォーマンスおよびスケーラビリティーが向上しました。これにより、各仮想 CPU に別のキューを持たせることができ、他の vCPU に影響を及ぼすことなく使用するために割り込みが可能になります。
マルチキュー virtio-scsi 「マルチキュー virtio-scsi」
準仮想化チケットの期間
準仮想化チケットロック(pvticketlocks)により、Red Hat Enterprise Linux 7 ゲスト仮想マシンでオーバーサブスクライブされた CPU で Red Hat Enterprise Linux 7 ゲスト仮想マシンのパフォーマンスが向上します。
準仮想化ページの障害
準仮想化ページ障害は、ホストからページのスワップアウトを試みる際にゲストにインジェクトされます。これにより、ホストのメモリーがオーバーコミットされ、ゲストメモリーがスワップアウトされると、KVM ゲストのパフォーマンスが改善されます。
準仮想化時間 vsyscall の最適化
gettimeofday および clock_gettime のシステムコールは、vsyscall メカニズムを介してユーザー空間で実行されます。以前は、これらのシステムコールを実行すると、システムがカーネルモードに切り替え、次にユーザー空間に戻りました。これにより、一部のアプリケーションのパフォーマンスが大幅に改善されます。

Red Hat Enterprise Linux の仮想化パフォーマンス機能

  • CPU/Kernel
    • NUMA: Non-Uniform Memory AccessNUMA 9章NUMA
    • CFS: 完全に Fair Scheduler。最新のクラスに焦点を合わせたスケジューラー。
    • RCU - 更新の読み取り共有スレッドデータの処理が改善されました。
    • 最大 160 個の仮想 CPU(vCPU)
  • memory
    • メモリー集約的な環境のヒュージページおよびその他の最適化。詳しくは 8章memory、を参照してください。
  • ネットワーク
    • vhost-net: カーネルベースの高速 virtIO ソリューション
    • SR-IOV: ネイティブに近いネットワークパフォーマンスレベルを実現するために導入
  • ブロック I/O
    • AIO: 他の I/O 動作にオーバーラップするスレッドのサポート
    • MSI - PCI バスデバイスの割り込み生成。
    • ディスク I/O スロットリング: ゲストディスクの I/O 要求の制御により、ホストリソースを過剰に消費しないようにできます。詳しくは 「ディスク I/O スロットリング」、を参照してください。
注記
仮想化サポート、制限、および機能の詳細は、『Red Hat Enterprise Linux 7 仮想化スタートガイド』および以下の』 URL を参照してください。

第2章 Performance Monitoring Tools

本章では、ゲストの仮想マシン環境の監視に使用するツールについて説明します。

2.1. perf kvm

kvm オプションを指定して perf コマンドを使用して、ホストからゲストオペレーティングシステムの統計を収集および分析できます。perf パッケージは、perf コマンドを提供します。以下のコマンドを実行してインストールされます。
# yum install perf
ホストで perf kvm を使用するには、ゲストの /proc/modules ファイルおよび /proc /kallsyms ファイルにアクセスできるようにする必要があります。手順2.1「ゲストからホストへの /proc ファイルのコピー」、ファイルでレポートを実行する方法は、を参照してください。

手順2.1 ゲストからホストへの /proc ファイルのコピー

重要
必要なファイル (scpを使用など)を直接コピーした場合には、長さがゼロのファイルのみをコピーします。この手順では、最初にゲストのファイルを一時的な場所 (cat コマンドで) に保存し、perf kvm が使用するホストにコピーする方法を説明します。
  1. ゲストにログインして、ファイルを保存します。

    ゲストにログインし、/proc/modules および /proc/kallsyms を一時的な場所 /tmp に保存します。
    # cat /proc/modules > /tmp/modules
    # cat /proc/kallsyms > /tmp/kallsyms
    
  2. 一時ファイルをホストにコピーします。

    ゲストからログアウトしたら、次の scp コマンド例を実行して、保存したファイルをホストにコピーします。ホスト名と TCP ポートが異なる場合は、そのホスト名と TCP ポートを置き換えてください。
    # scp root@GuestMachine:/tmp/kallsyms guest-kallsyms
    # scp root@GuestMachine:/tmp/modules guest-modules
    
    ホスト上のゲスト(guest-kallsyms および guest-modules)からの 2 つのファイルが利用でき、perf kvm で使用できるようになりました
  3. 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 を押して録画を停止します。
  4. レポートイベント

    以下のコマンド例は、記録プロセスで取得したファイルを使用し、出力を新しいファイルにリダイレクトし、分析を行います
    perf kvm --host --guest --guestmodules=guest-modules report -i perf.data.kvm \
    --force > 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)

仮想パフォーマンス監視ユニット(vPMU)は、ゲスト仮想マシンの機能を示す統計を表示します。
仮想パフォーマンス監視ユニットを使用すると、ユーザーはゲスト仮想マシンでパフォーマンスの問題のソースを特定できます。仮想 PMU は Intel の PMU(Performance Monitoring Unit)をベースとしており、Intel マシンでのみ使用できます。
この機能は、Red Hat Enterprise Linux 6 または Red Hat Enterprise Linux 7 を実行しているゲスト仮想マシンでのみサポートされ、デフォルトでは無効になっています。
お使いのシステムで仮想 PMU が対応しているかどうかを確認するには、以下のコマンドを実行して、ホスト CPU の arch_perfmon フラグを確認します。
# cat /proc/cpuinfo|grep arch_perfmon
仮想 PMU を有効にするには、ゲスト XML の cpu modehost-passthrough として指定します。
# virsh dumpxml guest_name |grep "cpu mode"
<cpu mode='host-passthrough'>
仮想 PMU を有効にしたら、ゲスト仮想マシンから perf コマンドを実行し、仮想マシンのパフォーマンス統計を表示します。

2.3. 仮想マシンマネージャーにおけるパフォーマンスの監視

Virtual Machine Monitor を使用して、システム上の仮想マシンのパフォーマンス情報を表示できます。また、Virtual Machine Manager に表示されるパフォーマンス情報を設定することもできます。

2.3.1. Virtual Machine Manager でのパフォーマンスの概要の表示

仮想マシンマネージャーを使用して仮想マシンのパフォーマンス概要を表示するには、以下の手順を実施します。
  1. 仮想マシンマネージャーのメインウィンドウで表示する仮想マシンを強調表示します。

    図2.1 表示する仮想マシンの選択

    表示する仮想マシンの選択
  2. Virtual Machine Manager Edit メニューから、Virtual Machine Details を選択します。
    仮想マシンの詳細ウィンドウが開き、コンソールが表示される場合があります。そのためには、View をクリックしてから Details を選択します。デフォルトで 概要 画面が開きます。
  3. 左側のナビゲーションペインから Performance を選択します。
    パフォーマンスビューには、CPU、メモリー使用量、ディスク、ネットワークへの入出力など、ゲストパフォーマンスの概要が表示されます。

    図2.2 ゲストパフォーマンスの詳細表示

    ゲストパフォーマンスの詳細表示

2.3.2. パフォーマンスのモニタリング

パフォーマンス監視の設定は、virt-manager の「s preferences」ウィンドウで変更できます。
パフォーマンスの監視を設定するには、以下を実行します。
  1. Edit メニューから Preferences を選択します。
    Preferences ウィンドウが表示されます。
  2. Polling タブでは、秒単位または統計ポーリングオプションの時間を指定します。

    図2.3 パフォーマンス監視の設定

    パフォーマンス監視の設定

2.3.3. ゲストの CPU 使用率の表示

システムにあるすべてのゲストの CPU 使用率を表示するには、以下のコマンドを実行します。
  1. View メニューから Graph を選択し、ゲスト CPU 使用率 のチェックボックスを選択します。
  2. 仮想マシンマネージャーには、システムにあるすべての仮想マシンの CPU 使用状況のグラフが表示されます。

    図2.4 ゲストの CPU 使用率グラフ

    ゲストの CPU 使用率グラフ

2.3.4. ホストの CPU 使用率の表示

システムにあるすべてのホストの CPU 使用率を表示するには、以下のコマンドを実行します。
  1. View メニューから Graph を選択し、Host CPU Usage チェックボックスを選択します。
  2. 仮想マシンマネージャーには、システムにおけるホスト CPU の使用状況グラフが表示されます。

    図2.5 ホストの CPU 使用率グラフ

    ホストの CPU 使用率グラフ

2.3.5. ディスク I/O の表示

システムにあるすべての仮想マシンのディスク I/O を表示するには、以下を実行します。
  1. ディスク I/O 統計収集が有効になっていることを確認します。これを行うには、Edit メニューから Preferences を選択し、Polling タブをクリックします
  2. Disk I/O チェックボックスを選択します。

    図2.6 ディスク I/O の有効化

    ディスク I/O の有効化
  3. ディスク I/O 表示を有効にするには、View メニューから Graph を選択し、Disk I/O チェックボックスを選択します。
  4. 仮想マシンマネージャーには、システムにあるすべての仮想マシンのディスク I/O グラフが表示されます。

    図2.7 ディスク I/O の表示

    ディスク I/O の表示

2.3.6. ネットワーク I/O の表示

システムにあるすべての仮想マシンのネットワーク I/O を表示するには、以下を実行します。
  1. ネットワーク I/O 統計収集が有効になっていることを確認します。これを行うには、Edit メニューから Preferences を選択し、Polling タブをクリックします
  2. Network I/O チェックボックスを選択します。

    図2.8 ネットワーク I/O の有効化

    ネットワーク I/O の有効化
  3. Network I/O 統計を表示するには、View メニューから Graph を選択してから Network I/O チェックボックスを選択します。
  4. 仮想マシンマネージャーには、システムにあるすべての仮想マシンのネットワーク I/O グラフが表示されます。

    図2.9 ネットワーク I/O の表示

    ネットワーク I/O の表示

2.3.7. メモリ使用量の表示

システムにあるすべての仮想マシンのメモリー使用量を表示するには、以下を実行します。
  1. メモリー使用量の統計収集が有効になっていることを確認します。これを行うには、Edit メニューから Preferences を選択し、Polling タブをクリックします
  2. Poll Memory stats チェックボックスを選択します。

    図2.10 メモリー使用量の有効化

    メモリー使用量の有効化
  3. メモリー使用量を表示するには、表示メニューから Graph を選択してから Memory Usage チェックボックスを選択します。
  4. Virtual Machine Manager は、システムにあるすべての仮想マシンで使用するメモリーの割合(メガバイト)を一覧表示します。

    図2.11 メモリー使用量の表示

    メモリー使用量の表示

第3章 virt-manager を使用した仮想化パフォーマンスの最適化

本章では、virt-manager、ゲスト仮想マシンを管理するためのデスクトップツールである virt-manager で利用可能なパフォーマンスチューニングオプションを説明します。

3.1. オペレーティングシステムの詳細とデバイス

3.1.1. ゲスト仮想マシンの詳細を指定する

virt-manager ツールは、新規ゲスト仮想マシンに選択されるオペレーティングシステムのタイプおよびバージョンに応じて異なるプロファイルを提供します。ゲストの作成時には、できるだけ多くの詳細を提供する必要があります。これにより、特定タイプのゲストで利用可能な機能を有効にすることでパフォーマンスを向上できます。
以下の「virt-manager ツールのキャプチャー」を参照してください。新規ゲスト仮想マシンの作成時に、使用する OS タイプと バージョンを常に指定します

図3.1 OS の種類とバージョンを指定する

OS の種類とバージョンを指定する

3.1.2. 未使用デバイスの削除

未使用のデバイスまたは不要なデバイスを削除すると、パフォーマンスを向上できます。たとえば、Web サーバーとしてゲストタスクは、オーディオ機能または割り当てられたタブレットを必要とすることはほとんどありません。
以下の「virt-manager ツールのキャプチャー」を参照してください。削除 ボタンをクリックして、不要なデバイスを削除します。

図3.2 未使用のデバイスの削除

未使用のデバイスの削除

3.2. CPU パフォーマンスオプション

ゲスト仮想マシンでは、複数の CPU 関連のオプションを利用できます。これらのオプションは正しく設定されていれば、パフォーマンスに大きな影響を及ぼす可能性があります。以下の図は、ゲストで利用可能な CPU オプションを示しています。これ以降のセクションでは、これらのオプションの影響について取り上げます。

図3.3 CPU パフォーマンスオプション

CPU パフォーマンスオプション

3.2.1. オプション: 利用可能な CPU

このオプションを使用して、ゲストで利用可能な仮想 CPU(vCPU)の量を調整します。(オーバーコミットとして知られている)ホストで利用可能な以上のリソースを割り当てる場合、以下の図に示すように警告が表示されます。

図3.4 CPU のオーバーコミット

CPU のオーバーコミット
CPU は、システム上の全ゲスト用の仮想 CPU の合計が、システム上のホスト CPU 数よりも大きい場合にオーバーコミットされます。仮想 CPU の合計数がホスト CPU の数よりも大きい場合には、1 つまたは複数のゲストで CPU をオーバーコミットできます。
重要
メモリーのオーバーコミットと同様に、CPU のオーバーコミットはパフォーマンスに悪影響を及ぼす可能性があります。たとえば、ゲストのワークロードが大きい場合や予測不能な場合など、パフォーマンスに悪影響を及ぼす可能性があります。オーバーコミットの詳細については、『仮想化の導入および管理ガイド』』を参照してください

3.2.2. オプション: CPU 設定

このオプションを使用して、目的の CPU モデルに基づいて CPU 設定タイプを選択します。Copy host CPU configuration チェックボックスをクリックして、物理ホストの CPU モデルと設定を検出して適用するか、または一覧を展開して利用可能なオプションを表示します。CPU 設定を選択すると、利用可能な CPU 機能または命令が表示され、CPU 機能リストで個別に有効化 /無効化できます。

図3.5 CPU 設定オプション

CPU 設定オプション
注記
ホスト CPU 設定は、手動設定よりも推奨されます。
注記
または、ホストマシンで virsh capabilities コマンドを実行して、CPU の種類や NUMA 機能など、システムの仮想化機能を表示します。

3.2.3. オプション: CPU トポロジー

このオプションでゲスト仮想マシンの仮想 CPU に特定の CPU トポロジーを適用します (ソケット、コア、スレッドなど)。

図3.6 CPU トポロジーのオプション

CPU トポロジーのオプション
注記
環境によっては要件が異なることもありますが、通常はソケット数を選択する場合に、コア、スレッドのいずれも 1 つのみを指定すると、最善のパフォーマンスを実現できます。

3.3. 仮想ディスクのパフォーマンスオプション

インストール中に、パフォーマンスに影響を与える可能性のある仮想ディスク関連のオプションが複数、ゲスト仮想マシンで利用できます。以下の図は、ゲストで利用可能な仮想ディスクオプションを示しています。
キャッシュモード、IO モード、および IO チューニングは、virt-manager の仮想ディスク セクションで選択できます 以下のイメージのように、Performance オプションの下のフィールドにこれらのパラメーターを設定します

図3.7 仮想ディスクのパフォーマンスオプション

仮想ディスクのパフォーマンスオプション
重要
virt-manager で仮想ディスクのパフォーマンスオプションを設定する場合、設定を有効にするために仮想マシンを再起動する必要があります。
「キャッシュ」 XML 設定のこれらの設定を編集する方法は、および を参照してください。

第4章 tuned および tuned-adm

本章では、仮想化環境でシステム設定を調整するための tuned デーモンの使用を説明します。
Tuned は、CPU 集中型タスクの要件やストレージ/ネットワークスループットの応答など、特定のワークロードの特性に対して Red Hat Enterprise Linux を調整するチューニングプロファイルの配信メカニズムです。これにより、特定のユースケースでパフォーマンスを強化し、電力消費を減らすように事前設定されたチューニングプロファイルを多数提供します。これらのプロファイルを編集するか、または新規プロファイルを作成して、環境に適したパフォーマンスソリューションを作成します。
tuned の一部として提供される仮想化関連のプロファイルには、以下が含まれます。
virtual-guest
throughput-performance プロファイルに基づいて、virtual-guest は仮想メモリーのスワップも減少します。
Red Hat Enterprise Linux 7 ゲスト仮想マシンの作成時に、virtual-guest プロファイルが自動的に選択されます。これは、仮想マシンに推奨されるプロファイルです。
このプロファイルは Red Hat Enterprise Linux 6.3 以降で利用できますが、仮想マシンのインストール時に手動で選択する必要があります。
virtual-host
throughput-performance プロファイルに基づいて、virtual-host はダーティーページのより積極的なライトバックを有効にします。このプロファイルは、KVM および Red Hat Virtualization(RHV)ホストの両方を含む仮想化ホストに推奨されるプロファイルです。
Red Hat Enterprise Linux 7 では、デフォルトで tuned パッケージがインストールされ、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-performance
カスタムの tuned プロファイルを作成して、チューニングパラメーターのセットをカプセル化することもできます。カスタムの tuned プロファイルの作成方法は、man ページの tuned.conf を参照してください。
現在アクティブなプロファイルのみを表示するには、以下のコマンドを実行します。
tuned-adm active
利用可能なプロファイルのいずれかに切り替えるには、以下のコマンドを実行します。
tuned-adm profile profile_name
たとえば、virtual-host プロファイルに切り替えるには、以下を実行します。
tuned-adm profile virtual-host
重要
Red Hat Enterprise Linux 7.1 以降で tuned プロファイルを設定したら、再起動後に設定されたプロファイルに対して tuned サービスが有効になっていることを確認してください。
# systemctl enable tuned
場合によっては、手動で設定したパラメーターを使用するように tuned を無効にすることが推奨されます。現行セッションでチューニングをすべて無効にするには、次のコマンドを実行します。
# tuned-adm off
tuned を永続的に無効にして、実行した変更をすべて元に戻するには、次のコマンドを実行します。
# tuned-adm off; systemctl disable tuned

第5章 ネットワーク

本章では、仮想化環境におけるネットワークの最適化について説明します。

5.1. ネットワークの調整のヒント

  • 複数のネットワークを使用して、1 つのネットワーク上の輻輳を回避します。たとえば、管理、バックアップ、またはライブマイグレーション用の専用ネットワークがあります。
  • Red Hat は、同じネットワークセグメントで複数のインターフェースを使用しないことを推奨します。ただし、これが避けられない場合は、arp_filter を使用して ARP Flux が発生しないようにすることができます。これは、ホストとゲストの両方で発生する望ましく、マシンが複数のネットワークインターフェースから ARP 要求に応答することで生じます。echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter または /etc/sysctl.conf を編集してこの設定を永続化します。
注記
ARP Flux の詳細は を参照してください。 http://linux-ip.net/html/ether-arp.html#ether-arp-flux

5.2. virtio および vhost_net

以下の図は、Virtio および vhost_net アーキテクチャーにおけるカーネルの位置付けを示しています。

図5.1 virtio および vhost_net アーキテクチャー

virtio および vhost_net アーキテクチャー
vhost_net は、Virtio ドライバーの一部をユーザー空間からカーネルに移動します。これにより、コピー操作が減少し、レイテンシーと CPU 使用率が短縮されます。

5.3. デバイスの割り当ておよび SR-IOV

デバイス割り当てと SR-IOV の構造におけるカーネルの位置付けを示します。

図5.2 デバイスの割り当ておよび SR-IOV

デバイスの割り当ておよび SR-IOV
デバイスの割り当てでは、デバイス全体をゲストに表示します。SR-IOV は、NIC およびシステムボードを含むドライバーおよびハードウェアをサポートし、複数の仮想デバイスを作成して、異なるゲストに渡す必要があります。ゲストではベンダー固有のドライバーが必要ですが、SR-IOV では、すべてのネットワークオプションのレイテンシーが一番低くなります。

5.4. Network Tuning Techniques

ここでは、仮想化環境におけるネットワークのパフォーマンスチューニングの方法について説明します。
重要
以下の機能は、Red Hat Enterprise Linux 7 ハイパーバイザーおよび仮想マシンでサポートされていますが、Red Hat Enterprise Linux 6.6 以降を実行する仮想マシンでもサポートされています。

5.4.1. ブリッジ Zero Copy Transmit

大規模なパケットサイズでは、ゼロコピー送信モードが有効になります。通常、スループットに影響を与えずにゲストネットワークおよび外部ネットワークとの間で大きなパケットを送信する場合に、最大 15% まで、ホストの CPU オーバーヘッドを削減します。
これは、ゲストとゲスト間、ゲストとホスト間のパフォーマンス、または小規模なパケットのワークロードには影響を与えません。
ブリッジゼロコピー送信は、Red Hat Enterprise Linux 7 仮想マシンで完全にサポートされていますが、デフォルトでは無効化されています。ゼロコピー送信モードを有効にするには、vhost_net モジュールの experimental_zcopytx カーネルモジュールパラメーターを 1 に設定します。詳細な手順は、『仮想化の導入および管理ガイド』を参照してください
注記
通常、追加のデータコピーは、サービス拒否(DoS)攻撃に対して、脅威の軽減策として作成されます。コピー送信をゼロにすると、この脅威の軽減策の手法が無効になります。
パフォーマンスのリグレッションが確認された場合、またはホスト CPU 使用率が懸念でない場合は、experimental_zcopytx を 0 に設定すると、コピー送信モードが無効になります。

5.4.2. Multi-Queue virtio-net

マルチキュー virtio-net は、一度に複数の仮想キューペアでパケットを転送できるように、仮想 CPU の数としてネットワークパフォーマンスをスケーリングするアプローチを提供します。
現在、ハイエンドサーバーにはより多くのプロセッサーがあり、それらで実行しているゲストには仮想 CPU の数が増えることがよくあります。単一キュー virtio-net では、仮想 CPU の数が増える際にネットワークのパフォーマンスがスケーリングされないため、ゲスト内のプロトコルスタックのスケールは制限されます。virtio-net には送信キューと受信キューが 1 つしかないため、ゲストは並行してパケットを送受信することはできません。
マルチキューサポートは、並行してパケット処理を許可することで、これらのボトルネックを取り除きます。
マルチキュー virtio-net は、以下の場合に最も優れたパフォーマンス上の利点を提供します。
  • トラフィックパケットは比較的大きくなる。
  • ゲストは、ゲスト、ゲスト間、ホスト、またはゲスト間を外部システムに実行中のトラフィックと共に、同時に多くの接続上でアクティブな状態です。
  • キューの数は仮想 CPU の数と同じになります。これは、マルチキューのサポートが、特定の仮想 CPU に特定のキューをプライベートにするために受信割り込み親および送信キューの選択を最適化するためです。
注記
現在、マルチキュー virtio-net 接続を設定すると、発信トラフィックのパフォーマンスに悪影響を及ぼす可能性があります。具体的には、TCP(Transmission Control Protocol)ストリーム上でパケットを 1,500 バイトで送信したときに発生する可能性があります。詳細は Red Hat ナレッジベースを参照してください

5.4.2.1. Multi-Queue virtio-net の設定

マルチキュー virtio-net を使用するには、ゲスト XML 設定に以下を追加してゲストでサポートを有効にします(N 、マルチキュータップデバイスの最大 256 キューをサポートするため、N は 1 から 256 までです)。
<interface type='network'>
      <source network='default'/>
      <model type='virtio'/>
      <driver name='vhost' queues='N'/>
</interface>
ゲストで N virtio-net キューを持つ仮想マシンを実行する場合は、以下のコマンドを使用してマルチキューサポートを有効にします(M の値は 1 から Nまでです)。
# ethtool -L eth0 combined M

5.5. ネットワークパケットのバッチ処理

転送パスが長い設定では、パケットをバッチ処理してからカーネルに送信する前に、キャッシュの使用状況が向上する可能性があります。
バッチ処理可能なパケットの最大数を設定するには、N はバッチ処理のパケットの最大数に置き換えます
# ethtool -C $tap rx-frames N
type='bridge' または type='network' インターフェースの tun/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 スケジューリング

Red Hat Enterprise Linux 7 が仮想ホストであり 、仮想化ゲストの場合の両方で、入出力(I/O)スケジューラーを使用して、ディスクパフォーマンスを強化できます。

6.1. Red Hat Enterprise Linux を仮想化ホストとして使用する I/O スケジューリング

仮想化ゲストのホストとして Red Hat Enterprise Linux 7 を使用する場合は、デフォルトの期限スケジューラーは通常理想的です。このスケジューラーは、ほぼすべてのワークロードで適切に実行されます。
ただし、最大 I/O スループットを最大限に活用するよりも重要な場合には、ゲストワークロードで I/O レイテンシーを最小化することよりも重要な場合は、代わりに cfq スケジューラーを使用することが有益です。

6.2. Red Hat Enterprise Linux を仮想化ゲストとして使用する I/O スケジューリング

ゲストが実行しているハイパーバイザーに関係なく、Red Hat Enterprise Linux ゲスト仮想マシンで I/O スケジューリングを使用できます。以下は、考慮すべき利点と問題の一覧です。
  • Red Hat Enterprise Linux ゲストの利点は以下のとおりです。スケジューラーは、I/O をハイパーバイザーに送信する前に、ゲストオペレーティングシステムからの小さな要求を大きな要求にマージします。これにより、ハイパーバイザーは I/O 要求をより効率的に処理できるようになり、ゲストの I/O パフォーマンスを大幅に向上させることができます。
  • ワークロード I/O およびストレージデバイスの割り当て方法に応じて、deadline などのスケジューラーは noop よりも有益になります。Red Hat は、どのスケジューラーがパフォーマンスに影響するかを確認するためのパフォーマンステストを推奨します。
  • iSCSI、SR-IOV、または物理デバイスのパススルーがアクセスするストレージを使用するゲストは、noop スケジューラーは使用しないでください。これらの方式では、ホストは基礎となる物理デバイスへの I/O 要求を最適化できません。
注記
仮想化環境では、ホストとゲスト層の両方で I/O をスケジュールすることが有益です。複数のゲストが、ホストオペレーティングシステムが管理するファイルシステムまたはブロックデバイスでストレージを使用する場合は、全ゲストからのリクエストを認識するので、ホストが I/O をスケジュールできます。さらに、ホストはストレージの物理レイアウトを認識します。これは、ゲストの仮想ストレージに線形にマップできない場合があります。
すべてのスケジューラーチューニングは、合成ベンチマークは通常、仮想環境で共有リソースを使用してシステムのパフォーマンスを正確に比較しないため、通常の動作条件下でテストする必要があります。

6.2.1. Red Hat Enterprise Linux 7 の I/O スケジューラーの設定

Red Hat Enterprise Linux 7 システムで使用されるデフォルトのスケジューラーは deadline です。ただし、Red Hat Enterprise Linux 7 ゲストマシンでは、以下の手順に従ってスケジューラーを noop に変更することが有益です
  1. /etc/default/grub ファイルで、GRUB_CMDLINE_LINUX の行の toelevator=noop の文字列を変更しますnoelevator= 文字列がある場合は、行の最後に addelevator=noop を追加します。
    変更が成功する後の /etc/default/grub ファイルを示します。
    # cat /etc/default/grub
    [...]
    GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=vg00/lvroot rhgb quiet elevator=noop"
    [...]
    
  2. /boot/grub2/grub.cfg ファイルを再ビルドします。
    • BIOS ベースのマシンの場合:
      # grub2-mkconfig -o /boot/grub2/grub.cfg
    • UEFI ベースのマシンの場合:
      # grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg

第7章 ブロック I/O

本章では、仮想化環境における I/O の最適化について説明します。

7.1. ブロック I/O の調整

virsh blkiotune コマンドを使用すると、管理者はゲスト XML 設定の <blkio> 要素に手動でゲスト仮想マシンのブロック I/O パラメーターを設定したり、表示したりできます。
仮想マシンの現在の <blkio> パラメーターを表示するには、以下を実行します。
# virsh blkiotune virtual_machine
仮想マシンの <blkio> パラメーターを設定するには、virsh blkiotune コマンドを使用し、お使いの環境に応じてオプションの値を置き換えます。

# virsh blkiotune virtual_machine [--weight number] [--device-weights string] [--config] [--live] [--current]
パラメーター には以下が含まれます。
weight
範囲 100 から 1000 までの I/O ウェイト。
デバイスの I/O 加重を増やすと、I/O 帯域幅の優先度が高まるため、より多くのホストリソースが提供されます。同様に、デバイスのウェイトを下げると、ホストのリソースが少なくなります。
device-weights
1 つの文字列は、/path/to/device,weight,/path/to/device,weight の形式で、1つ以上のデバイス/weight ペアを一覧表示します 。各重みは、デバイスごとの一覧からそのデバイスを削除するには 100-1000 の範囲、または 0 の値が必要です。文字列に一覧表示されているデバイスのみが変更されます。その他のデバイスの既存のデバイスごとの重みは変更されません。
config
次回の起動時に変更を有効にするには、--config オプションを追加します。
live
実行中の仮想マシンに変更を適用するには、--live オプションを追加します。
注記
--live オプションでは、このアクションに対応するハイパーバイザーが必要です。すべてのハイパーバイザーが最大メモリー制限のライブ変更を許可する訳ではありません。
current
--current オプションを追加して、現在の仮想マシンに変更を適用します。
たとえば、以下は、liftbrul 仮想マシンの /dev/sda デバイスのウェイトを 500 に変更します。
# virsh blkiotune liftbrul --device-weights /dev/sda, 500
注記
virsh blkiotune コマンドの使用に関する詳細は、virsh help blkiotune コマンドを使用します。

7.2. キャッシュ

キャッシュオプションは、ゲストのインストール時に virt-manager、またはゲスト XML 設定を編集して既存のゲスト仮想マシンで設定できます。

表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=directsyncwritethrough と似ていますが、ゲストの I/O はホストページキャッシュをバイパスします。
cache=unsafeホストはすべてのディスク I/O をキャッシュする可能性がありますが、ゲストからの同期要求は無視されます。
Cache=defaultキャッシュモードを指定しないと、システムのデフォルト設定が選択されます。
virt-manager では、仮想ディスクでキャッシュモードを指定できますvirt-manager を使用してキャッシュモードを変更する方法は、を参照してください。 「仮想ディスクのパフォーマンスオプション」
ゲスト XML でキャッシュモードを設定するには、driver タグ内の cache 設定を編集して、キャッシングオプションを指定します。たとえば、キャッシュを writeback に設定するには、以下を実行します。
<disk type='file' device='disk'>
          <driver name='qemu' type='raw' cache='writeback'/>

7.3. I/O モード

I/O モードオプションは、ゲストのインストール時に virt-manager、またはゲスト XML 設定を編集して既存のゲスト仮想マシンで設定できます。

表7.2 IO モードオプション

IO モードオプション説明
IO=nativeRed Hat Virtualization(RHV)環境のデフォルトです。このモードは、ダイレクト I/O オプションを使用したカーネルの非同期 I/O を参照します。
IO=threadsデフォルトは、ホストユーザーモードベースのスレッドです。
IO=defaultRed Hat Enterprise Linux 7 のデフォルトはスレッドモードです。
virt-manager では、仮想ディスクで I/O モードを指定できます。virt-manager を使用して I/O モードを変更する方法は、を参照してください。 「仮想ディスクのパフォーマンスオプション」
ゲスト XML で I/O モードを設定するには、driver タグ内の io 設定を編集します。nativethreads、または default を指定します。たとえば、I/O モードを threads に設定するには、以下を実行します。
<disk type='file' device='disk'>
          <driver name='qemu' type='raw' io='threads'/>

7.4. ブロック I/O チューニングのバリキュー

ここでは、仮想化環境におけるブロック I/O パフォーマンス調整の詳細の方法について説明します。

7.4.1. ディスク I/O スロットリング

複数の仮想マシンが同時に実行する場合は、過剰なディスク I/O を使用することで、システムのパフォーマンスに干渉する可能性があります。KVM のディスク I/O スロットリングでは、仮想マシンからホストマシンに送られるディスク I/O 要求に制限を設定する機能を利用できます。これにより、仮想マシンが共有リソースを過剰に使用し、その他の仮想マシンのパフォーマンスに影響を及ぼすことを防ぐことができます。
ディスク I/O スロットリングは、異なる顧客に属するゲスト仮想マシンが同じホストで実行されている場合や、異なるゲストに対して QoS 保証が提供されている場合など、さまざまな状況で役立ちます。ディスク I/O スロットリングは、低速なディスクをシミュレートするために使用することもできます。
I/O スロットリングは、ゲストに割り当てられた各ブロックデバイスに個別に適用でき、スループットおよび I/O 操作の制限に対応します。virsh blkdeviotune コマンドを使用して、仮想マシンの I/O 制限を設定します。
# virsh blkdeviotune virtual_machine device --parameter limit
device は、仮想マシンに割り当てられたディスクデバイスのいずれかに一意のターゲット名(<target dev='name'/>)またはソースファイルを指定します。<source file='name'/>ディスクデバイス名の一覧は、virsh domblklist コマンドを使用します。
オプションのパラメーターは以下のとおりです。
total-bytes-sec
合計スループットの上限(バイト毎秒単位)。
read-bytes-sec
読み取りスループットの上限(バイト毎秒単位)。
write-bytes-sec
書き込みスループットの上限(バイト毎秒単位)。
total-iops-sec
1 秒あたりの合計 I/O 操作の制限。
read-iops-sec
1 秒あたりの読み取り I/O 操作の制限。
write-iops-sec
1 秒あたりの書き込み I/O 操作の制限。
たとえば、virtual_machinethrottlevda を、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

マルチキュー virtio-scsi は、virtio-scsi ドライバーでストレージのパフォーマンスとスケーラビリティーを向上させます。これにより、各仮想 CPU に別のキューを持たせることが可能になります。また、他の vCPU に影響を及ぼすことなく使用するために、割り込みできるようになります。

7.4.2.1. Multi-Queue virtio-scsi の設定

Red Hat Enterprise Linux 7 では、マルチキュー virtio-scsi はデフォルトで無効になっています。
ゲストでマルチキュー virtio-scsi サポートを有効にするには、ゲスト XML 設定に以下を追加します。ここでの N は、vCPU キューの合計数に置き換えます。
   <controller type='scsi' index='0' model='virtio-scsi'>
   <driver queues='N' />
    </controller>

第8章 memory

本章では、仮想化環境におけるメモリーの最適化オプションについて説明しています。

8.1. メモリーチューニングのヒント

仮想化環境でメモリーパフォーマンスを最適化するには、以下を考慮してください。
  • それが使用する量を超えるリソースをゲストに割り当てないでください。
  • 可能であれば、ゲストを単一の NUMA ノードに割り当て、その NUMA ノードで十分なリソースを提供します。NUMA 9章NUMA

8.2. 仮想マシンでのパフォーマンスチューニング

8.2.1. メモリー監視ツール

メモリー使用量は、ベアメタル環境で使用されるツールを使用して仮想マシンで監視できます。メモリー使用量を監視し、メモリー関連の問題の診断に役立つツールには以下が含まれます。
  • top
  • vmstat
  • numastat
  • /proc/
注記
これらのパフォーマンスツールの使用方法は、『Red Hat Enterprise Linux 7 パフォーマンスチューニングガイド』およびこれらのコマンドの』 man ページを参照してください。

8.2.2. virsh によるメモリーのチューニング

ゲスト XML 設定のオプションの <memtune> 要素を使用すると、管理者はゲスト仮想マシンメモリー設定を手動で設定できます。<memtune> を省略すると、デフォルトのメモリー設定が適用されます。
virsh memtune コマンドを使用して、仮想マシンの <memtune> 要素でメモリーパラメーターを表示または設定します。環境に応じて値を置き換えます。
# virsh memtune virtual_machine --parameter size
オプションのパラメーター には以下が含まれます。
hard_limit
仮想マシンが使用できる最大メモリー(kibibytes のブロックが 1024 バイト)。
警告
この制限を低く設定しすぎると、仮想マシンがカーネルによって強制終了される可能性があります。
soft_limit
メモリーの競合時に実施するメモリー制限(kibibytes の 1024 バイトブロック)。
swap_hard_limit
最大メモリーとスワップは、仮想マシンが使用できるスワップ(kibibytes の 1024 バイトブロック)です。swap_hard_limit の値は hard_limit 値よりも大きくなければなりません。
min_guarantee
仮想マシンの最小メモリーの割り当て確保(kibibytes のブロック)
注記
virsh memtune コマンドの使用に関する詳細は、# virsh help memtune を参照してください。
オプションの <memoryBacking> 要素には、仮想メモリーページがホストページでサポートされる方法に影響を与える複数の要素が含まれる場合があります。
locked を設定すると、ホストがゲストに属するメモリーページをスワップアウトするのを防ぎます。ゲスト XML に以下を追加して、ホストのメモリーの仮想メモリーページをロックします。
<memoryBacking>
        <locked/>
</memoryBacking>
重要
locked を設定する場合、hard_limit<memtune> 要素に設定する必要があります。ゲストに設定された最大メモリー、および プロセス自体が使用するメモリーをすべて、要素で設定する必要があります。
nosharepages を設定すると、ホストがゲスト間で使用された同じメモリーをマージするのを防ぎます。ハイパーバイザーに対し、ゲストの共有ページを無効にするように指示するには、ゲストの XML に以下の設定を追加します。
<memoryBacking>
         <nosharepages/>
</memoryBacking>

8.2.3. Huge Page および Transparent Huge Page

AMD64 および Intel 64 CPU は通常 4kB ページでメモリーに対応していますが、Huge Page と呼ばれる大きな 2MB または 1GB ページを使用できます。KVM ゲストは、Huge Page メモリーのサポートを使用してデプロイでき、Transaction Lookaside Buffer(TLB: Transaction Lookaside Buffer )に対して CPU キャッシュのヒットを増やすことで、パフォーマンスを向上させることができます。
Red Hat Enterprise Linux 7 でデフォルトで有効になっているカーネル機能は、大きなメモリーやメモリー集約型のワークロードなど、ヒュージページを大幅に向上させることができます。Red Hat Enterprise Linux 7 は、Huge Page を使用してページサイズを増やすことで、大量のメモリーを管理できます。Red Hat Enterprise Linux 7 では、THP(Transparent Huge Pages)が使用されるため、効果的さと便利性を向上させるために、Red Hat Enterprise Linux 7 はデフォルトでTransparent Huge Pages (THP)を使用します。Huge Page および THP の詳細は、『パフォーマンスチューニングガイド』を参照してください
Red Hat Enterprise Linux 7 システムは 2MB および 1 GB の Huge Page をサポートしており、これは起動時にまたはランタイム時に割り当てることができます。複数の Huge Page 「ブートまたはランタイム時のゲストに対して 1 GB のヒュージページの有効化」、を参照してください。

8.2.3.1. Transparent Huge Pages の設定

Transparent Huge Page(THP)は抽象化レイヤーで、Huge Page の作成、管理、および使用のほとんどの側面を自動化します。デフォルトでは、パフォーマンスに対してシステム設定が自動的に最適化されます。
注記
KSM を使用すると、Transparent Huge Page を減らすことができます。したがって、THP を有効にする前に、KSM を無効にすることが推奨されます。「KSM の非アクティブ化」
透過的な Huge Page はデフォルトで有効になります。現在のステータスを確認するには、以下を実行します。
# cat /sys/kernel/mm/transparent_hugepage/enabled
透過的な Huge Page をデフォルトで使用できるようにするには、以下を実行します。
# echo always > /sys/kernel/mm/transparent_hugepage/enabled
これにより、/sys/kernel/mm/transparent_hugepage/enabledalways に設定されます。
透過的な Huge Page を無効にするには、以下を実行します。
# echo never > /sys/kernel/mm/transparent_hugepage/enabled
Transparent Huge Page のサポートにより、静的な Huge Page の使用は妨げられません。ただし、静的 Huge Page が使用されていない場合、KVM は通常の 4kB ページサイズではなく、透過的な Huge Page を使用します。

8.2.3.2. 静的 Huge Page の設定

場合によっては、Huge Page の制御がより高くなります。 ゲストで静的 Huge Page を使用するには、virsh edit を使用して、ゲストの XML 設定に以下を追加します。
<memoryBacking>
        <hugepages/>
</memoryBacking>
これにより、デフォルトのページサイズではなく、Huge Page を使用してメモリーをゲストに割り当てるようにホストに指示します。
以下のコマンドを実行して、現在の Huge Page 値を表示します。
cat /proc/sys/vm/nr_hugepages

手順8.1 Huge Page の設定

以下の手順例は、huge page を設定するためのコマンドを示しています。
  1. 現在の Huge Page 値を表示します。
    # cat /proc/meminfo | grep Huge
    AnonHugePages:      2048 kB
    HugePages_Total:       0
    HugePages_Free:        0
    HugePages_Rsvd:        0
    HugePages_Surp:        0
    Hugepagesize:       2048 kB
  2. 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
    
    その後、ゲストの /etc/grub2.cfg ファイルの /kernel 行の末尾に追加して、カーネルブートパラメーターに transparent_hugepage=never を追加します。
  3. Huge Page をマウントします。
    # mount -t hugetlbfs hugetlbfs /dev/hugepages
  4. 仮想マシンの XML 設定のmemoryBacking セクションに追加します。
    <hugepages>
      <page size='1' unit='GiB'/>
    </hugepages>
    
  5. libvirtd を再起動して、以下のコマンドで仮想マシンを再起動します。
    # systemctl start libvirtd
    # virsh start virtual_machine
  6. /proc/meminfo の変更を確認します。
    # cat /proc/meminfo | grep Huge
    AnonHugePages:         0 kB
    HugePages_Total:   25000
    HugePages_Free:    23425
    HugePages_Rsvd:        0
    HugePages_Surp:        0
    Hugepagesize:       2048 kB
Huge Page は、ホストだけでなくゲストもも利点はありませんが、ヒュージページの合計値は、ホストで利用可能なものよりも小さくなければなりません。

8.2.3.3. ブートまたはランタイム時のゲストに対して 1 GB のヒュージページの有効化

Red Hat Enterprise Linux 7 システムは 2MB および 1 GB の Huge Page をサポートしており、これは起動時にまたはランタイム時に割り当てることができます。

手順8.2 起動時の 1 GB のヒュージページの割り当て

  1. 起動時に異なる Huge Page のサイズを割り当てるには、次のコマンドを使用してヒュージページの数を指定します。この例では、4 つの 1 GB のヒュージページと 1024 2MB の Huge Page を割り当てます。
    'default_hugepagesz=1G hugepagesz=1G hugepages=4 hugepagesz=2M hugepages=1024'
    
    このコマンドラインを変更し、起動時に割り当てられる別の Huge Page の数を指定します。
    注記
    システムの起動時に初めて 1 GB の Huge Page を割り当てる場合は、次の 2 つの手順も実行する必要があります。
  2. ホストに 2MB および 1GB の 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
    
  3. 仮想マシンの XML 設定のmemoryBacking セクションに追加します。
    <hugepages>
      <page size='1' unit='GiB'/>
    </hugepages>
    
  4. libvirtd を再起動して、ゲストで 1 GB のヒュージページを使用できるようにします。
    # systemctl restart libvirtd
    

手順8.3 ランタイム時に 1 GB の Huge Page の割り当て

1GB の Huge Page は、ランタイム時に割り当てることもできます。ランタイムの割り当てにより、システム管理者は、それらのページを割り当てる NUMA ノードを選択できます。ただし、ランタイムページの割り当ては、メモリーの断片化によるブート時間の割り当てに比べると、割り当て失敗が生じる可能性が高くなります。
  1. ランタイム時に異なるサイズの Huge Page を割り当てるには、以下のコマンドを使用して、Huge Page の数、NUMA ノード、割り当てる NUMA ノード、およびヒュージページのサイズを置き換えます。
    # 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 のヒュージページを、node3 から 1024 2MB の Huge Page を割り当てます。
    これらの Huge Page 設定は、ホストシステムの空きメモリー容量に応じて、上記のコマンドでいつでも変更できます。
    注記
    次の 2 つの手順は、ランタイム時に 1 GB の Huge Page を最初に割り当てる際に、完了する必要もあります。
  2. ホストに 2MB および 1GB の 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
    
  3. 仮想マシンの XML 設定のmemoryBacking セクションに追加します。
    <hugepages>
      <page size='1' unit='GiB'/>
    </hugepages>
    
  4. libvirtd を再起動して、ゲストで 1 GB のヒュージページを使用できるようにします。
    # systemctl restart libvirtd
    

8.3. Kernel Same-page Merging(KSM)

KVM ハイパーバイザーが使用する Kernel same-page Merging(KSM)により、KVM ゲストが同じメモリーページを共有できます。この共有ページは通常、一般的なライブラリーや他の同一データです。KSM により、メモリーの重複を回避して、同一または同様のゲストオペレーティングシステムのゲスト密度が高まります。
共有メモリーの概念は、最新のオペレーティングシステムでは一般的です。たとえば、プログラムが最初に起動すると、親プログラムとすべてのメモリーを共有します。子または親プログラムがこのメモリーを変更しようとすると、カーネルは新しいメモリーリージョンを割り当て、元のコンテンツをコピーして、プログラムがこの新しいリージョンを変更できるようにします。これは、書き込み時のコピーとして知られています。
KSM は、この概念を逆に使用する Linux 機能です。KSM により、カーネルは実行中の 2 つ以上のプログラムを調べ、そのメモリーを比較することができます。メモリー領域またはページが同じであれば、KSM は、1 ページに同じ複数のメモリーページを減らします。このページには、書き込み時にコピーのマークが付けられます。ページのコンテンツがゲスト仮想マシンによって変更されると、そのゲストに新しいページが作成されます。
これは、KVM を使用した仮想化に役に立ちます。ゲスト仮想マシンが起動すると、ホスト qemu-kvm プロセスからメモリーのみが継承されます。ゲストの実行後、ゲストが同じオペレーティングシステムまたはアプリケーションを実行する場合は、ゲストオペレーティングシステムイメージのコンテンツを共有できます。KSM により、KVM は同一のゲストメモリー領域を共有するよう要求できます。
KSM により、メモリー速度と使用率が強化されます。KSM では、共通プロセスデータはキャッシュまたはメインメモリーに保存されます。これにより、KVM ゲストのキャッシュミスが軽減され、一部のアプリケーションやオペレーティングシステムのパフォーマンスが向上します。2 つ目は、メモリーを共有すると、ゲストの全体的なメモリー使用量が減り、これにより、大量のリソースの使用が可能になります。
注記
Red Hat Enterprise Linux 7 では、KSM が NUMA を認識しています。これにより、ページコアレッシング中に NUMA ローカリティーが考慮されるので、リモートノードに移動されたページに関連するパフォーマンスが低下するのを防ぐことができます。Red Hat は、KSM を使用している場合には、ノード間のメモリーマージを回避することを推奨します。KSM を使用している場合は、NUMA ノード間のページをマージしないように、/sys/kernel/mm/ksm/merge_across_nodes tunable を 0 に変更します。これは、virsh node-memory-tune --shm-merge-across-nodes 0 コマンドで実行できます。カーネルメモリーアカウンティングの統計は、最終的には複数のノード間のマージの後に相互に矛盾する可能性があります。そのため、KSM デーモンが大量のメモリーをマージすると、numad が混同する可能性があります。システムに大量の空きメモリーがある場合は、KSM デーモンをオフにして無効にすることで、パフォーマンスが向上する可能性があります。9章NUMAに関する詳しい情報は「」を参照してください。
重要
KSM を考慮していなくても、コミットされた RAM に十分なスワップサイズであることを確認します。KSM は、同一または同様のゲストの RAM 使用率を減らします。swap 領域が十分でない KSM を持つオーバーコミットを行うゲストは可能ですが、ゲスト仮想マシンのメモリー使用によりページが共有されなくなる可能性があるため、推奨されません。
Red Hat Enterprise Linux は、KSM を制御するには、以下の 2 つの方法を使用します。
これらのサービスはいずれも標準のサービス管理ツールで制御されます。
注記
Red Hat Enterprise Linux 6.7 では、KSM はデフォルトで無効になっています。

8.3.1. KSM サービス

  • Theksm サービスは qemu-kvm パッケージに含まれます。
  • ksm サービスが起動しない場合には、KSM(Kernel same-page merging)が 2000 ページのみを共有します。このデフォルト値により、制限されたメモリー保存の利点が得られます。
  • ksm サービスが起動すると、KSM は、ホストシステムのメインメモリーまで共有されます。ksm サービスを起動して、KSM がより多くのメモリーを共有するようにします。
# systemctl start ksm
Starting ksm:                                              [  OK  ]
Theksm サービスをデフォルトの起動シーケンスに追加できます。systemctl コマンドを使用して、ksm サービスを永続化します。
# systemctl enable ksm

8.3.2. KSM チューニングサービス

Theksmtuned サービスは、ループおよび調整により、kernel same-page merging(KSM) 設定を調整しますまた、ゲスト仮想マシンが作成または破棄されると、ksmtuned サービスは libvirt により通知されます。Theksmtuned サービスにはオプションがありません。
# systemctl start ksmtuned
Starting ksmtuned:                                         [  OK  ]
Theksmtuned サービスは、retune パラメーターを使用してチューニング機能を手動で実行するように指示するものです
/etc/ksmtuned.conf ファイルは、ksmtuned サービスの設定ファイルです。以下のファイル出力は defaultksmtuned.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 ファイル内で、ksmd デーモンが非アクティブになる前に 、npages はスキャンするページ分を設定します。この値は、/sys/kernel/mm/ksm/pages_to_scan ファイルでも設定されます。
KSM_THRES_CONST の値は、アクティブ化するしきい値として使用される使用可能なメモリーの量を表しますksmd は、以下のいずれかが発生した場合はアクティベートされます。
  • KSM_THRES_CONST に設定されたしきい値を下回る空きメモリードロップの量。
  • コミットされたメモリー容量およびしきい値 KSM_THRES_CONST は、メモリーの合計量を超えます。

8.3.3. KSM 変数と監視

Kernel same-page merging(KSM)は、監視データを /sys/kernel/mm/ksm/ ディレクトリーに保存します。このディレクトリーのファイルはカーネルにより更新され、KSM の使用と統計の正確な記録です。
以下の一覧にある変数は、上記のように /etc/ksmtuned.conf ファイルの設定可能な変数でもあります。

/sys/kernel/mm/ksm/ にあるファイル:

full_scans
実行された完全スキャン数
merge_across_nodes
異なる NUMA ノードからページをマージできるかどうかを指定します。
pages_shared
共有されたページの合計数
pages_sharing
現在共有されているページ数
pages_to_scan
スキャンされなかったページ数
pages_unshared
共有されなくなったページ数
pages_volatile
揮発性のページ数
run
KSM プロセスが実行しているかどうか
sleep_millisecs
スリープ状態(ミリ秒単位)。
これらの変数は、virsh node-memory-tune コマンドを使用して手動で調整できます。たとえば、以下は、共有メモリーサービスがスリープ状態になる前にスキャンするページ数を指定します。
# virsh node-memory-tune --shm-pages-to-scan number
DEBUG=1 行が /etc/ksmtuned.conf ファイルに追加されると、KSM チューニングアクティビティーは /var/log /ksmtuned ログファイルに保存されます。ログファイルの場所は、LOGFILE パラメーターで変更できます。ログファイルの場所の変更は推奨されず、SELinux 設定の特別な設定が必要になる場合があります。

8.3.4. KSM の非アクティブ化

Kernel same-page merging(KSM)にはパフォーマンスのオーバーヘッドがあり、特定の環境やホストシステムでは大きすぎる可能性があります。KSM には、ゲスト全体で情報を漏えいするのに使用可能な、サイドチャネルも導入される可能性があります。これが懸念される場合は、KSM をゲストごとに無効にすることができます。
KSM を、ksmtuned サービスおよびksm サービスを停止すると 、非アクティブにすることができます。ただし、この操作は再起動後に維持されません。KSM を無効にするには、root としてターミナルで以下を実行します。
# systemctl stop ksmtuned
Stopping ksmtuned:                                         [  OK  ]
# systemctl stop ksm
Stopping ksm:                                              [  OK  ]
ksmtuned を停止して 、ksm は KSM を非アクティブにしますが、このアクションは再起動後に維持されません。systemctl コマンドを使用して、KSM を永続的に無効にします。
# systemctl disable ksm
# systemctl disable ksmtuned
KSM を無効にした場合は、KSM を無効にする前に共有されていたメモリーページは共有されます。システムの PageKSM をすべて削除するには、以下のコマンドを使用します。
# echo 2 >/sys/kernel/mm/ksm/run
これが実行されると、khugepaged デーモンは、KVM ゲストの物理メモリーに透過的なヒュージページを再構築できます。# echo 0 >/sys/kernel/mm/ksm/run を使用すると、KSM が停止しますが、以前に作成した KSM ページをすべて共有しません(これは # systemctl stop ksmtuned コマンドと同じです)。

第9章 NUMA

これまでは、AMD64 システムおよび Intel 64 システム上のメモリーはすべて、全 CPU が同等でアクセスできるようになりました。Uniform Memory Access(UMA)として知られるアクセス時間は、どの CPU で操作を行うかに関係なく同じです。
この動作は、最新の AMD64 および Intel 64 プロセッサーではなくなりました。Non-Uniform Memory Access(NUMA)では、システムメモリーは NUMA ノードに分割されます。これは、ソケットまたはシステムメモリーのローカルサブセットへのアクセスレイテンシーが同一の特定の CPU セットに対応します。
本章では、仮想化環境におけるメモリー割り当てと NUMA チューニングの設定について説明します。

9.1. NUMA メモリー割り当てのポリシー

以下のポリシーは、システムのノードからメモリーが割り当てられる方法を定義します。
Strict
厳密なポリシーは、ターゲットノードにメモリーを割り当てることができない場合に割り当てが失敗することを意味します。
メモリーモード属性を定義せずに NUMA ノードセット一覧を指定する(デフォルトは strict モード)。
Interleave
メモリーページは、ノードセットで指定されるノード間で割り当てられますが、ラウンドロビンで割り当てられます。
Preferred
メモリーは、単一の優先メモリーノードから割り当てられます。十分なメモリーが利用できない場合には、他のノードからメモリーを割り当てることができます。
目的のポリシーを有効にするには、ドメイン XML ファイルの <memory mode> 要素の値として設定します。
<numatune>
        <memory mode='preferred' nodeset='0'>
</numatune>
重要
メモリーが strict モードでオーバーコミットされ、ゲストに十分なスワップ領域がない場合、カーネルは追加のメモリーを取得するためにゲストプロセスを強制終了します。Red Hat は、このような状況を防ぐために、preferred の割り当てを使用して単一ノードセット(例: nodeset='0')を指定することを推奨します。

9.2. NUMA の自動負荷分散

NUMA の自動分散により、NUMA ハードウェアシステムで実行しているアプリケーションのパフォーマンスが向上します。Red Hat Enterprise Linux 7 システムでデフォルトで有効になっています。
通常、アプリケーションは、プロセスのスレッド数がスレッドと同じ NUMA ノード上のメモリーにアクセスする場合に最適です。NUMA の自動分散により、(スレッドまたはプロセスのように)タスクにアクセスしているメモリーに近いに移動します。また、アプリケーションデータを、それを参照するタスクに移動します。これは、自動 NUMA 分散がアクティブになると、カーネルによって自動的に行われます。
NUMA の自動分散は、システムで複数のアルゴリズムとデータ構造を使用します。この構造は、アクティブで、自動 NUMA 分散がシステム上でアクティブの場合にのみ割り当てられます。
  • Periodic NUMA unmapping of process memory (プロセスメモリーの定期的な NUMA マッピング解除)
  • NUMA hinting fault (NUMA ヒンティングフォールト)
  • Migrate-on-Fault (MoF) - メモリーを使用するプログラムが実行される場所にメモリーを移動します。
  • task_numa_placement - 実行中のプログラムをそれらのメモリーの近くに移動します。

9.2.1. 自動 NUMA バランスの設定

Red Hat Enterprise Linux 7 では、自動 NUMA 分散はデフォルトで有効になっており、NUMA プロパティーのハードウェア上でブートすると自動的に有効になります。
NUMA バランシングは、以下の両方の条件が満たされると有効になります。
  • # numactl --hardware shows multiple nodes
  • # cat /proc/sys/kernel/numa_balancing1 を表示
手動での NUMA チューニングにより、NUMA の自動分散が上書きされ、それらのアプリケーションの定期的なメモリーマッピング、NUMA 障害、移行、および NUMA の自動配置を無効にします。
システム全体での手動の NUMA チューニングがより望ましい場合があります。
NUMA の自動分散を無効にするには、以下のコマンドを使用します。
# echo 0 > /proc/sys/kernel/numa_balancing
NUMA の自動分散を有効にするには、以下のコマンドを使用します。
# echo 1 > /proc/sys/kernel/numa_balancing

9.3. Libvirt NUMA の調整

通常、NUMA システムのパフォーマンスは、1 つの NUMA ノード上のリソース量にゲストサイズを制限することで実現されます。 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
注記
-cnumastat を実行すると、出力がコンパクトになります。-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 3
以下の例では、それぞれ合計 4 GB の RAM が格納されている 4 つのホスト NUMA ノードを示しています(MemTotal)。各ドメイン(MemFree)でほぼすべてのメモリーが使用されます。実行には 4 つのドメイン(仮想マシン)があります。ドメイン 'rhel7-0' には、特定のホスト NUMA ノードにピニングされていない 1.5GB メモリーがあります。ただし、ドメイン「rhel7-2」には、ホストノードに 1 に固定された 4GB メモリーと 4 NUMA ノードがあります。
ホストの NUMA ノードの統計を出力するには、環境の nodestats.py スクリプトを作成します。スクリプトの例は、/usr/share/doc/libvirt-python-version/examples/nodestats.pylibvirt-python パッケージファイルにあります。スクリプトへの特定のパスは、rpm -ql libvirt-python コマンドを使用して表示できます。

9.3.2. NUMA vCPU ピニング

vCPU ピニングは、ベアメタルシステムでのタスクピニングと同様の利点を提供します。vCPU は、ホストのオペレーティングシステムのユーザー空間タスクとして実行されるので、ピニングすることでキャッシュの効率性が向上します。この例としては、すべての仮想 CPU スレッドが同じ物理ソケットで実行している環境であるため、L3 キャッシュドメインを共有します。
注記
Red Hat Enterprise Linux 7.0 から 7.2 までのバージョンでは、アクティブな vCPU をピニングすることはできません。ただし、Red Hat Enterprise Linux 7.3 では、非アクティブな vCPU のピニングも利用できます。
vCPU ピニングを numatune と組み合わせると、NUMA ミスを回避できます。NUMA ミスによるパフォーマンスへの影響は大きく、一般的にはパフォーマンスが 10% 以上になります。vCPU ピニングおよび numatune を一緒に設定する必要があります。
仮想マシンがストレージまたはネットワーク I/O タスクを実行している場合、すべての仮想 CPU およびメモリーを、I/O アダプターに物理的に接続されているのと同じ物理ソケットに固定することが有益です。
注記
lstopo ツールを使用して NUMA トポロジーを可視化できます。また、仮想 CPU が同じ物理ソケット上のコアにバインディングされていることを確認することもできます。lstopo の詳細は、以下のナレッジベースのアーティクルを参照してください
重要
ピニングにより、物理コアよりも多くの仮想 CPU が多くなると、複雑性が高まります。
以下の XML 設定例は、物理 CPU 0-7. にピニングされたドメインプロセスがあります。vCPU スレッドは、独自の cpuset に固定されています。たとえば、vCPU0 は物理 CPU 0 にピニングされ、vCPU1 は物理 CPU 1 に固定されます。
<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>
vcpu と vcpupin タグには直接関係があります。vcpupin オプションが指定されていない場合、値は自動的に判断され、親 vcpu タグオプションから継承されます。以下の設定は、vcpu 5 の <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. ドメインプロセス

Red Hat Enterprise Linux で利用できるように、libvirt は libnuma を使用してドメインプロセスのメモリーバインディングポリシーを設定します。これらのポリシーの nodeset は、静的 (ドメイン XML で指定)または auto (numad にクエリーで設定)のいずれかとして設定できます。<numatune> タグ内でこれらを設定する方法の例は、以下の XML 設定を参照してください。
<numatune>
        <memory mode='strict' placement='auto'/>
</numatune>
<numatune>
        <memory mode='strict' nodeset='0,2-3'/>
</numatune>
libvirt は sched_setaffinity(2) を使用してドメインプロセスの CPU バインディングポリシーを設定します。cpuset オプションは、静的 (ドメイン XML で指定) または自動(numad にクエリーを設定して)のいずれかになります。<vcpu> タグ内でこれらを設定する方法の例は、以下の XML 設定を参照してください。
<vcpu placement='auto'>8</vcpu>
<vcpu placement='static' cpuset='0-10,ˆ5'>8</vcpu>
<vcpu><numatune> に使用する配置モードには、暗黙的な継承ルールがあります。
  • <numatune> の配置モードは、<vcpu> の同じ配置モードにデフォルト設定されるか、<nodeset> が指定されている場合は静的に設定されます
  • 同様に、<vcpu> の配置モードは <numatune> の同じ配置モードにデフォルト設定されるか、<cpuset> が指定されている場合は static に設定されます。
つまり、ドメインプロセスの CPU のチューニングとメモリーのチューニングを個別に指定でき、個別に定義することも可能ですが、他の配置モードに依存するよう設定することもできます。
さらに、起動時にすべての vCPU を固定せずに選択した数の vCPU を起動できるように numad を使用してシステムを設定することもできます。
たとえば、32 vCPU が搭載されたシステムで 8 つの vCPU のみを有効にするには、以下のような XML を設定します。
<vcpu placement='auto' current='8'>32</vcpu>
注記

9.3.4. ドメイン仮想 CPU スレッド

ドメインプロセスのチューニングに加え、libvirt では、XML 設定の各 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>
このタグでは、libvirt は cgroup または sched_setaffinity(2) を使用して、vcpu スレッドを指定された cpuset に固定します。
注記
<cputune> の詳細は、以下の URL を参照してください。 http://libvirt.org/formatdomain.html#elementsCPUTuning
また、単一の NUMA ノードを超える仮想 CPU を持つ仮想マシンを設定する必要がある場合は、ゲストがホスト上の NUMA トポロジーを検出するようにホストを設定します。これにより、CPU、メモリー、および NUMA ノードのマッピングが 1:1 になります。たとえば、以下は、4 つの仮想 CPU および 6 GB メモリーを持つゲストと、以下の NUMA 設定を持つホストに適用できます。
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
このシナリオでは、以下のドメイン XML 設定を使用します。
<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. キャッシュ割り当て技術を使用したパフォーマンスの改善

特定の CPU モデルでカーネルが提供する Cache Allocation Technology(CAT)を使用できます。これにより、リアルタイムパフォーマンスを向上させるために、vCPU スレッドのホスト CPU のキャッシュの一部の割り当てが可能になります。
cachetune タグ内で vCPU キャッシュの割り当てを設定する方法は、以下の XML 設定を参照してください。
<domain>
  <cputune>
    <cachetune vcpus='0-1'>
      <cache id='0' level='3' type='code' size='3' unit='MiB'/>
      <cache id='0' level='3' type='data' size='3' unit='MiB'/>
    </cachetune>
  </cputune>
</domain>
上記の XML ファイルでは、L3CODE の場合と L3DATA 用に 1 度ずつ割り当てられる L3 キャッシュ(level='3' id='0')から、仮想 CPU が 3 MiB にスレッドを設定します。
注記
単一の仮想マシンには複数の <cachetune> 要素を指定できます。
詳細は、アップストリームの libvirt ドキュメントcachetune を参照してください。

9.3.6. emulatorpin の使用

ドメインプロセスピニングポリシーをチューニングする別の方法は、<cputune> 内で <emulatorpin> タグを使用することです。
<emulatorpin> タグは、エミュレータースレッド(仮想 CPU を含めないドメインのサブセット)がピニングされるホスト物理 CPU を指定します。<emulatorpin> タグにより、エミュレータースレッドプロセスに正確なアフィニティーを設定できます。これにより、vhost スレッドは物理 CPU とメモリーと同じサブセットで実行され、キャッシュのローカル性の利点が得られます。 以下に例を示します。
<cputune>
        <emulatorpin cpuset="1-3"/>
</cputune>
注記
Red Hat Enterprise Linux 7 では、自動 NUMA 分散がデフォルトで有効になっています。NUMA の自動分散により、<emulatorpin> を手動でチューニングする必要性が軽減されます。vhost-net エミュレータースレッドは仮想 CPU タスクをより確実に従えるためです。NUMA 「NUMA の自動負荷分散」

9.3.7. virsh で vCPU ピニングの調整

重要
以下はコマンドのみの例です。実際の環境に応じて値に置き換える必要があります。
以下の virsh コマンドは、物理 CPU 2 に ID が 1 の vcpu スレッド rhel7 をピニングします。
% virsh vcpupin rhel7 1 2
virsh コマンドを使用して、現在の vcpu ピニング設定を取得することもできます。以下に例を示します。
% virsh vcpupin rhel7

9.3.8. virsh でドメインプロセス CPU ピニングの調整

重要
以下はコマンドのみの例です。実際の環境に応じて値に置き換える必要があります。
emulatorpin オプションは、CPU アフィニティー設定を各ドメインプロセスに関連付けられたスレッドに適用します。完全なピニングには、(前述したように) virsh vcpupin と各ゲストに virsh emulatorpin の両方を使用する必要があります。以下に例を示します。
% virsh emulatorpin rhel7 3-4

9.3.9. virsh を使用したドメインプロセスメモリーポリシーのチューニング

ドメインプロセスメモリーは、動的に調整できます。以下のコマンド例を参照してください。
% virsh numatune rhel7 --nodeset 0-10
このようなコマンドの例は、man ページの virsh を参照してください。

9.3.10. ゲスト NUMA トポロジー

ゲスト NUMA トポロジーは、ゲスト仮想マシンの XML の <cpu> タグ内の <numa> タグを使用して指定できます。以下の例を参照して、適切な値を置き換えます。
<cpu>
        ...
    <numa>
      <cell cpus='0-3' memory='512000'/>
      <cell cpus='4-7' memory='512000'/>
    </numa>
    ...
</cpu>
<cell> 要素は NUMA セルまたは NUMA ノードを指定します。cpus ノードの一部である CPU または範囲を指定し、memory は kibibytes でノードメモリーを指定します(1024 バイトブロック)。各セルまたはノードには、0 から始まる順番に cellid または nodeid が割り当てられます。
重要
CPU ソケット、コア、およびスレッドのトポロジーが設定されたゲスト仮想マシンの NUMA トポロジーを変更する場合、単一のソケットに属するコアとスレッドが同じ NUMA ノードに割り当てられるようにしてください。同じソケットのスレッドまたはコアが別の NUMA ノードに割り当てられている場合、ゲストは起動に失敗する可能性があります。
警告
Red Hat Enterprise Linux 7 では、ゲスト NUMA トポロジーを同時に使用することは Red Hat Enterprise Linux 7 ではサポートされておらず、Red Hat Virtualization または Red Hat OpenStack Platform などの階層型製品でのみ利用できます。

9.3.11. PCI デバイスの NUMA ノードの局所性

新規仮想マシンを起動する際には、ホストの NUMA トポロジーと PCI デバイスの両方を確認することが重要になります。PCI パススルーが要求されると、ゲストは正しい NUMA ノードに固定され、メモリーのパフォーマンスを最適化します。
たとえば、ゲストが NUMA ノード 0-1 にピニングされていても、その PCI デバイスの 1 つがノード 2 となっている場合は、ノード間のデータ転送に時間がかかります。
Red Hat Enterprise Linux 7.1 以前では、libvirt はゲスト XML の PCI デバイスの NUMA ノードの局所性を報告して、管理アプリケーションによるパフォーマンス決定を改善できるようにします。
この情報は、/sys/devices/pci*/*/numa_nodesysfs ファイルに表示されます。これらの設定を検証する 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 のエミュレーション* およびディスク sd* は NUMA ノード 0 に接続され、コア 0,2,4,6,8,10,12,14 です。
  • NIC p1* および ib* は、NUMA ノード 1、コア 1、3、7、9、11、13、15 に接続されています。

9.4. NUMA-Aware Kernel SamePage Merging(KSM)

Kernel SamePage Merging(KSM)により、仮想マシンが同一のメモリーページを共有できます。KSM は、システムが NUMA メモリーを使用していることを検出し、異なる NUMA ノード間でページのマージを制御することができます。
sysfs /sys/kernel/mm/ksm/merge_across_nodes パラメーターを使用して、異なる NUMA ノード間でページのマージを制御します。デフォルトでは、すべてのノードのページは結合できます。このパラメーターをゼロに設定すると、同じノードのページのみがマージされます。
通常、システムメモリーを過剰にサブスクライブしない限り、KSM 共有を無効にすることでランタイムパフォーマンスが向上します。
重要
複数のゲスト仮想マシンで KSM がノード全体でマージされる場合、ゲストと CPU は、マージした KSM ページへのアクセスレイテンシーが大幅に増大する可能性があります。
ハイパーバイザーに対し、ゲストの共有ページを無効にするように指示するには、ゲストの XML に以下の設定を追加します。
<memoryBacking>
         <nosharepages/>
</memoryBacking>
<memoryBacking> 要素を使用してメモリー設定を調整する方法は、「virsh によるメモリーのチューニング」

付録A 改訂履歴

改訂履歴
改訂 1.0-35Thus May 23 2019Jiri Herrmann
7.7 ベータ版公開用バージョン
改訂 1.0-34Tue Oct 25 2018Jiri Herrmann
7.6 GA 公開用バージョン
改訂 1.0-32Tue Aug 14 2018Jiri Herrmann
7.6 ベータ版公開用バージョン
改訂 1.0-31Wed Apr 4 2018Jiri Herrmann
7.5 GA 公開用バージョン
改訂 1.0-27Mon Jul 27 2017Jiri Herrmann
7.4 GA 公開用バージョン
改訂 1.0-24Mon Oct 17 2016Jiri Herrmann
7.3 GA 公開用バージョン
改訂 1.0-22Mon Dec 21 2015Laura Novich
複数のバグを修正するためのガイドの再公開
改訂 1.0-19Thu Oct 08 2015Jiri Herrmann
改訂履歴の処理

法律上の通知

Copyright © 2019 Red Hat, Inc.
このドキュメントは、Red Hat が Creative Commons Attribution-ShareAlike 3.0 Unported License に基づいてライセンスを提供しています。If you distribute this document, or a modified version of it, you must provide attribution to Red Hat, Inc. and provide a link to the original.If the document is modified, all Red Hat trademarks must be removed.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent.Red Hat Software Collections is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission.We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.