1. netem corrupt 5%
的作用
功能说明
corrupt 5%
表示 随机修改 5% 的数据包内容(如翻转比特位),模拟数据损坏。- 它本身不会直接丢弃或延迟数据包,而是让接收端收到错误的数据(可能触发校验和失败、协议层重传等)。
为何带宽骤降?
- 关键问题:
netem
的corrupt
操作需要 逐包处理(修改数据包内容),这会引入显著的 CPU 开销。 - 性能瓶颈:
- 当发送速率极高(如 5.26 Gbps)时,
netem
可能无法实时处理所有数据包,导致 队列堆积。 - 默认情况下,
netem
使用内核的 Qdisc 内核线程(软中断)处理数据包,其处理能力远低于专用硬件(如网卡 DMA)。 - 当队列满时,内核会触发 TCP 拥塞控制(如降低发送窗口),最终表现为带宽骤降。
- 当发送速率极高(如 5.26 Gbps)时,
2. 验证原因:观察 netem
队列状态
方法 1:检查 Qdisc 队列长度
bash
tc -s qdisc show dev enp4s0 |
输出示例:
qdisc netem 1: root refcnt 2 limit 1000 packets # 默认队列长度为 1000 包 | |
Sent 1234567 packets 567890123 bytes (123.45 MB) | |
dropped 0 overlimits 0 requeues 0 |
- 关键指标:
limit 1000 packets
:队列最大容量。overlimits
:因队列满而丢弃的数据包数(若增加,说明队列堆积)。- 若
overlimits
为 0 但带宽仍骤降,可能是netem
处理延迟导致发送端主动降速。
方法 2:监控 CPU 使用率
bash
top -p $(pgrep -f "ksoftirqd") # 观察软中断线程(处理 Qdisc) | |
mpstat -P ALL 1 # 查看各 CPU 核心负载 |
- 预期现象:
- 使用
netem
时,某个 CPU 核心的si
(软中断)使用率会接近 100%。 - 高 CPU 负载会导致内核无法及时处理数据包,触发发送端降速。
- 使用
3. 为什么 corrupt
比 delay
/loss
更影响性能?
操作类型 | 内核处理开销 | 典型带宽影响 |
---|---|---|
delay | 低(仅修改时间戳) | 几乎无影响(除非延迟极大) |
loss | 低(直接丢弃包) | 线性降速(如 5% 丢包 → 带宽约降 5%) |
corrupt | 高(需逐包修改数据) | 可能引发指数级降速(因拥塞控制) |
corrupt
的特殊性:- 修改数据包内容后,接收端的 TCP 栈会检测到校验和错误,触发 快速重传 或 RTO(超时重传)。
- 重传会导致发送端 降低发送窗口,进一步限制带宽。
- 若
netem
处理速度跟不上发送速率,队列堆积会加剧这一过程。
4. 如何验证是 netem
性能瓶颈而非其他问题?
实验 1:替换为 loss
测试
# 移除原有规则 | |
sudo tc qdisc del dev enp4s0 root | |
# 添加 5% 丢包规则(低开销) | |
sudo tc qdisc add dev enp4s0 root netem loss 5% | |
# 重新运行 iperf3 | |
iperf3 -c <接收端IP> -t 30 |
预期结果:
- 带宽会线性下降约 5%(如从 5.26 Gbps 降至 ~5 Gbps),不会骤降至 7 Mbps。
- 说明
corrupt
的高开销是主因。
实验 2:降低发送速率测试
bash
# 限制 iperf3 发送速率为 100 Mbps | |
iperf3 -c <接收端IP> -b 100M -t 30 | |
# 同时保持 netem corrupt 5% | |
sudo tc qdisc add dev enp4s0 root netem corrupt 5% |
预期结果:
- 带宽可能稳定在 ~95 Mbps(5% 损坏影响),不会骤降。
- 说明高发送速率下
netem
处理能力不足。
5. 解决方案
方案 1:降低 netem
处理压力
-
减少影响范围:
# 仅对特定流量应用 corrupt(如通过 iptables 标记)
sudo iptables -A PREROUTING -p tcp --dport 1234 -j MARK --set-mark 1
sudo tc qdisc add dev enp4s0 root handle 1: prio
sudo tc filter add dev enp4s0 parent 1: protocol ip prio 1 u32 match ip dport 1234 0xffff action mirred egress redirect dev netem_if
# 需创建虚拟设备或使用其他方法限制流量
(更简单的方法是直接降低测试速率)
-
降低损坏比例:
sudo tc qdisc change dev enp4s0 root netem corrupt 0.5% # 从 5% 降至 0.5%
方案 2:使用硬件加速(如 DPDK)
- 若需高精度模拟损坏且保持高性能,可考虑:
- 使用 DPDK 的
pktgen
工具(用户态处理,绕过内核瓶颈)。 - 专用网络测试仪(如 Ixia、Spirent)。
- 使用 DPDK 的
方案 3:接受性能下降(测试目的)
- 如果目标是 验证系统在错误下的行为(如 TCP 重传、应用层超时),带宽骤降是合理现象。
- 此时应关注:
- 接收端是否正确处理损坏数据(如 TCP 校验和失败)。
- 应用层是否触发容错机制(如重试、降级)。
6. 总结
现象 | 原因 | 是否正常 |
---|---|---|
带宽从 5.26 Gbps 骤降至 7 Mbps | netem corrupt 5% 的高 CPU 开销导致队列堆积,触发 TCP 拥塞控制 | 正常(但需明确测试目标) |
corrupt 比 loss /delay 更影响性能 | 修改数据包内容需要逐包处理,开销远高于丢弃或延迟 | 预期行为 |
低发送速率下 corrupt 不导致骤降 | netem 处理能力足够时,带宽仅受损坏比例影响 | 验证了瓶颈来源 |
建议:
- 若需测试高带宽下的错误处理,改用
loss
或delay
,或降低corrupt
比例。 - 若需精确模拟损坏,接受性能下降,并监控 TCP 重传等指标。
# 延迟
sudo tc qdisc add dev enp1s0 root netem delay 100ms 1000ms
# 服务器限速(丢弃超额包)
tc qdisc add dev enp1s0 root netem loss 10% 丢弃
# 在接收端添加损坏规则# 5% 概率损坏包
sudo tc qdisc add dev enp1s0 handle 1: root netem corrupt 5%
限制发送端带宽
# sudo tc qdisc add dev enp4s0 root netem rate 100mbit
#sudo tc qdisc add dev eth0 root tbf rate 100mbit burst 32kbit latency 400ms
使用 tc
(流量控制工具)在网卡 eth0
上创建一个 TBF(令牌桶过滤器) 根队列规则,限制出口流量速率为 100Mbps,允许突发流量最多 32Kbit,并设置最大延迟为 400毫秒,从而实现基础的流量整形和限速。
删除
#tc qdisc del dev enp4s0 root
查看
#tc qdisc show dev enp4s0
无法识别 netem
队列规则(qdisc)类型,通常是因为缺少必要的内核模块或配置。以下是解决步骤:
1. 检查内核模块是否加载
netem
需要 sch_netem
内核模块支持。运行以下命令检查并加载模块:
sudo modprobe sch_netem |
如果模块不存在,可能需要安装内核扩展包(见步骤2)。
2. 安装内核扩展包(如未安装)
在基于RHEL/CentOS的系统上,确保安装了内核扩展包:
sudo yum install kernel-modules-extra # CentOS/RHEL 7/8 | |
# 或 | |
sudo dnf install kernel-modules-extra # Fedora/RHEL 9+ |
3. 验证模块是否加载
运行以下命令确认模块已加载:
lsmod | grep netem |
如果看到 sch_netem
,则模块已加载。
4. 重新尝试添加qdisc
加载模块后,重新执行你的命令:
sudo tc qdisc add dev ens22f0 root netem rate 100mbit |