优化 Azure 虚拟机网络吞吐量

Azure虚拟机(VM)具有可以优化的默认网络设置,以提高吞吐量和一致性。 本文介绍如何优化 Windows 和 Linux VM 的网络性能。

重要

本文中所述的许多优化(例如,拥塞控制、队列规则、缓冲区大小和 NIC 优化)会影响系统之间的流量流动方式。

为了获得最佳效果,请在整个参与工作负荷的所有虚拟机上一致地应用这些设置,包括:

  • 客户端系统
  • 服务器系统

仅将这些配置应用于一部分虚拟机可能会导致:

  • 吞吐量不一致
  • 数据包重传增加
  • 不理想的拥塞表现

始终验证整个数据路径中的更改并测试端到端性能。

Windows 虚拟机

如果 Windows VM 支持加速网络,请启用该功能以实现最佳吞吐量。 有关详细信息,请参阅创建具有加速网络的 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)设置,并导致临时连接丢失约一分钟。 在连接丢失期间显示“正在重新连接”对话框。 通常在第三次尝试后,连接会还原。

  3. 再次输入 Get-NetAdapterRss 命令,确认 RSS 在 VM 中已启用。 如果成功,将返回以下示例输出:

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

Linux 虚拟机

RSS 默认在 Azure 的 Linux 虚拟机(VM)中启用。 自 2017 年 10 月发布的 Linux 内核包括其他网络优化选项,可帮助 Linux VM 实现更高的吞吐量。

启用 Azure 加速网络以实现最佳吞吐量

Azure加速网络可以显著提高吞吐量并减少延迟和抖动。 根据 VM 大小和平台生成,Azure使用以下两种技术之一:广泛使用的 Mellanox,以及由Microsoft开发的 MANA

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
    

用具有代表性的流量分别测试各个选项,然后针对您的环境采用性能最佳的组合。

注释

pfifo_fast 可用性可能因发行版/内核而异。 如果不可用,请在环境中使用最接近支持的 qdisc 选项并继续基准测试。

NIC 环缓冲区的 UDEV 规则(TX/RX)

创建 udev 规则 /etc/udev/rules.d/99-azure-ring-buffer.rules 以将环形缓冲区设置应用于网络接口:

对加速网络接口(rx 4096 tx 4096)使用 hv_pci,并对合成rx 1024 tx 1024接口保留 hv_netvsc

如果你更喜欢用于环形缓冲区优化的交互式方法,还可以使用此帮助程序工具:Azure Linux NIC 设置(bash)。

注释

此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 后,创建一个 udev 规则 /etc/udev/rules.d/99-azure-qdisc.rules ,以在添加或更改网络接口时应用该 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 以指定哪些 CPU 不应被分配 IRQ。 需要确定排除这些 CPU 的 掩码

有关如何计算掩码的详细信息, 请参阅此处

SR-IOV 双接口行为和副作用

在 Linux 高性能网络环境中,Azure 使用 SR-IOV(例如,配合 Mellanox 驱动程序,如 mlx4mlx5)。 在此模型中,可以看到同一 VM 网络路径的合成接口和虚拟函数(VF)接口。 了解详细信息

此设计是预期的,但如果这两个接口都被视为独立的数据路径,则优化和故障排除期间可能会造成混淆。

可能的副作用包括:

  • 当设置应用于一个接口但流量使用另一个接口时,基准结果不一致。
  • 在合成路径与 VF 路径之间进行故障转移期间,延迟意外飙升或发生重传。
  • 如果从错误的接口收集计数器和抓包数据,则会导致诊断结果产生误导。

若要降低风险,请:

  • 在调优之前,先确认哪个接口承载工作负载流量。
  • 使 udev 和 sysctl 调优与接口策略保持一致。
  • 重新启动、驱动程序更新或加速网络状态更改后重新测试吞吐量和延迟。

其他注释

系统管理员可以通过编辑配置文件(例如 /etc/sysctl.d//etc/modules-load.d//etc/udev/rules.d/)来实现这些建议。 仔细查看内核和驱动程序更新以避免回归。

有关特定配置和故障排除的详细信息,请参阅有关网络性能的Azure文档。