4. 硬件路径概览
聊千兆以太网的吞吐瓶颈,很多人一上来就调TCP参数、改应用程序。但我干了这么多年,得说一句实话:大部分性能问题,根源都在硬件路径上。你想想看,数据从网线进来到最终被应用程序读取,中间要穿过多少关卡?每一关都可能成为瓶颈。
这一节,我带你走一遍完整的硬件路径。不画大图,只讲那些我曾经踩过坑的地方。
4.1 数据包的物理旅程
一个网络数据包,从网线到应用内存,大致要经历下面这些站:
- 网线 & 物理层 PHY:电信号/光信号进来,PHY芯片完成编码、时钟恢复。
- MAC 控制器:通常集成在网卡主芯片里,负责帧校验、流量控制。
- DMA 引擎:把数据直接从网卡搬移到系统内存,不经过CPU。
- Ring Buffer(环形缓冲区):在内存中预分配的区域,网卡往里写,驱动来取。
- 中断 / NAPI:通知CPU“数据到了”,或者通过轮询批量处理。
- 内核协议栈:TCP/IP处理,包括校验和、重组、socket队列。
- 应用程序:通过 read/recv 从 socket 取数据。
每跳一步,都可能产生延迟或带宽损失。我在一个视频流项目中遇到过,明明千兆网卡,实际吞吐只有400Mbps。查到最后,是 ring buffer 设置太小,导致大量丢包重传。
核心原则:数据路径上最慢的那一环,决定了整体吞吐。
4.2 关键瓶颈点初识
我习惯把硬件路径的瓶颈分成五类。下面这张表列出来,后面几章我们会逐个深挖。
| 环节 | 典型瓶颈 | 常见症状 |
|---|---|---|
| 物理层 (PHY/MAC) | 网线质量、协商速率错误、双工不匹配 | 大量CRC错误、碰撞计数高、链路降速 |
| DMA & Ring Buffer | ring buffer溢出、DMA重映射缓存未命中 | 网卡丢包 (ifconfig 看到的 dropped)、CPU softirq 高 |
| 中断处理 | 中断频率过高、CPU亲和性差 | 单核 %softirq 爆满、吞吐波动大 |
| 内核协议栈 | TCP窗口太小、checksum offload未开启、锁竞争 | 用户态延迟、tcp_retransmit 计数增长 |
| 内存带宽 & 缓存 | NUMA 跨节点访问、共享内存池瓶颈 | strace 显示大量内存拷贝、应用 CPU 空闲但吞吐上不去 |
你可能会问:这么多环节,从哪里开始查?我个人习惯是从物理层开始,因为如果链路本身就是坏的,折腾上层全是白费力气。
4.3 一条典型的优化路径:从网卡到应用
让我画一个最简单的流程图,把硬件路径和对应的关键优化点串起来。这张图我几乎每次排查都会手画一遍。
提示:实际排查时不用按顺序全部检查。如果ifconfig显示有dropped计数,先看ring buffer;如果应用延迟高但没丢包,先看中断亲和性和协议栈参数。
4.4 我常用的几个初始诊断命令
刚接手一台机器时,我会快速跑一遍下面这些命令,心里就有个底:
ethtool -S eth0— 检查网卡统计,特别关注 rx_dropped、tx_dropped、rx_crc_errors、rx_fifo_errors。cat /proc/interrupts | grep eth0— 看中断分布是否均匀。如果全挤在CPU0上,那肯定有瓶颈。cat /sys/class/net/eth0/queues/rx-*/rps_cpus— 检查RPS配置。sar -n DEV 1— 看吞吐和丢包率实时变化。
嗯,这里要注意:ethtool -S 的输出因驱动而异。我以前在某个厂家的定制网卡上,丢包统计字段叫“rx_no_buffer”,而不是常见的“rx_dropped”。所以别死记字段名,多想想“统计名称可能是驱动自定义的”。
4.5 避坑指南
我曾经踩过的坑:有一次排查吞吐上不去,所有硬件指标都正常,ring buffer也调大了。最后发现是因为BIOS里把网卡的PCIe link speed设成了Gen1,链路速率只有2.5GT/s,根本上不了千兆。所以记得也要查PCIe带宽——用 lspci -vvv 看类似 Speed 5GT/s 或者 Speed 2.5GT/s 的字段。
另外,别忽略网线质量。有次客户说局域网文件拷贝只有200Mbps,我过去一看,网线是扁平线,还绕在金属桌腿上。换一根Cat6屏蔽线,直接上900Mbps。嗯,物理层往往是最容易被忽略的瓶颈。