GBase 8a集群运维,网卡丢包导致性能抖动的为啥都是RX

网卡负责发送和接收网络数据,分别对应TX和RX。在GBase 8a集群多个项目中发现,网卡丢包导致加载查询性能几倍甚至10几倍的抖动时,都是RX在丢包,而TX一个都没有。本文整理该现象的可能原因,目标是解决网络问题导致性能严重抖动的,不仅仅为了解决网卡丢包问题。

RX / TX 丢包分别是谁负责

RX(接收方向:外部网络 → 本机网卡)

数据包从网线 / 光口进来,网卡硬件先缓存,再交给内核接收缓冲区。

RX 丢包 = 本机来不及收,直接在网卡 / 内核阶段丢弃

TX(发送方向:本机网卡 → 外部网络)

应用写出数据 → 内核发送缓冲区 → 网卡硬件缓存 → 对外发出。

TX 丢包分两类:

  1. 本机侧丢包:本机发包太快,网卡 tx ring、内核 tx buffer 塞满,本机直接丢;
  2. 对端链路丢包:数据包已经从本机网卡发出去,中间交换机 / 对端网卡拥塞丢弃 ——这种丢包 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),数据量也没有变动时,突然发现,总是某个节点性能偶发性能下降,大概率就是网络故障导致。

如果是集群自身问题,不可能总是某个节点有问题,而应该是大量节点都出问题。

如果是数据源,或数据源和集群之间的整个网络有问题,也应是所有节点都出问题。