服务器 > 网络 > udp

UDP丢包问题解决经验梳理

77人参与 2024-08-06 udp

客户反馈udp业务丢包很高,有百分之5左右,导致集群告警严重,同时通过iperf工具来验证节点之间打流确实存在严重丢包,一般丢包类问题本质就是调优问题,因此首先先让用户将网卡驱动固件版本升级到最新,但是节点之间打流丢包还是很高,使用的命令如下iperf3 -u -c 192.168.2.14 -b 10000m -l 10000 -p 3 -t 100

其中-l参数决定了udp单个包的数据大小,这个1万是用户根据业务模型来定的。其实看到这个参数就会有一定想法,是否和mtu默认为1500有关系导致数据包分包了,但是客户认为集群内其它cpu平台没有这么高丢包率,当前至少先尝试调优一下。调优过程也参考了网上的一些文章,有个大神的文章特别清楚,链接如下

https://zhuanlan.zhihu.com/p/617397417

1.实验室搭了环境后,接收方平台也就是hygon平台用相同iperf命令打流丢包确实很严重,有百分之20左右

用iperf3时遇到个如下报错的问题,研究了半天才搞清楚是需要加-b参数指定本地用于发送数据

的 ip,这种情况会出现在本地有多个ip网口的情况下

2.复现到丢包以后开始寻找原因,主要通过ifconfig命令先查看接收的网口下的rx error和dropped是否会有增长

3.确认没有增长以后,由于是直连的,因此链路中和网口这里都算是排除了,然后通过netstat -su命令查看是不是数据交给kernel处理时有丢失,下面两个划线的地方是否有增长

4.实验室查看kerenl层面是有增长的,于是通过下面命令查看这几个参数的大小,并进行相应的设置,这些参数的解读也都在文章开头的链接里了,主要都是和kernel处理相关的

sysctl -a | grep net | grep 'mem\|backlog' | grep 'udp_mem\|rmem_max\|max_backlog'

sysctl -w net.core.netdev_max_backlog=65533

sysctl -w net.core.rmem_max=128000000

sysctl -w net.ipv4.udp_mem=" 2233305 2977741 4466610”

5.实验室中单独设置kernel层面的参数,调优效果几乎没有,很显然即使网口显示没有丢包,但是丢包作为一个整体的最终结果,这样单一的思路也是不正确的,应当意识到kernel层面最终能否处理的过来,和cpu核心和网卡之间的亲和是有关系的,网卡作为其中一个环节还是有调优方向的,配置得当可以让cpu和kernel更好的处理数据,因此通过以下几个关键命令调优

ethtool -l 提高队列数用于绑定更多核心

ethtool -g 对rx 的ring buffer进行提高

ethtool -k关闭ntuple功能避免和rps功能冲突

关闭irqbalance避免和中断绑和冲突

最后进行中断绑核以及配置rps,rps说明如下

6.最终调优后将丢包减少至百分之6,将调优手段整理为脚本提供客户便于一键执行,客户执行后丢包也大大降低了,但是集群中的告警还是存在,最终还是将网络中的mtu设置为9000,问题才彻底解决

附上脚本

#关闭irq服务不然无法手动绑定
systemctl stop irqbalance
#用于增加最大可分配的 udp 缓冲区空间总量和可缓存报文数量
sysctl -w net.core.netdev_max_backlog=65533
sysctl -w net.core.rmem_max=128000000
sysctl -w net.ipv4.udp_mem=" 2233305 2977741 4466610 " 
sysctl -p
#配置rps功能
rps() {
rfc=4096
cc=$(grep -c processor /proc/cpuinfo)
rsfe=$(echo $cc*$rfc | bc)
sysctl -w net.core.rps_sock_flow_entries=$rsfe
for dev in "$@";do
	for filerfc in $(ls /sys/class/net/${dev}/queues/rx-*/rps_flow_cnt)
	do
		echo $rfc > $filerfc
		echo "$filerfc"
	done
done
}
#中断亲和绑定
irq() {
for dev in "$@";do
	core=1
	for irq in `cat /proc/interrupts | grep -i ${dev} | awk '{print $1}' | sed 's/://g'`
	do
        	echo ${core} > /proc/irq/${irq}/smp_affinity_list
        	echo "$irq"
        	core=$(($core+1))
	done
done
}
#关闭网口流控,增大ring buffer
selfdev() {
for dev in "$@";do
	ethtool -a $dev tx off rx off
	ethtool -g $dev tx 4096 rx 4096
done
}

if [ $# -eq 0 ];then
	echo "usage:$0 [network_interface1] [network_interface2]..."
	exit 1
fi

selfdev $@
rps $@
irq $@

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

nginx安装stream模块配置tcp/udp端口转发

08-06

udp接收发送数据程序以及注意事项

08-06

网络编程套接字(二)之UDP服务器简单实现

08-06

《计算机网络微课堂》5-3 UDP和TCP的对比

08-03

LWIP RAW编程接口 UDP函数详解

08-03

Nginx实现UDP四层转发的过程

09-18

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论