9.3. 設定ツール

Red Hat Enterprise Linux ではシステムの設定に役立つツールをいくつか提供しています。本セクションでは利用できるツールを簡単に説明し、Red Hat Enterprise Linux 7 でネットワーク関連のパフォーマンスの問題を解決する場合のツールの使用例を紹介しています。
ただし、ネットワークパフォーマンスに関連する問題はハードウェアが正常に機能していない、またはインフラストラクチャーが不完全であることが原因で発生する場合もありますので注意が必要です。ツールを使ってネットワークスタックのチューニングを行う前に、まずハードウェアおよびインフラストラチャーが期待通りに動作しているか必ず確認されることを強く推奨しています。
また、ネットワークパフォーマンスの特定の問題についてはネットワークのサブシステムを再設定するのではなくアプリケーション側を変更することで解決するものもあります。一般的にはアプリケーションが posix 呼び出しを頻繁に行うよう設定すると解決することがよくあります。アプリケーション領域にデータをキュー待ちさせることになってもデータを柔軟に格納して必要に応じメモリーにスワップインしたりスワップアウトすることができるようになるためです。

9.3.1. ネットワークパフォーマンス向けの Tuned プロファイル

Tuned サービスではいくつかの使用例でパフォーマンスを改善させるプロファイルを数種類用意しています。以下のプロファイルはネットワークパフォーマンの改善に役立つプロファイルになります。
  • latency-performance
  • network-latency
  • network-throughput
プロファイルについての詳細は「tuned-adm」を参照してください。

9.3.2. ハードウェアバッファーの設定

多数のパケットがハードウェアバッファーによってドロップされる場合に考えられるソリューションがいくつかあります。
入力トラフィックの速度を落とす
キューを満たす速度を下げるには、受信トラフィックのフィルター、参加するマルチキャストグループ数の削減、またはブロードキャストトラフィック量の削減を行います。受信トラフィックのフィルター方法に関する詳細は『Red Hat Enterprise Linux 7 セキュリティーガイド』を参照してください。マルチキャストグループの詳細は Red Hat Enterprise Linux 7 のクラスタリング関連のドキュメントを参照してください。ブロードキャストのトラフィックの詳細は『Red Hat Enterprise Linux 7 システム管理者のガイド』または設定するデバイスに関するドキュメントを参照してください。
ハードウェアバッファキューのサイズ変更
キューのサイズを大きくすることでドロップされてしまうパケット数を減らしオーバーフローを防ぎます。ethtool コマンドでネットワークデバイスの rx/tx パラメーターを修正します。
# ethtool --set-ring devname value
キューの排出の割合を変更する
デバイス加重はデバイスで一度 (スケジュールされているプロセッサーのアクセス 1 回) に受信できるパケット数を参照します。dev_weight パラメーターで管理されているデバイス加重を増やすことでキューが排出される割合を増加させることができます。一時的に変更する場合は /proc/sys/net/core/dev_weight ファイルの内容を編集します。永続的に変更する場合は procps-ng パッケージで提供される sysctl を使って変更します。
キューの排出の割合を変更するのがネットワークパフォーマンスの低下を軽減する最もシンプルな方法になります。ただし、デバイスで一度に受信できるパケット数を増やすと余分なプロセッサー時間を使用することになります。この間、他のプロセッサーはスケジュールに入れられないため、別のパフォーマンスの問題を引き起こす可能性があります。

9.3.3. 割り込みキューの設定

分析結果が待ち時間の高さを示している場合はパケットの受信を割り込みベースではなくポーリングベースに変更すると改善される可能性があります。

9.3.3.1. ビジーポーリングの設定

ビジーポーリングはソケット層のコードにネットワークデバイスの受信キューをポーリングさせ、ネットワークの割り込みは無効にすることでネットワーク受信パス内の待ち時間を低減します。このため割り込みおよびその結果となるコンテキストスイッチによる遅延が解消されます。ただし CPU の使用率も増大します。ビジーポーリングでは CPU がスリープ状態になるのが阻止されるため余分な電力消費が発生する可能性があります。
ビジーポーリングはデフォルトでは無効になっています。以下の手順で特定のソケットでのビジーポーリングを有効にします。
  • sysctl.net.core.busy_poll0 以外の値に設定します。このパラメーターはソケットのポーリングと選択用デバイスキューでパケットを待機する時間を管理します (マイクロ秒単位)。Red Hat では 50 の設定を推奨しています。
  • SO_BUSY_POLL ソケットオプションをソケットに追加します。
グローバルにポーリングを有効にする場合は sysctl.net.core.busy_read のパラメーターも 0 以外の値に設定する必要があります。このパラメーターはソケットの読み取り用デバイスキューでパケットを待機する時間を管理します (マイクロ秒単位)。また、SO_BUSY_POLL オプションのデフォルト値も設定されます。Red Hat ではソケット数が少ない場合は 50、ソケット数が多い場合は 100 の設定を推奨しています。ソケット数が非常に多くなる場合は (数百以上) 代わりにepoll を使用します。
ビジーポーリング動作は次のドライバーで対応しています。また、Red Hat Enterprise Linux 7 でも対応のドライバーになります。
  • bnx2x
  • be2net
  • ixgbe
  • mlx4
  • myri10ge
Red Hat Enterprise Linux 7.1 からは次のコマンドを実行するとデバイスかビジーポーリングに対応するどうかをチェックすることもできるようになります。
# ethtool -k device | grep "busy-poll"
上記のコマンドを実行して busy-poll: on [fixed] が返された場合はそのデバイスでビジーポーリングを使用することができます。

9.3.4. ソケット受信キューの設定

分析結果がソケットキューの排出の割合が遅すぎるためパケットがドロップされてしまうことを示している場合は、このことが原因となるパフォーマンスの問題を軽減する方法がいくつかあります。
受信トラフィックの速度を下げる
パケットがキューに到達する前にフィルターをかけたりドロップする、またはデバイスの加重を低くするなどの方法でキューが満杯になる割合を低下させます。
アプリケーションのソケットキューの深さを増やす
限られたトラフィック量を集中的に受信するようなソケットキューの場合、その集中的なトラフィック量に合うようソケットキューの深さを増やすとパケットがドロップされなくなる場合があります。

9.3.4.1. 受信トラフィックの速度を下げる

受信トラフィックの速度を下げるには、受信トラフィックにフィルターをかけたり、ネットワークインターフェースカードのデバイス加重を減らします。受信トラフィックのフィルター方法に関する詳細は『Red Hat Enterprise Linux 7 セキュリティーガイド』を参照してください。
デバイス加重はデバイスで一度 (スケジュールされているプロセッサーのアクセス 1 回) に受信できるパケット数を参照します。デバイス加重は dev_weight パラメーターで管理します。一時的に変更する場合は /proc/sys/net/core/dev_weight ファイルの内容を編集します。永続的に変更する場合は procps-ng パッケージで提供される sysctl を使って変更します。

9.3.4.2. キューの深さを増やす

ソケットキューの排出の割合を改善させる場合、アプリケーションのソケットキューの深さを増やすのが一般的には最も簡単な方法になりますが長期的なソリューションにはならない場合が多くあります。
キューの深さを増やすには次のような変更を行うことでソケット受信バッファのサイズを増やします。
/proc/sys/net/core/rmem_default の値を増やす
このパラメーターにより、ソケットで使用される受信バッファーのデフォルトサイズを制御します。この値は /proc/sys/net/core/rmem_max の値以下にする必要があります。
setsockopt を使って SO_RCVBUF に大きな値を設定する
このパラメーターにより、ソケットの受信バッファーの最大サイズを制御します (バイト単位)。getsockopt システムコールを使ってバッファーの現在の値を決定します。この詳細については、socket(7) man ページをご覧ください。

9.3.5. RSS (Receive-Side Scaling) の設定

RSS (Receive-Side Scaling) はマルチキュー受信とも呼ばれ、ネットワーク受信プロセスを複数のハードウェアベースの受信キューに分散させることで、インバウンドのネットワークトラフィックを複数の CPU で処理させることができるようになります。RSS は単一 CPU のオーバーロードで発生する受信割り込み処理におけるボトルネックを緩和し、ネットワークの待ち時間を短くすることができます。
ご使用のネットワークインターフェースカードが RSS に対応しているか確定するには、複数の割り込み要求キューが /proc/interrupts 内でそのインターフェースに関連付けられているかどうかチェックします。たとえば、p1p1 インターフェイスを確認する場合は以下を実行します。
# egrep 'CPU|p1p1' /proc/interrupts
   CPU0    CPU1    CPU2    CPU3    CPU4    CPU5
89:   40187       0       0       0       0       0   IR-PCI-MSI-edge   p1p1-0
90:       0     790       0       0       0       0   IR-PCI-MSI-edge   p1p1-1
91:       0       0     959       0       0       0   IR-PCI-MSI-edge   p1p1-2
92:       0       0       0    3310       0       0   IR-PCI-MSI-edge   p1p1-3
93:       0       0       0       0     622       0   IR-PCI-MSI-edge   p1p1-4
94:       0       0       0       0       0    2475   IR-PCI-MSI-edge   p1p1-5
上記の出力は NIC ドライバーにより p1p1 インターフェースに 6 つの受信キューが作成されたことを示しています (p1p1-0 から p1p1-5)。また、各キューでいくつの割り込みが処理されたか、どの CPU が割り込みを処理したかも示しています。この例の場合、システムには 6 つの CPU があり、この NIC ドライバーはデフォルトで 1 CPU ごと 1 つのキューを作成するためキューが 6 つ作成されています。NIC ドライバーでは一般的なパターンです。
別の方法では、ネットワークドライバーが読み込まれた後に ls -1 /sys/devices/*/*/device_pci_address/msi_irqs の出力をチェックすることもできます。たとえば、PCI アドレスが 0000:01:00.0 のデバイスをチェックするには、以下のコマンドを実行するとそのデバイスの割り込み要求キューを一覧表示できます。
# ls -1 /sys/devices/*/*/0000:01:00.0/msi_irqs
101
102
103
104
105
106
107
108
109
RSS はデフォルトで有効になっています。RSS のキューの数 (または、ネットワークアクティビティーを処理する CPU 数) は該当するネットワークデバイスドライバーで設定されます。bnx2x ドライバーは num_queuessfc ドライバーは rss_cpus パラメーターで設定されます。いずれにしても、通常は /sys/class/net/device/queues/rx-queue/ で設定されます。device はネットワークデバイスの名前 (eth1 など)、rx-queue は該当する受信キューの名前になります。
RSS を設定する場合はキューの数の設定は物理 CPU コアごと 1 キューに限定することを推奨しています。分析ツール上では複数のハイパースレッドが別々のコアとして表示されることがよくありますが、ハイパースレッドなどの論理コアを含むすべてのコアにキューを設定するのがネットワークパフォーマンスの改善につながるとは証明されていません。
RSS が有効になっていると、ネットワーク処理は各 CPU がキューに登録した処理量に基づいて CPU 間で均等に分散されます。ただし、ethtool --show-rxfh-indir および --set-rxfh-indir パラメーターを使ってネットワークアクティビティーの配分方法を修正したり、特定タイプのネットワークアクティビティーを他より重要なアクティビティーとして加重することもできます。
irqbalance デーモンを RSS と併用するとノード間メモリー転送やキャッシュラインバウンスの可能性が低減されます。ネットワークパケット処理の待ち時間が少なくなります。

9.3.6. 受信パケットステアリング (RPS) の設定

受信パケットステアリング (Receive Packet Steering ー RPS) はパケットを処理のため特定の CPU にダイレクトするという点では RSS と似ています。しかし、RPS はソフトウェアレベルで実装されるため単一ネットワークインターフェースカードのハードウェアキューがネットワークトラフィックでボトルネックにならないよう阻止する際に役立ちます。
RPS には ハードウェアベースの RSS と比較して、以下のような利点があります。
  • RPS はすべてのネットワークインターフェースカードで使用できます。
  • 新たなプロトコルに対応するようソフトウェアフィルターを簡単に追加することができます。
  • ネットワークデバイスのハードウェア割り込み率は上がりません。ただし、プロセッサー間の割り込みが生まれます。
RPS は /sys/class/net/device/queues/rx-queue/rps_cpus ファイル内でネットワークデバイスおよび受信キューごとに設定されます。device はネットワークデバイスの名前 (eth0 など)、rx-queue は該当する受信キューの名前です (rx-0 など)。
rps_cpus ファイルのデフォルト値は 0 です。この値の場合は RPS は無効です。したがってネットワーク割り込みを処理する CPU がパケットも処理します。
RPS を有効にするには、指定されたネットワークデバイスおよび受信キューからのパケットを処理する CPU で該当ファイル rps_cpus を設定します。
rps_cpus ファイルはコンマで区切った CPU ビットマップを使用します。つまり、CPU にインターフェース上の受信キューの割り込みを処理させるには、ビットマップ上の CPU 位置の値を 1 に設定します。たとえば、CPU 0、1、2、および 3 で割り込みを処理する場合は rps_cpus の値を f (15 の 16 進数表記) に設定します。2 進数表記では、15 は 00001111 (1+2+4+8) で表されます。
単一の送信キューのネットワークデバイスでは、同一メモリードメイン内の CPU を使用するように RPS を設定すると、最善のパフォーマンスが達成できます。これは、NUMA 以外のシステム上では、利用可能な CPU すべてが使用されることを意味します。ネットワーク割り込み率が非常に高い場合は、ネットワーク割り込みを処理する CPU を除外するとパフォーマンスが改善する場合もあります。
複数キューのネットワークデバイスでは、通常、RPS と RSS の両方を設定する利点はありません。これは、RSS はデフォルトで CPU を各受信キューにマップするように設定されるためです。ただし、CPU よりもハードウェアキューの方が少ない場合、および同一メモリードメインの CPU を使用するように RPS が設定されている場合は、RPS が利点ももたらす可能性があります。

9.3.7. RFS (Receive Flow Steering) の設定

CPU キャッシュのヒット率を高めネットワークの待ち時間を減らすため RPS の動作を拡張したのが RFS (Receive Flow Steering) です。RPS はキューの長さのみに基づいてパケットを転送する一方、RFS は RPS のバックエンドを使用して最適な CPU を計算してからパケットを消費するアプリケーションの場所に応じてそのパケットを転送します。これにより CPU のキャッシュ効率が高まります。
RFS はデフォルトで無効になっています。RFS を有効にするには、以下の 2 つのファイルを編集する必要があります。
/proc/sys/net/core/rps_sock_flow_entries
このファイルの値を同時にアクティブになるであろう接続の予測最大数に設定します。適度なサーバー負荷の場合は 32768 の設定値を推奨しています。入力した値はすべて直近の 2 の累乗で切り上げられます。
/sys/class/net/device/queues/rx-queue/rps_flow_cnt
device は設定するネットワークデバイス名 (eth0 など)、rx-queue は設定する受信キューになります (rx-0 など)。
rps_sock_flow_entriesN で割った値をこのファイルの値に設定します。N はデバイス上の受信キューの数です。たとえば、rps_flow_entries32768 に設定されていて設定済みの受信キューが 16 ある場合、rps_flow_cnt2048 に設定します。単一キューデバイスの場合は rps_flow_cnt の値は rps_sock_flow_entries の値と同じになります。
一人の送信者から受け取ったデータは複数の CPU には送られません。一人の送信者から受け取ったデータ量が単一 CPU で処理できる量を越えている場合はフレームサイズを大きくして割り込み数および CPU の処理量を減らします。あるいは NIC オフロードオプションまたは高速な CPU の導入を考慮してください。
RFS と併せて numactl または taskset を使用してアプリケーションを特定のコア、ソケット、または NUMA ノードに固定することを検討してみてください。これにより、パケットが間違った順番で処理されることを防ぐことができます。

9.3.8. アクセラレート RFS の設定

アクセラレート RFS はハードウェアに対する支援が加わり RFS の速度が更に高まります。RFS 同様、パケットはパケットを消費するアプリケーションの位置に基づいて転送されます。ただし、従来の RFS とは異なり、パケットはデータを消費するスレッドに対してローカルとなる CPU に直接送信されます。つまりアプリケーションを実行している CPU、またはキャッシュ階層内のその CPU にローカルとなる CPU のいずれかになります。
アクセラレート RFS は、以下の条件が満たされた場合にのみ、利用可能になります。
  • アクセラレート RFS がネットワークインターフェースカード対応になっていること。アクセラレート RFS は ndo_rx_flow_steer() netdevice 関数をエクスポートするカードでサポートされています。
  • ntuple フィルタリングが有効になっていること。
条件が満たされるとキューマッピングに対する CPU が従来の RFS 設定に応じて自動的に推測されます。つまり、キューマッピングに対する CPU は各受信キューのドライバーで設定される IRQ 親和性に応じて推測されるということになります。従来の RFS の設定方法については「RFS (Receive Flow Steering) の設定」を参照してください。
Red Hat では RFS を使用すべき状況でネットワークインターフェースカードがハードウェアアクセラレートに対応している場合は常にアクセラレート RFS の使用を推奨しています。

このページには機械翻訳が使用されている場合があります (詳細はこちら)。