Knowledge Center Monthly Newsletter - July 2025
Stay up to date with the latest from the Knowledge Center. See all new Knowledge Center articles published in the last month, and re:Post’s top contributors.
为什么我的 Amazon EC2 实例在平均利用率很低时会超过其网络限制?
我的 Amazon Elastic Compute Cloud (Amazon EC2) 实例的平均网络利用率很低,但该实例仍超过其带宽或每秒数据包数 (PPS) 配额。
简短描述
即使您的平均利用率很低,bw_in_allowance_exceeded、bw_out_allowance_exceeded 或 pps_allowance_exceeded 弹性网络适配器 (ENA) 网络性能指标也可能会增加。此问题的最常见原因是网络资源需求的短暂激增,称为微爆。微爆通常仅持续数秒、数毫秒甚至数微秒。Amazon CloudWatch 指标不够精细,无法反映这些情况。例如,您可以使用 CloudWatch 中的 NetworkIn 和 NetworkOut 实例指标来计算每秒的平均吞吐量。但是,由于微爆,计算出的速率可能低于该实例类型的可用实例带宽。
对于拥有“最高”带宽(例如“最高 10 千兆位每秒 (Gbps)”)的小型实例,bw_in_allowance_exceeded 和 bw_out_allowance_exceeded 指标也会增加。 较小的实例使用网络 I/O 积分在有限的时间内突增超过其基准带宽。当积分耗尽时,流量将与基准带宽保持一致,指标也会增加。由于实例突增是在尽力的基础上实现的,因此即使您的实例有可用的 I/O 积分,指标也可能会增加。
当非最佳流量模式导致数据包以较低的 PPS 速率丢失时,pps_allowance_exceeded 指标也会增加。非对称路由、过时的驱动程序、小数据包、分段和连接跟踪会影响工作负载的 PPS 性能。
解决方法
平均值计算
CloudWatch 每 60 秒对 Amazon EC2 指标进行一次采样,以捕获 1 分钟内传输的总字节数或数据包。Amazon EC2 汇总采样并在 5 分钟时段内将其发布到 CloudWatch。该期限内的每个统计数据都显示不同的值。
当您使用详细监控时,CloudWatch 会在 1 分钟时段内发布未经聚合的 NetworkIn 和 NetworkOut 指标。Sum(总和)、Minimum(最小值)、Average(平均值)和 Maximum(最大值)的值相同,SampleCount 的值为 1。CloudWatch 始终在 5 分钟时段内聚合并发布 NetworkPacketsIn 和 NetworkPacketsOut 指标。
使用以下方法计算一段时间内的平均吞吐量(以每秒字节数 (Bps) 或 PPS 为单位):
- 要获得指定时间段内的简单平均值,请将 Sum(总和)除以 Period(时段)或值之间的时间戳差 (DIFF_TIME)。
- 对于活动量最高的那一分钟内的平均值,用 Maximum(最大值)除以 60 秒。
要将 Bps 转换为 Gbps,请将计算结果除以 1,000,000,000 字节,然后将其乘以 8 位。
CloudWatch 指标出现微爆
以下示例显示了微爆是如何在 CloudWatch 中出现的。该实例的网络带宽限额为 10 Gbps,并使用基本监控。
在 60 秒的采样中,大约 24 GB 的出站数据传输会占用所有可用带宽。数据传输增加了 bw_out_allowance_exceeded 值,并在大约 20 秒内完成,平均速度为 9.6 Gbps。Amazon EC2 不发送任何其他数据,并且该实例在剩下的 4 个 240 秒采样中保持空闲状态。
5 分钟时段的平均吞吐量(以 Gbps 为单位)远低于微爆期间的平均吞吐量:
公式: AVERAGE_Gbps = SUM(NetworkOut) / PERIOD(NetworkOut) / 1,000,000,000 字节* 8 位
SUM(NetworkOut) =(~24 GB * 1 个采样)+(~0 GB * 4 个采样)= ~24 GB
PERIOD(NetworkOut) = 300 秒(5 分钟)
AVERAGE_Gbps = ~24 / 300 / 1,000,000,000 * 8 = ~0.64 Gbps
即使您根据最高采样计算平均吞吐量,该吞吐量仍然无法反映微爆期间的吞吐量:
公式: AVERAGE_Gbps = MAXIMUM(NetworkOut) / 60 秒/ 1,000,000,000 字节/ 8 位
MAXIMUM(NetworkOut) = ~24 GB
AVERAGE_Gbps = ~24 GB / 60 / 1,000,000,000 * 8 = ~3.2 Gbps
当高分辨率数据可用时,您可以获得更准确的平均值。当您以 1 秒的间隔收集操作系统 (OS) 网络使用情况指标时,平均吞吐量短暂达到大约 9.6 Gbps。
监控微爆
您可以在 Linux 和 Windows 上使用 CloudWatch 代理以最多 1 秒的间隔向 CloudWatch 发布操作系统级别的网络指标。该代理还可以发布 ENA 网络性能指标。
注意:高分辨率指标的定价更高。
您还可以使用操作系统工具以最多 1 秒的间隔监控网络统计信息。对于 Windows 实例,使用性能监视器。对于 Linux,使用 sar、nload、iftop、iptraf-ng 或 netqtop。
要清楚地识别微爆,请对操作系统执行数据包捕获,然后使用 Wireshark 以 1 毫秒的间隔绘制 I/O 图。有关详细信息,请参阅 Wireshark 网站上的下载 Wireshark 和 8.8.“I/O 图表”窗口。
此方法有以下限制:
- 网络限额在微秒级别上大致是成比例的。例如,带宽性能为 10 Gbps 的实例类型可以在 1 毫秒内发送和接收大约 10 兆比特 (Mb)。
- 数据包捕获会导致额外的系统负载,并可能降低总体吞吐量和 PPS 速率。
- 数据包捕获可能不包括所有数据包,因为缓冲区满会导致数据包丢失。
- 时间戳不能准确反映网络何时发送数据包或 ENA 何时收到数据包。
- I/O 图表可能显示入站流量的活动较低,因为 Amazon EC2 会在超过其配额的流量到达实例之前对其进行调整。
数据包队列和丢包
当网络将数据包排队时,产生的延迟以毫秒为单位进行测量。TCP 连接可以扩展其吞吐量并超过 EC2 实例类型的配额。因此,即使您使用瓶颈带宽和往返 (BBR) 或其他使用延迟作为信号的拥塞控制算法,预计也会出现一些数据包队列。当网络丢弃数据包时,TCP 会自动重新传输丢失的分段。数据包队列和丢包都会导致更高的延迟和更低的吞吐量。但是,您无法查看恢复操作。通常,您可以查看的唯一错误是应用程序使用较短的超时时间,或者当网络丢弃足够的数据包以至于连接被强制关闭时。
ENA 网络性能指标不区分排队的数据包或丢弃的数据包。要测量 Linux 上的连接级别 TCP 延迟,请使用 ss 或 tcprtt 命令。要测量 TCP 重新传输情况,请使用 ss 或 tcpretrans 命令获取连接级别统计数据,使用 nstat 获取系统范围的统计数据。要下载作为 BPF 编译器集合 (BCC) 一部分的 tcprtt 和 tcpretrans 工具,请参阅 GitHub 网站上的 bcc。您还可以使用数据包捕获来测量延迟和重新传输情况。
**注意:**网络因超出实例配额而丢弃的数据包不会出现在 ip 或 ifconfig 的丢包计数器中。
防止微爆
首先,根据应用程序的关键性能指标 (KPI) 检查 ENA 网络性能指标,以确定数据包队列或丢包的影响。
如果 KPI 低于所需阈值,或者您收到应用程序日志错误,请执行以下操作来减少数据包队列和丢包:
- 纵向扩展: 将实例大小增加到具有更高网络限额的实例。带有“n”的实例类型(例如 C7gn)具有更高的网络限额。
- 横向扩展: 在多个实例之间分配流量,以减少单个实例上的流量和争用。
对于基于 Linux 的操作,您还可以实施以下策略以避免微爆。最佳做法是在测试环境中测试这些策略,以验证它们是否在减少流量整形的同时,不会对工作负载产生负面影响。
**注意:**以下策略仅适用于出站流量。
SO_MAX_PACING_RATE
使用 SO_MAX_PACING_RATE 套接字选项指定连接的最大调整速率(以 Bps 为单位)。然后,Linux 内核会在来自套接字的数据包之间引入延迟,使得吞吐量不会超过您指定的配额。
要使用此方法,必须实现以下更改:
- 应用程序代码更改。
- 来自内核的支持。有关详细信息,请参阅 GitHub 网站上的 net: introduce SO_MAX_PACING_RATE。
- 公平队列 (FQ) 排队准则或内核支持在 TCP 层进行调整(仅适用于 TCP)。
有关详细信息,请参阅 man7 网站上的 getsockopt(2) - Linux manual page 和 tc-fq(8) - Linux manual page。另请参阅 GitHub 网站上的 tcp: internal implementation for pacing。
qdiscs
Linux 使用每个 ENA 队列的 pfifo_fast 排队准则 (qdisc) 的默认配置来调度数据包。使用 fq qdisc 来减少来自单个流量的突发流量并调节其吞吐量。或者,使用 fq_codel 和 cake 提供主动队列管理 (AQM) 功能,以减少网络拥塞并改善延迟。有关详细信息,请参阅 man7 网站上的 tc(8) - Linux manual page。
对于 TCP,请在客户端和服务器上激活显式拥塞通知 (ECN)。然后,将 ECN 与可以执行 ECN 拥塞体验 (CE) 标记的 qdisc 结合使用。CE 标记会导致操作系统降低连接的吞吐量,从而减少超出实例配额导致的延迟和数据包丢失。要使用此解决方案,必须根据连接的平均往返时间 (RTT) 将 qdisc 配置为低 CE 阈值。最佳做法是仅在连接之间的平均 RTT 变化不大时才使用此解决方案。例如,您的实例仅在一个可用区内管理流量。
由于性能问题,在实例级别设置聚合带宽整形不是最佳做法。
浅层传输 (Tx) 队列
使用浅层 Tx 队列来减少 PPS 整形。字节队列限制 (BQL) 动态限制 Tx 队列中正在传输的字节数。要激活 BQL,请在 GRUB 的内核命令行中添加 ena.enable_bql=1。
**注意:**必须有 ENA 驱动程序版本 2.6.1g 或更高版本才能使用此解决方案。已经在 Linux 内核版本以 K 结尾的 ENA 驱动程序上激活 BQL。
有关详细信息,请参阅 LWN.net 网站上的 bql: 字节队列限制。
使用 ENA Express 时,必须停用 BQL 以最大限度地提高带宽。
您还可以使用 ethtool 将 Tx 队列长度从其默认的 1,024 个数据包缩短。有关详细信息,请参阅 man7 网站上的 ethtool(8) - Linux manual page。