自省 自行 自醒

DBA必备技能之网络排障分析总结

Word count: 2.2kReading time: 8 min
2025/07/26
loading

前言

最近天天和网络问题打交道,什么重传、丢包、IP 重组失败等等,之前曾写过一篇 DBA 必备技能之网络丢包分析总结,聊了一下丢包的种种原因,丢包会涉及到⽹卡、驱动、内核协议栈三⼤类,每一层都有可能会丢包,有可能是驱动层,有可能是协议层,也有可能是硬件层等等,今天这一期简单总结下分析网络问题的瑞士军刀 —— sar,用好轮子可以让我们事半功倍。

sar

sar (System Activity Reporter) 号称为最为全面的系统性能分析工具之一,以前在分析内存问题的时候也经常使用,除此之外,还支持查看 IO、CPU、文件系统等等,不仅如此,sar 还是分析网络问题的一把好手:

  • 怀疑 CPU 存在瓶颈,可用 sar -u 和 sar -q 等来查看
  • 怀疑内存存在瓶颈,可用 sar -B、sar -r 和 sar -W 等来查看
  • 怀疑 I/O 存在瓶颈,可用 sar -b、sar -u 和 sar -d 等来查看
  • 怀疑网络有问题,可用 sar -n 来查看

sar -n 支持很多子选项,加上关键字 “E” 则是查看 ERROR,比如 sar -n DEV 用于查看网络接口统计信息,那么 sar -n EDEV 则是查看网络接口错误,同理,sar -n IP 用于查看 IP 数据报统计信息,sar -n EIP 则是用于查看 IP 错误统计信息,以此类推。

sar -n EDEV

用于快速判断网卡层是否存在硬件故障、丢帧、FIFO 溢出等问题,可以使用 sar -n EDEV 1 | awk ‘NR == 3 || $3 == “xxx” || $3 == “xxx”‘ 仅观测关心的网卡情况:

  1. rxerr/s:每秒接收出错的报文总数
  2. txerr/s:每秒发送出错的报文总数
  3. coll/s:每秒以太网碰撞次数
  4. rxdrop/s:每秒因内核缓冲区不足丢弃的接收报文数
  5. txdrop/s:每秒因缓冲区不足丢弃的发送报文数
  6. txcarr/s:每秒发送载波错误数 (常见于线缆/PHY 问题)
  7. rxfram/s:每秒接收帧对齐错误数
  8. rxfifo/s:每秒接收 FIFO 溢出次数
  9. txfifo/s:每秒发送 FIFO 溢出次数

sar -n EIP

用于判断 IP 层是否因地址配置/转发策略错误或缓冲区不足造成丢包。对于 IP 层,以 Greenplum 为例,主要关注 IP 重组失败:

对于 IP 分片,数据帧不是无限大的,数据帧长度受到 MTU 限制,由于应用层数据有的时候会超过 MTU,超过了链路层的最大运输能力,因此需要对数据进行分片传输。TCP 有着自己的分片规则,但是 UDP 没有实现对应的分片,每次都是按照报文传输,不论报文多大。所以这就苦了 IP 层,IP 层会对 UDP 数据包进行分片传输。并且如果在传输过程中,一次传输被分成多个分片,传输中有一个小分片丢失,那接收端最终会舍弃整个文件,导致传输失败,这就是 UDP 不可靠的原因。而 TCP 的话,MTU 通过限制 MSS (单个数据报的最大消息长度) 的取值,来限制单个 TCP 包的长度。

由于分片可能因丢包而永远无法到达,分片重组必须有超时机制。如果重组无法在一定时间内完成,系统将删除缓冲区中的碎片,放弃重组。因此,如果有分片因路由延迟到达不及时,重组也会失败。另外,系统用于分片重组的内存是有限的,当大量分片达到导致缓冲区不够用时,系统也会放弃重组,巨帧的好处体现出来了。如下这几个参数用于控制这些行为:

  • net.ipv4.ipfrag_high_thresh:设置了碎片缓冲区的高水位线为 4194304 字节 (4 MB)。当碎片缓冲区的使用率超过该阈值时,内核会开始丢弃新到达的碎片。
  • net.ipv4.ipfrag_low_thresh:设置了碎片缓冲区的低水位线为 3145728 字节 (3 MB)。当碎片缓冲区的使用率低于该阈值时,内核会停止丢弃新到达的碎片。
  • net.ipv4.ipfrag_max_dist:是一个用于限制数据包分片重组的内核参数。它定义了分片偏移 (fragment offset) 之间的最大允许间隔。当分片之间的偏移超过此阈值时,内核会丢弃分片并阻止重组,以防止可能的攻击和资源耗尽。
  • net.ipv4.ipfrag_time:设置了碎片在缓冲区中保持的时间为 30 秒。超过该时间的碎片将被丢弃。

sar -n 提供如下指标,着重关注 asmf 和 fragf。

  1. ihdrerr/s:每秒因 IP 报文头错误(校验和、版本号、TTL 超时等)被丢弃的输入报文数
  2. iadrerr/s:每秒因目标地址非法而被丢弃的输入报文数
  3. iukwnpr/s:每秒因上层协议未知/不支持而丢弃的本机定向报文数
  4. idisc/s:每秒由于资源不足等原因被丢弃的输入报文数 (无错误但被丢)
  5. odisc/s:每秒由于资源不足被丢弃的输出报文数
  6. onort/s:每秒因为“无路由”而被丢弃的输出报文数
  7. asmf/s:每秒 IP 重组失败次数
  8. fragf/s:每秒因不可分片(DF 位)而丢弃的报文数

sar -n ETCP

ETCP 则是用于定位重传高、RST 异常、握手失败等问题,常与抓包/ss 结合分析。

  • atmptf/s:每秒 TCP 连接建立尝试失败次数(SYN‑SENT/RCVD→CLOSED/ LISTEN)
  • estres/s:每秒已建立连接被复位而直接关闭的次数
  • retrans/s:每秒重传的 TCP 段数(衡量网络重传比例的重要指标)
  • isegerr/s:每秒收到的 TCP 差错段数(如校验和错误)
  • orsts/s:每秒发送的带 RST 标志的 TCP 段数

retrans 是一个很重要的指标,常见原因是线路丢包、驱动/软中断丢包、拥塞窗口过小、内核/网卡 Buffer 不足,会导致吞吐下降、查询延迟抖动。我们可以调整 ring buffer 大小 (ethtool -G),提升网卡队列深度 (ethtool -L)、提升Socket Buffer & 拥塞控制等 (tcp_mem*,socket_buffer)。下面这个图一目了然:

  1. ring buffer:吸收突发流量,防止驱动层丢包;太大会占内存、增加时延,网卡在收到包后会将帧存放在硬件的 frame buffer 上,并通过 DMA 同步到内核的一块内存,这就是 ring buffer

  2. 硬 IRQ 合并:降低 IRQ 频率、减轻 CPU,中高吞吐场景常调,在最传统的中断模式下,每个帧将产生一次硬中断,CPU 0 收到硬中断后产生一个软中断,内核切换上下文进行协议栈的处理

  3. 软 IRQ & Ingress Qdisc:控制 NAPI 一次能拉多少包、Input 排队深度,关键参数:netdev_max_backlog,NAPI 是一种更先进的处理方式

  4. Egress Qdisc,Output 队列长度 + 算法;与 Bufferbloat、流控息息相关,关键参数:txqueuelen + net.core.default_qdisc,txqueuelen 用于增大网卡传送队列的长度,表示最大缓存包的数量,超过这个数量的包会被丢弃,Socket → Qdisc 由 net.core.default_qdisc 控制,Qdisc → Driver 是设备发送队列 (txqueuelen),设备层的软件发送队列长度 (包数)。当 Qdisc 把包送到驱动,如驱动/硬件忙,包会在此排队。

  5. TCP Buffer:决定单连接窗口大小与拥塞控制可扩展范围,关键参数:net.ipv4.tcp_rmem + net.core.rmem_max,tcp_rmem 和 tcp_wmem 是 TCP 专用三元组,决定 TCP 自动调优在单个连接内能把窗口扩到多大,但实际可扩大的最大值不能超过 net.core.*mem_max,这俩参数是天花板。关于 socket 缓存,强烈推荐这篇文章 👉🏻 Socket 缓存究竟如何影响 TCP 的性能?

  6. 监听 & 拥塞:受 RST、SYN 拒绝、TIME_WAIT 暴涨等场景影响,关键参数:net.core.somaxconn + tcp_max_syn_backlog,somaxconn 是三次握手完成后的 Accept 队列天花板,tcp_max_syn_backlog 控制还在握手的 SYN_RECV 队列长度

小结

网络是一个庞大的子系统,尤其对于分布式数据库,网络又是一项关键的组件,对于我们每位 DBA 来说,学习与掌握好网络是必备技能之一。下一期,再聊聊常见的网络调优技能。

参考

https://zorrozou.github.io/docs/Socket%E7%BC%93%E5%AD%98%E7%A9%B6%E7%AB%9F%E5%A6%82%E4%BD%95%E5%BD%B1%E5%93%8DTCP%E7%9A%84%E6%80%A7%E8%83%BD.html

https://www.ryanchan.top/archives/linux-kernel-and-network-tuning-guide

https://www.starduster.me/2020/03/02/linux-network-tuning-kernel-parameter/

https://github.com/leandromoreira/linux-network-performance-parameters?tab=readme-ov-file#network-tools-for-testing-and-monitoring

CATALOG
  1. 1. 前言
  2. 2. sar
  3. 3. sar -n EDEV
  4. 4. sar -n EIP
  5. 5. sar -n ETCP
  6. 6. 小结
  7. 7. 参考