Red Hat Training

A Red Hat training course is available for RHEL 8

第34章 ネットワークパフォーマンスのチューニング

ネットワーク設定のチューニングは、考慮すべき要素が多数ある複雑なプロセスです。たとえば、これには、CPU からメモリーへのアーキテクチャー、CPU コアの量などが含まれます。Red Hat Enterprise Linux は、ほとんどのシナリオに最適化されたデフォルト設定を使用します。ただし、場合によっては、ネットワーク設定をチューニングして、スループットや遅延を増やしたり、パケットドロップなどの問題を解決したりする必要があります。

34.1. ネットワークアダプター設定のチューニング

40 Gbps 以上の高速ネットワークでは、ネットワークアダプター関連のカーネル設定の特定のデフォルト値がパケットドロップやパフォーマンス低下の原因となる可能性があります。これらの設定をチューニングすると、このような問題を防ぐことができます。

34.1.1. nmcli を使用して、高いパケットドロップ率を減らすためにリングバッファーサイズを増やす

パケットドロップ率が原因でアプリケーションがデータの損失、タイムアウト、またはその他の問題を報告する場合は、イーサネットデバイスのリングバッファーのサイズを増やします。

受信リングバッファーは、デバイスドライバーとネットワークインターフェイスコントローラー (NIC) の間で共有されます。カードは、送信 (TX) および受信 (RX) リングバッファーを割り当てます。名前が示すように、リングバッファーは循環バッファーであり、オーバーフローによって既存のデータが上書きされます。NIC からカーネルにデータを移動するには、ハードウェア割り込みと、SoftIRQ とも呼ばれるソフトウェア割り込みの 2 つの方法があります。

カーネルは RX リングバッファーを使用して、デバイスドライバーが着信パケットを処理できるようになるまで着信パケットを格納します。デバイスドライバーは、通常は SoftIRQ を使用して RX リングをドレインします。これにより、着信パケットは sk_buff または skb と呼ばれるカーネルデータ構造に配置され、カーネルを経由して関連するソケットを所有するアプリケーションまでの移動を開始します。

カーネルは TX リングバッファーを使用して、ネットワークに送信する必要がある発信パケットを保持します。これらのリングバッファーはスタックの一番下にあり、パケットドロップが発生する重要なポイントであり、ネットワークパフォーマンスに悪影響を及ぼします。

手順

  1. インターフェイスのパケットドロップ統計を表示します。

    # ethtool -S enp1s0
        ...
        rx_queue_0_drops: 97326
        rx_queue_1_drops: 63783
        ...

    コマンドの出力は、ネットワークカードとドライバーに依存することに注意してください。

    discard または drop カウンターの値が高い場合は、カーネルがパケットを処理できるよりも速く、使用可能なバッファーがいっぱいになることを示します。リングバッファーを増やすと、このような損失を回避できます。

  2. 最大リングバッファーサイズを表示します。

    # ethtool -g enp1s0
     Ring parameters for enp1s0:
     Pre-set maximums:
     RX:             4096
     RX Mini:        0
     RX Jumbo:       16320
     TX:             4096
     Current hardware settings:
     RX:             255
     RX Mini:        0
     RX Jumbo:       0
     TX:             255

    Pre-set maximums セクションの値が Current hardware settings セクションよりも高い場合は、次の手順で設定を変更できます。

  3. このインターフェイスを使用する NetworkManager 接続プロファイルを特定します。

    # nmcli connection show
    NAME                UUID                                  TYPE      DEVICE
    Example-Connection  a5eb6490-cc20-3668-81f8-0314a27f3f75  ethernet  enp1s0
  4. 接続プロファイルを更新し、リングバッファーを増やします。

    • RX リングバッファーを増やすには、次のように入力します。

      # nmcli connection modify Example-Connection ethtool.ring-rx 4096
    • TX リングバッファーを増やすには、次のように入力します。

      # nmcli connection modify Example-Connection ethtool.ring-tx 4096
  5. NetworkManager 接続をリロードします。

    # nmcli connection up Example-Connection
    重要

    NIC が使用するドライバーによっては、リングバッファーを変更すると、ネットワーク接続が短時間中断されることがあります。

34.1.2. パケットドロップを回避するためにネットワークデバイスのバックログキューをチューニングする

ネットワークカードがパケットを受信し、カーネルプロトコルスタックがこれらのパケットを処理する前に、カーネルはこれらのパケットをバックログキューに保存します。カーネルは、CPU コアごとに個別のキューを維持します。

コアのバックログキューがいっぱいの場合、カーネルは、netif_receive_skb() カーネル関数がこのキューに割り当てるそれ以降の受信パケットをすべてドロップします。サーバーに速度が 10 Gbps 以上のネットワークアダプターまたは複数の 1 Gbps アダプターが含まれている場合は、バックログキューのサイズをチューニングしてこの問題を回避します。

前提条件

  • 速度が 10 Gbps 以上、または複数の 1 Gbps ネットワークアダプター

手順

  1. バックログキューのチューニングが必要かどうかを判断し、/proc/net/softnet_stat ファイル内のカウンターを表示します。

    # awk '{for (i=1; i<=NF; i++) printf strtonum("0x" $i) (i==NF?"\n":" ")}' /proc/net/softnet_stat | column -t
    221951548  0      0  0  0  0  0  0  0  0  0  0  0
    192058677  18862  0  0  0  0  0  0  0  0  0  0  1
    455324886  0      0  0  0  0  0  0  0  0  0  0  2
    ...

    この awk コマンドは、/proc/net/softnet_stat の値を 16 進形式から 10 進形式に変換し、表形式で表示します。各行は、コア 0 から始まる CPU コアを表します。

    関連する列は次のとおりです。

    • 最初の列: 受信フレームの総数
    • 2 番目の列: バックログキューがいっぱいであるためにドロップされたフレームの数
    • 最後の列: CPU コア番号
  2. /proc/net/softnet_stat ファイルの 2 番目の列の値が時間の経過とともに増加する場合は、バックログキューのサイズを増やします。

    1. 現在のバックログキューのサイズを表示します。

      # sysctl net.core.netdev_max_backlog
      net.core.netdev_max_backlog = 1000
    2. 次の内容を含む /etc/sysctl.d/10-netdev_max_backlog.conf ファイルを作成します。

      net.core.netdev_max_backlog = 2000

      net.core.netdev_max_backlog パラメーターを現在の値の 2 倍に設定します。

    3. /etc/sysctl.d/10-netdev_max_backlog.conf ファイルから設定をロードします。

      # sysctl -p /etc/sysctl.d/10-netdev_max_backlog.conf

検証

  • /proc/net/softnet_stat ファイルの 2 番目の列を監視します。

    # awk '{for (i=1; i<=NF; i++) printf strtonum("0x" $i) (i==NF?"\n":" ")}' /proc/net/softnet_stat | column -t

    それでも値が増加する場合は、net.core.netdev_max_backlog 値を再度 2 倍にします。パケットドロップカウンターが増加しなくなるまで、このプロセスを繰り返します。

34.1.3. NIC の送信キューの長さを増やして送信エラーの数を減らす

カーネルは、パケットを送信する前に送信キューにパケットを格納します。デフォルトの長さ (1000 パケット) は、通常、10 Gbps には十分です。また、多くの場合、40 Gbps ネットワークにも十分です。ただし、より高速なネットワークの場合、またはアダプターで送信エラーが増加する場合は、キューの長さを増やしてください。

手順

  1. 現在の送信キューの長さを表示します。

    # ip -s link show enp1s0
    2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    ...

    この例では、enp1s0 インターフェイスの送信キューの長さ (qlen) は 1000 です。

  2. ネットワークインターフェイスのソフトウェア送信キューのドロップされたパケットカウンターを監視します。

    # tc -s qdisc show dev enp1s0
    qdisc fq_codel 0: root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64
     Sent 16889923 bytes 426862765 pkt (dropped 191980, overlimits 0 requeues 2)
    ...
  3. 送信エラー数が多い、または増加している場合は、送信キューの長さをより長く設定します。

    1. このインターフェイスを使用する NetworkManager 接続プロファイルを特定します。

      # nmcli connection show
      NAME                UUID                                  TYPE      DEVICE
      Example-Connection  a5eb6490-cc20-3668-81f8-0314a27f3f75  ethernet  enp1s0
    2. 次の内容で /etc/NetworkManager/dispatcher.d/99-set-tx-queue-length-up NetworkManager ディスパッチャースクリプトを作成します。

      #!/bin/bash
      # Set TX queue length on enp1s0 to 2000
      
      if [ "$1" == "enp1s0" ] && [ "$2" == "up" ] ; then
          ip link set dev enp1s0 txqueuelen 2000
      fi
    3. /etc/NetworkManager/dispatcher.d/99-set-tx-queue-length-up ファイルに実行可能ビットを設定します。

      # chmod +x /etc/NetworkManager/dispatcher.d/99-set-tx-queue-length-up
    4. 変更を適用します。

      # nmcli connection up Example-Connection

検証

  1. 送信キューの長さを表示します。

    # ip -s link show enp1s0
    2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 2000
    ...
  2. ドロップされたパケットカウンターを監視します。

    # tc -s qdisc show dev enp1s0

    dropped カウンターがまだ増加する場合は、送信キューの長さを再度 2 倍にします。カウンターが増加しなくなるまで、このプロセスを繰り返します。