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
仮想マシンが使用できる最大メモリーです。この値はキビバイト (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)

通常、x86 CPU は 4 kB ページ単位でメモリーに対応しますが、huge page とも言われる 2 MB または 1 GB の大容量ページを使用することも可能です。TLB (Transaction Lookaside Buffer) に対して CPU キャッシュの使用を増加させてパフォーマンスを向上させる場合、huge page メモリー対応で KVM のゲストを導入することができます。
huge page はカーネルの機能で、Red Hat Enterprise Linux 7 ではデフォルトで有効になっています。とくに大容量のメモリーやメモリー集約型のワークロードでパフォーマンスが大幅に向上します。Red Hat Enterprise Linux 7 では、huge page を使用することでページサイズを拡大し、大容量メモリーをより効率的に管理できます。
Red Hat Enterprise Linux 7 システムは、起動時またはランタイム時に割り当てることのできる 2 MB および 1 GB の Huge Page をサポートします。複数の Huge Page のページサイズを有効にする方法については、「起動時またはランタイム時におけるゲストの 1 GB Huge Page の有効化」を参照してください。

8.2.3.1. Transparent Huge Page の設定

Transparent huge page (THP) は、パフォーマンス向上のためにシステム設定を自動的に最適化します。すべての空きメモリーをキャッシュとして使用できるようにすることで、パフォーマンスが向上します。KSM は Transparent huge page の発生を減らす可能性があるため、これを無効にしてから THP を有効にしなければならない場合があります。KSM を無効にする場合は、「KSM の非アクティブ化」を参照してください。
Transparent huge page はデフォルトで有効になります。現在のステータスを確認するには、以下を実行します。
# cat /sys/kernel/mm/transparent_hugepage/enabled
Transparent Huge Page のデフォルト使用を可能にするには、以下を実行します。
# echo always > /sys/kernel/mm/transparent_hugepage/enabled
これにより、/sys/kernel/mm/transparent_hugepage/enabledalways に設定されます。
Transparent Huge Page を無効にするには、以下を実行します。
# echo never > /sys/kernel/mm/transparent_hugepage/enabled
Transparent Huge Page サポートによって静的な Huge Page の使用が妨げられることはありません。ただし、静的な Huge Page が使用されない場合には、通常の 4 kb のページサイズではなく Transparent Huge Page が KVM によって使用されます。

8.2.3.2. 静的 Huge Page の設定

huge page の制御を強化することが望ましい場合があります。ゲスト上で静的な huge page を使用するには、virsh edit を使用してゲスト XML 設定に以下を追加します。
<memoryBacking>
        <hugepages/>
</memoryBacking>
これは、ホストに対して、デフォルトのページサイズではなく huge page を使用してメモリーをゲストに割り当てるよう指示します。
Red Hat Enterprise Linux 7.1 以降では、ホストからの huge page はゲスト NUMA ノードに割り当てることができます。ゲスト XML の <memoryBacking> 要素に huge page サイズ、ユニット、およびゲスト NUMA ノードセットを指定します。詳細情報および設定例については、「ホストの Huge Page の複数のゲスト NUMA ノードへの割り当て」を参照してください。
以下のコマンドを実行して、現在の 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
    
    次に、transparent_hugepage=never をゲストの /etc/grub2.cfg ファイル内の /kernel 行の末尾に追加することで、これをカーネル起動パラメーターに追加します。
  3. huge page をマウントします。
    # mount -t hugetlbfs hugetlbfs /dev/hugepages
  4. libvirtd を再起動してから、以下のコマンドを使って仮想マシンを再起動します。
    # systemctl start libvirtd
    # virsh start virtual_machine
  5. /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 はホストだけでなくゲストにとっても便利ですが、huge page の合計ページ数は必ずホスト内で利用できるページ数より少なくしてください。

8.2.3.3. 起動時またはランタイム時におけるゲストの 1 GB Huge Page の有効化

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

手順8.2 起動時の 1 GB Huge Page の割り当て

  1. 起動時に 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. ホストに 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
  3. ゲスト上で 1GB huge page の使用を有効にするために libvirtd を再起動します。
    # systemctl restart libvirtd

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

1 GB の huge page はランタイム時に割り当てることもできます。ランタイム時の割り当てにより、システム管理者はそれらのページの割り当て元となる NUMA ノードを選択できます。ただし、ランタイム時のページ割り当ては、メモリーの断片化により起動時の割り当てよりも割り当てが失敗する確率が大きくなります。
  1. ランタイム時に 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. ホストに 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
  3. ゲスト上で 1GB huge page の使用を有効にするために libvirtd を再起動します。
    # systemctl restart libvirtd

注記

NUMA ノード固有の huge page を設定するには、「ホストの Huge Page の複数のゲスト NUMA ノードへの割り当て」を参照してください。