1. 网络吞吐性能概述
做网络性能优化这么多年,我经常被问到同一个问题:“为什么我带宽买了100M,实际传文件只有30M?” 这个问题背后,其实就是吞吐量、带宽、延迟这三兄弟在打架。今天咱们就把这事儿彻底聊透。
1.1 吞吐量 vs 带宽:别搞混了
很多人把带宽和吞吐量当成一回事,其实差远了。
| 概念 | 定义 | 打个比方 |
|---|---|---|
| 带宽 | 链路能承载的最大数据传输速率 | 高速公路的限速牌——理论上能跑多快 |
| 吞吐量 | 实际成功传输数据的速率 | 你实际开到多少——堵车、红绿灯、收费站都得算进去 |
说白了,带宽是理论天花板,吞吐量是现实成绩单。我见过太多运维盯着带宽买买买,结果吞吐量纹丝不动——钱白花了。
核心公式:
吞吐量 = 带宽 × 效率因子
效率因子永远 ≤ 1,它由协议开销、丢包、延迟、硬件瓶颈共同决定。
1.2 延迟:吞吐量的隐形杀手
延迟和吞吐量的关系,很多人理解反了。我刚开始做网络时也犯过这个错——以为延迟只影响响应速度,跟吞吐量没关系。
实际上,高延迟会直接掐死吞吐量。为什么?
拿TCP来说,它有个拥塞窗口机制。发送方发出去一个包,必须等收到ACK才能继续发。如果RTT(往返时间)是100ms,那窗口再大,每秒也只能完成10次往返。你想想看,带宽再宽,数据在管道里慢慢晃,吞吐量能高吗?
经验公式:
TCP吞吐量上限 ≈ 拥塞窗口大小 / RTT
举个例子:窗口64KB,RTT 100ms,理论吞吐量只有 640KB/s ≈ 5Mbps。带宽再大也没用。
我在项目中遇到过跨国传输的场景,RTT高达300ms。客户买了1G带宽,实际吞吐量死活上不去。后来一算,TCP窗口默认才64KB,理论上限才2Mbps左右。调了窗口和启用BBR之后,吞吐量直接翻了10倍。
1.3 影响吞吐的关键因素
吞吐量上不去,原因通常跑不出下面这三类。我习惯按这个顺序排查:
1.3.1 硬件层面
- 网卡:老旧百兆网卡、半双工模式、中断合并策略不合理
- CPU:软中断处理不过来,尤其是高带宽小包场景
- 内存带宽:DDR3和DDR5的拷贝速度差好几倍,直接影响零拷贝效率
- PCIe通道:多队列网卡如果插在PCIe 2.0 x4上,带宽直接卡死
我曾经遇到一个案例:服务器网卡是万兆的,但插在PCIe 2.0 x4插槽上,理论带宽才2GB/s,实际跑万兆网络时CPU软中断飙到100%。换个插槽就解决了。
1.3.2 协议层面
- TCP协议栈:三次握手、慢启动、拥塞控制、ACK机制,每个环节都在消耗带宽
- 协议头开销:以太网头+IP头+TCP头,最少54字节。小包场景下开销占比极高
- Nagle算法:延迟发送小包,对交互式应用友好,但对大吞吐场景是累赘
- 窗口缩放因子:Windows Scaling没开启,窗口最大只有64KB,高延迟链路直接废掉
避坑指南:
我曾经在调优时只改了发送缓冲区大小,忘了改接收缓冲区。结果发送端拼命发,接收端窗口满了直接丢包——吞吐量反而下降了。记住:发送和接收窗口必须对称调整。
1.3.3 配置层面
- MTU:默认1500字节,如果链路支持巨帧(Jumbo Frame),可以设到9000,减少包数量
- Ring Buffer:网卡环形缓冲区太小,高并发下直接丢包
- RSS/RPS:多队列没开启,所有流量挤在一个CPU核心上
- TCP卸载:TSO/GRO/LRO没启用,CPU被迫处理协议栈
- QoS策略:限速、流量整形配置不当,人为制造瓶颈
嗯,这里要注意:配置层面的问题往往最容易被忽略,但修复成本最低。我建议每次调优前,先跑一遍 sysctl -a | grep net 把当前参数全dump出来,对比基线再动手。
1.4 吞吐性能全景图
下面这张图是我自己总结的吞吐性能影响因素框架,每次排查问题我都会对着它过一遍:
1.5 一个真实案例
去年帮一家游戏公司排查问题。他们的日志采集服务器,带宽是10G,但吞吐量始终在1.2Gbps左右徘徊。我上去一看:
- MTU是默认1500,没开巨帧
- Ring Buffer只有256,丢包率0.3%
- RSS没开,所有流量在CPU 0上
- TCP窗口缩放因子没启用
我做了三件事:
- MTU调到9000(链路支持)
- Ring Buffer调到4096
- 开启RSS,把队列分散到4个核心
吞吐量从1.2Gbps直接跳到7.8Gbps。没花一分钱硬件,就是配置调优。嗯,这就是为什么我总说:先软后硬,先配后换。
一句话总结本章:
吞吐量 = 带宽 × 效率因子。效率因子被硬件、协议、配置三座大山压着。排查时从配置入手最快,协议次之,硬件最后动。