Azure 仮想マシンのネットワーク スループットの最適化

Azure仮想マシン (VM) には、スループットと一貫性を向上させるために最適化できる既定のネットワーク設定があります。 この記事では、Windows および Linux VM のネットワーク パフォーマンスを最適化する方法について説明します。

Important

この記事で説明する最適化の多く (輻輳制御、キューの規範、バッファー サイズ、NIC チューニングなど) は、システム間のトラフィックフローに影響します。

最適な結果を得るには、次のようなワークロードに参加しているすべての仮想マシンに対して、これらの設定を一貫して適用します。

  • クライアント システム
  • サーバー システム

これらの構成を仮想マシンのサブセットにのみ適用すると、次のことができます。

  • 一貫性のないスループット
  • パケット再送信の増加
  • 最適でない輻輳時の動作

データ パス全体の変更を常に検証し、パフォーマンスをエンドツーエンドでテストします。

Windows仮想マシン

Windows 仮想マシンで "高速ネットワーク" がサポートされている場合は、その機能を有効にして最適なスループットを実現します。 詳細については、高速ネットワークを使用した Windows VM の作成に関する記事を参照してください。

他のすべてのWindows VM では、受信側スケーリング (RSS) は、RSS のない VM よりも高い最大スループットを提供できます。 RSS は既定で無効になっている可能性があります。 RSS が有効になっているかどうかを確認し、有効にするには、次の手順に従います。

  1. Get-NetAdapterRss PowerShell コマンドを使用して、ネットワーク アダプターに対して RSS が有効になっているかどうかを確認します。 次の例では、 Get-NetAdapterRss からの出力で RSS が有効になっていないことが示されています。

    Name                    : Ethernet
    InterfaceDescription    : Microsoft Hyper-V Network Adapter
    Enabled                 : False
    
  2. RSS を有効にするには、次のコマンドを入力します。

    Get-NetAdapter | % {Enable-NetAdapterRss -Name $_.Name}
    

    このコマンドには出力がありません。 ネットワーク インターフェイス カード (NIC) の設定を変更し、約 1 分間の一時的な接続損失を引き起こします。 接続が失われている間、"再接続中" を示すダイアログが表示されます。 通常、3 回目の試行後に接続が復元されます。

  3. 再度 Get-NetAdapterRss コマンドを入力して、VM で RSS が有効になっていることを確認します。 成功した場合は、次のような出力が返されます。

    Name                    : Ethernet
    InterfaceDescription    : Microsoft Hyper-V Network Adapter
    Enabled                 : True
    

Linux 仮想マシン

RSS は、Azureの Linux 仮想マシン (VM) で既定で有効になっています。 2017 年 10 月以降にリリースされた Linux カーネルには、Linux VM のスループット向上に役立つ追加のネットワーク最適化オプションが含まれています。

Azure Accelerated Networking を有効にして最適なスループットを実現する

Azure高速ネットワークは、スループットを大幅に向上させ、待機時間とジッターを減らすことができます。 VM のサイズとプラットフォームの生成に応じて、Azureでは、広く利用できる Mellanox と、Microsoftによって開発された MANA という 2 つのテクノロジのいずれかを使用します。

Azure 向けに最適化されたカーネル

Ubuntu (Canonical) や SUSE などの一部のディストリビューションでは、チューニングされたカーネルAzure提供されます

次のコマンドを使用して、Azure カーネルを使用していることを確認します。カーネル名には通常、azureが含まれます。

uname -r

# Sample output for an Azure kernel on an Ubuntu Linux VM
6.8.0-1017-azure

他の Linux ディストリビューション

最新のディストリビューションの多くは、新しいカーネルでのネットワークの大幅な改善を含みます。 カーネルのバージョンを確認し、可能な場合は 4.19 以降を使用します。 新しいカーネルには、より優れたネットワーク動作が含まれており、BBR などの最新の輻輳制御オプションがサポートされています。

Azure の Linux VM で一貫した転送速度を実現する

Linux VM では、特に大規模なリージョン転送中 (たとえば、西ヨーロッパと米国西部の間で 1 GB から 50 GB) の転送速度に一貫性がない可能性があります。 一般的な原因には、古いカーネル、既定のバッファー サイズ、および調整されていない輻輳制御またはキューの規範設定が含まれます。

より安定したスループットを得るには、まず次のベースラインのチューニングを適用したうえで、ワークロードに対して輻輳制御/qdisc の組み合わせをテストしてください。

sysctl の基本調整(コピー&ペースト)

次のベースライン sysctl 設定を適用します。

sudo tee /etc/sysctl.d/99-azure-network-tuning.conf > /dev/null <<'EOF'
# Buffer and memory tuning
# Overall TCP memory pressure thresholds (min, pressure, max pages)
net.ipv4.tcp_mem = 4096 87380 67108864
# Overall UDP memory pressure thresholds (min, pressure, max pages)
net.ipv4.udp_mem = 4096 87380 33554432
# Per-socket TCP read buffer limits (min, default, max bytes)
net.ipv4.tcp_rmem = 4096 87380 67108864
# Per-socket TCP write buffer limits (min, default, max bytes)
net.ipv4.tcp_wmem = 4096 65536 67108864
# Default socket receive buffer size in bytes
net.core.rmem_default = 33554432
# Default socket send buffer size in bytes
net.core.wmem_default = 33554432
# Minimum UDP send buffer per socket in bytes
net.ipv4.udp_wmem_min = 16384
# Minimum UDP receive buffer per socket in bytes
net.ipv4.udp_rmem_min = 16384
# Maximum socket send buffer size in bytes
net.core.wmem_max = 134217728
# Maximum socket receive buffer size in bytes
net.core.rmem_max = 134217728
# Busy polling time in microseconds for low-latency packet receive
net.core.busy_poll = 50
# Busy read time in microseconds when polling sockets
net.core.busy_read = 50

# Extra TCP and networking settings
# Enable TCP timestamps for RTT measurement and PAWS protection
net.ipv4.tcp_timestamps = 1
# Allow safer TIME-WAIT socket reuse for outbound connections
net.ipv4.tcp_tw_reuse = 1
# Expand available ephemeral source port range
net.ipv4.ip_local_port_range = 1024 65535
# Increase packets processed per NAPI polling cycle
net.core.netdev_budget = 1000
# Increase per-socket ancillary/option memory limit in bytes
net.core.optmem_max = 65535
# Disable F-RTO (typically unnecessary on stable wired paths)
net.ipv4.tcp_frto = 0
# Increase maximum listen backlog for pending connections
net.core.somaxconn = 32768
# Increase ingress packet backlog queue length
net.core.netdev_max_backlog = 32768
# Increase per-CPU packet processing quota per softirq cycle
net.core.dev_weight = 64
EOF

sudo sysctl --system

輻輳制御とqdiscテスト(sysctl)

ワークロードの動作が異なります。 これらの組み合わせをテストし、待機時間、スループット、再送信プロファイルに最適な結果を得る組み合わせを維持します。

  1. BBR + FQ (多くの場合、高スループットおよび長距離転送の強力な既定値)
    sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
    sudo sysctl -w net.core.default_qdisc=fq
    
  2. BBR + PFIFO_FAST (バーストまたは混合トラフィックでのキューの動作を比較するのに役立ちます)
    sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
    sudo sysctl -w net.core.default_qdisc=pfifo_fast
    
  3. CUBIC + PFIFO_FAST (互換性と比較のための一般的なレガシ ベースライン)
    sudo sysctl -w net.ipv4.tcp_congestion_control=cubic
    sudo sysctl -w net.core.default_qdisc=pfifo_fast
    

代表的なトラフィックで各オプションを測定し、環境に最適な組み合わせを使用します。

Note

pfifo_fast 可用性はディストリビューション/カーネルによって異なる場合があります。 使用できない場合は、環境内でサポートされている最も近い qdisc オプションを使用し、ベンチマークを続行します。

NIC リング バッファーの UDEV 規則 (TX/RX)

/etc/udev/rules.d/99-azure-ring-buffer.rulesで udev ルールを作成し、リング バッファー設定をネットワーク インターフェイスに適用します。

高速ネットワーク インターフェイス (rx 4096 tx 4096) にhv_pciを使用し、合成rx 1024 tx 1024 インターフェイスのhv_netvscを維持します。

リング バッファーを対話形式で調整したい場合は、このヘルパー ツールを使用することもできます: Azure Linux NIC セットアップ (bash)

Note

このGitHub ツールは省略可能なヘルパーであり、Microsoft Learn 製品ドキュメントの一部ではありません。 広範なロールアウトの前に、非運用環境でスクリプトを確認し、変更をテストします。

# Setup Accelerated Interface ring buffers (Mellanox / Mana) 
SUBSYSTEM=="net", DRIVERS=="hv_pci", ACTION=="add",  RUN+="/usr/sbin/ethtool -G $env{INTERFACE} rx 4096 tx 4096"

# Setup Synthetic interface ring buffers (hv_netvsc)
SUBSYSTEM=="net", DRIVERS=="hv_netvsc*", ACTION=="add",  RUN+="/usr/sbin/ethtool -G $env{INTERFACE} rx 1024 tx 1024"

インターフェイス イベントに対する qdisc の UDEV ルール

ベンチマークが完了し、希望する qdisc を選択したら、 /etc/udev/rules.d/99-azure-qdisc.rules で udev ルールを作成し、ネットワーク インターフェイスが追加または変更されたときにその qdisc を適用します。

<qdisc_choice>は、テスト中に選択した qdisc (fqpfifo_fastなど) に置き換えます。

ACTION=="add|change", SUBSYSTEM=="net", KERNEL=="enp*", PROGRAM="/sbin/tc qdisc replace dev \$env{INTERFACE} root noqueue"
ACTION=="add|change", SUBSYSTEM=="net", KERNEL=="eth*", PROGRAM="/sbin/tc qdisc replace dev \$env{INTERFACE} root <qdisc_choice>"

NIC 送信キューの長さの UDEV 規則

送信キューの長さを増やすには、 /etc/udev/rules.d/99-azure-txqueue-len.rules に次の規則を作成します。

SUBSYSTEM=="net", ACTION=="add|change", KERNEL=="eth*", ATTR{tx_queue_len}="10000" 

IRQのスケジューリング (irqbalance)

ワークロードによっては、irqbalance サービスが特定のノードで IRQ をスケジュールしないように制限できます。 IRQBalance を使用する場合は、 /etc/default/irqbalance を更新して、IRQ をスケジュールしない CPU を指定します。 これらの CPU を除外 するマスクを 決定する必要があります。

マスクの計算方法の詳細については、 こちらをご覧ください

SR-IOV デュアル インターフェイスの動作と副作用

Linux のハイ パフォーマンス ネットワークでは、Azureは SR-IOV を使用します (たとえば、mlx4mlx5などの Mellanox ドライバーを使用します)。 このモデルでは、同じ VM ネットワーク パスの合成インターフェイスと仮想関数 (VF) インターフェイスの両方を確認できます。 詳細については、こちらを参照してください

この設計は想定されていますが、両方のインターフェイスが独立したデータ パスとして扱われると、チューニングとトラブルシューティング中に混乱が生じます。

考えられる副作用は次のとおりです。

  • 設定が 1 つのインターフェイスに適用されているが、トラフィックが他方を使用する場合、ベンチマーク結果に一貫性がありません。
  • 合成パスと VF パス間のフェールオーバー中の予期しない待機時間の急増または再送信。
  • カウンターとパケット キャプチャが間違ったインターフェイスから収集された場合の誤解を招く診断。

リスクを軽減するには:

  • チューニングする前に、ワークロード トラフィックを運ぶインターフェイスを検証します。
  • udev と sysctl のチューニングは、インターフェイス戦略と一貫性を保ちます。
  • 再起動、ドライバーの更新、または高速ネットワーク状態の変更後のスループットと待機時間を再テストします。

その他のメモ

システム管理者は、 /etc/sysctl.d//etc/modules-load.d//etc/udev/rules.d/などの構成ファイルを編集することで、これらの推奨事項を実装できます。 カーネルとドライバーの更新プログラムを注意深く確認して、回帰を回避します。

特定の構成とトラブルシューティングの詳細については、ネットワーク パフォーマンスに関するAzureドキュメントを参照してください。