网卡负责发送和接收网络数据,分别对应TX和RX。在GBase 8a集群多个项目中发现,网卡丢包导致加载查询性能几倍甚至10几倍的抖动时,都是RX在丢包,而TX一个都没有。本文整理该现象的可能原因,目标是解决网络问题导致性能严重抖动的,不仅仅为了解决网卡丢包问题。
目录导航
RX / TX 丢包分别是谁负责
RX(接收方向:外部网络 → 本机网卡)
数据包从网线 / 光口进来,网卡硬件先缓存,再交给内核接收缓冲区。
RX 丢包 = 本机来不及收,直接在网卡 / 内核阶段丢弃。
TX(发送方向:本机网卡 → 外部网络)
应用写出数据 → 内核发送缓冲区 → 网卡硬件缓存 → 对外发出。
TX 丢包分两类:
- 本机侧丢包:本机发包太快,网卡 tx ring、内核 tx buffer 塞满,本机直接丢;
- 对端链路丢包:数据包已经从本机网卡发出去,中间交换机 / 对端网卡拥塞丢弃 ——这种丢包 ifconfig 不会统计在本机 TX 错误里。
为什么 RX 丢包极其常见
RX 硬件缓冲区极小,极易打满
网卡 RX ring(接收环形缓冲区)默认尺寸远小于 TX ring:
- 典型万兆网卡:RX ring 256/512 描述符;TX ring 1024/4096;
- 瞬时大流量突发(广播、大并发 TCP、UDP 风暴),数据包涌入速度 > CPU 内核处理速度,RX buffer 瞬间填满,网卡直接丢弃入包,
RX errors/RX drops上涨。
内核软中断瓶颈
收包依赖 softirq 软中断、CPU 处理协议栈:
- 单核软中断打满、irq 均衡没做、网卡队列少(单队列网卡);
- 数据包堆积在网卡 RX 缓冲区,来不及上送内核,直接丢包; TX 发包是业务进程主动推送,流量可控,不容易出现内核处理跟不上硬件的情况。
广播 / 组播、未知单播只走 RX
机房大量广播风暴、ARP 风暴、未知泛洪流量,全部是入方向流量,只会产生 RX 丢包,和 TX 无关。
物理链路故障绝大多数影响 RX
光模块衰减、网线接触不良、端口 CRC 校验错误、对端交换机故障: 外部发来的包损坏,网卡校验失败直接丢弃,计入 RX errors; 本机发出去的包本机校验没问题,链路损坏只会在对端产生 RX 丢包,本机 TX 无统计。
TX 什么时候会丢包
本机发包速率远超网卡物理带宽
比如 10G 网卡,程序疯狂发包到 20Gbps,TX ring 打满,本机网卡丢弃数据包,TX drops 上涨。 大数据 / 数据库并发批量导出、UDP 压测场景容易出现。
硬件 TX 故障
网卡 TX 通道损坏、光模块发送异常,极其罕见,一般伴随整机网络异常。
要坏就都坏了,不该只有TX坏掉。
应对丢包常见的优化手段
TCP 内核参数优化
调大拥塞窗口、减少慢启动惩罚
1)拥塞算法选型(最关键)
默认 cubic 适合高速长肥管道;弱网 / 易丢包环境推荐 BBR,BBR 不依赖丢包判断拥塞,丢包不会大幅压低发送速率。
# 启用BBR
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p
# 验证
sysctl net.ipv4.tcp_congestion_control
- Cubic:丢包立刻砍半拥塞窗口,丢包后性能暴跌;
- BBR:基于带宽 + RTT 测算,少量丢包几乎不降低发送速度,只微调 pacing。
放宽重传逻辑,避免过早重传、频繁超时
# /etc/sysctl.conf
# 1. 三次Dup ACK才快速重传(默认3,不要改小)
net.ipv4.tcp_reordering = 5
# 网络乱序严重时,认为是乱序而非丢包,减少不必要重传
net.ipv4.tcp_fastretrans = 0
# 2. 初始RTO超时基数,默认200ms,弱网适当放大
net.ipv4.tcp_rto_min = 100
# 重传退避上限,避免超时等待过久
net.ipv4.tcp_retries2 = 8
# 3. 关闭SACK会大幅恶化丢包性能,必须开启
net.ipv4.tcp_sack = 1
net.ipv4.tcp_dsack = 1
net.ipv4.tcp_fack = 1
SACK 作用:只重传丢失分片,而非整段窗口重传,丢包代价大幅降低。
加大收发缓冲区,缓存抵消瞬时丢包抖动
# 全局缓冲区上限
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
# TCP自动调节缓冲区范围
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
# 允许TCP自动扩张缓冲区
net.ipv4.tcp_window_scaling = 1
大缓冲区可以缓存更多未确认报文,短时丢包不会阻塞应用写入
减少小报文频繁发送(合并包,降低丢包概率)
# 开启TCP Nagle合并小包
net.ipv4.tcp_nagle = 1
# 延时ACK适度调大,合并ACK回包
net.ipv4.tcp_delack_min = 40
业务侧尽量批量写入,避免 1 字节小包高频收发,小包丢包对吞吐伤害更大。
链路 / 二层优化:从源头降低丢包冲击
增大设备队列长度(网卡 qdisc、交换机 buffer)
# 网卡队列扩到4096(根据网卡型号调整)
ethtool -G eth0 rx 4096 tx 4096
# fq队列替换默认pfifo_fast,BBR配套
tc qdisc replace dev eth0 root fq pacing
交换机端口扩大缓存 buffer,避免端口拥塞尾丢。
关闭网卡节能、offload 调优
ethtool -K eth0 gro on tso on gso on
ethtool -s eth0 autoneg on
链路冗余 / 多链路聚合
Bonding LACP、ECMP 多路由,单链路丢包自动切其他链路,降低整体丢包率。
GBase 8a现场调整
如下是解决网络问题导致性能严重抖动的,不仅仅为了解决网卡丢包问题。
调整网卡的RX,TX参数
出现次数最多的,参考 GBase 8a集群运维,网卡rx,tx配置参数问题,导致性能偶发缓慢
部分现场设置参数时,网卡出现了重启并卡住,最终用带外管理IP连接主机,重启机器才解决。所以建议与OS和硬件运维人员协商调整参数,并做好意外处理预案。
检查并更换光模块和光纤
只出现过1次,进入机房的维修人员确认光模块不稳定,更换后现象消失。
交换机故障
发生过2次。集群新扩容节点放在了新的交换机上。之后现场就发现性能有明显抖动,相同SQL,耗时从5秒到50秒都有。scp测试节点见的传输速度,发现某个新扩容IP与集群原有节点间速度,从350MB/s到700KB/s抖动。确认是交换机部分端口不稳定问题导致。后续更换了交换机解决。
总结
GBase 8a在稳定运行后,在没有任何业务变动(无新的SQL),数据量也没有变动时,突然发现,总是某个节点性能偶发性能下降,大概率就是网络故障导致。
如果是集群自身问题,不可能总是某个节点有问题,而应该是大量节点都出问题。
如果是数据源,或数据源和集群之间的整个网络有问题,也应是所有节点都出问题。