在开发DPDK应用的时候,我们可以通过rte_eth_stats_get函数获取网卡统计信息中的imissed计数来判断网卡是否出现丢包。
2.分析
一个网络帧从网卡接收到被应用处理,中间主要需要经历两个阶段,我们分别从这两个阶段进行分析。
- 阶段一:网卡通过其DMA硬件将收到的报文写入到收包队列中,如果入队道路拥塞将会导致报文无法入队(入队)
- 阶段二:应用从收包队列中读取报文,如果出队慢将导致队列溢出(出队)
3.入队
入队问题主要集中在PCIe异常“降速”方面。因为报文从网卡到系统是经过PCIe总线来传输的,PCIe总线的吞吐将直接影响入队的速率。
现象
若按网口能力满带宽接入流量,网口出现imissed丢包情况,可通过lspci -vv命令查看网口能力与实际使用是否一致。
- 情况1:网口能力是传输速率5GT/s,总线宽带x8(LnkCap),实际使用的是传输速率5GT/s,总线宽带x4(LnkSta)。吞吐能力从4GB/s下降到2GB/s。
- 情况2:网口能力是传输速率8GT/s,总线宽带x8(LnkCap),实际使用的是传输速率5GT/s,总线宽带x8(LnkSta)。吞吐能力从7.877GB/s下降到4GB/s。
解决
一般是服务器与网卡兼容性问题,可以更换网卡或者更换服务器。如果有条件,可以找服务器厂商从bios等方面进行详细定位解决兼容性问题。
4.出队
出队问题主要集中在性能不高、设计不优和CPU错误降频等方面。
4.1.性能不高
现象
出队工作核心使用率100%,不能及时处理队列报文,导致队列报文溢出,持续imissed++,此时出队平均速率是小于入队平均速率。
解决
linux系统下可以使用perf性能分析工具,做热点函数分析,perf安装命令yum install perf。perf常用的热点函数定位命令如下:
- 进程级:perf top -p <pid>
- 线程级:perf top -t <tid>
线程tid可以通过pidstat -t -p <pid>获取。
对于热点函数,可以选中函数进入内部分析热点代码。
4.2.设计不优
现象
出队工作核心使用率没有达到100%,但依然偶尔会丢包,断续imissed++。一般这是因为出队速率抖动引发溢出,即出队最低速率小于入队平均速率,而收包队列的规格(几K)不足以缓存拥塞的报文。
解决
偶尔丢包有时不容易从热点函数中发现,需要分析代码流程进行调优。比如某个报文会触发密集cpu计算,需要更长处理时间,如收到fin报文流结束,对流内容进行复杂处理。针对这种情况,我们可以从以下两个方面进行调优:
- 异步处理
将复杂处理由同步处理(Run-to-completion)改为异步处理(Pipeline),降低抖动(一般异步还会有更好的cache局部性)。
- 加软队列
增加一级容量更大的软队列,缓存抖动(一般业务有按规则分发的需要也需要构建一级软队列,软队列会或多或少增加报文处理的延时)。
4.3.CPU错误降频
如果CPU被降频,将直接影响出队性能。
现象
查看系统日志,发现出现CPU被错误降频。
分析
解决