ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

组播数据包丢失故障排除指南

2022-01-29 21:34:19  阅读:253  来源: 互联网

标签:指南 组播 RX 应用程序 缓冲区 net 数据包 接字


介绍

本文档的目的是帮助找出丢失组播数据包的原因并进行一些调整以尽量减少此类丢失。

组播数据包丢失的原因有多种。

UDP 协议本身牺牲了性能的可靠性,并且不保证数据报的传递。 因此,数据包在网络传输过程中可能会丢失。

即使数据包到达网络节点,也并不总是意味着应用程序接收到它,因为在处理接收到的数据包时会经过几个级别,在每个级别上都可能会丢失。

网络数据包的典型路径如图 1 所示。

在这里插入图片描述
图1

首先,网络适配器(NIC)接收并处理网络数据包。 NIC 有自己的硬件环形缓冲区。当网络数据流高于 NIC 可以处理时,最新的数据将覆盖最旧的数据。这种可能性取决于 NIC 的特性,例如计算性能和硬件缓冲区大小。

接下来,经过网卡处理后,进入操作系统缓冲区,也可能溢出。来自所有 NIC 的所有应用程序和辅助数据包的所有数据包都通过此缓冲区。

因此,在操作系统层面丢失的可能性取决于:

  • 操作系统缓冲区的大小
  • 系统性能
  • 系统负载
  • 网络相关的系统负载

即使应用程序不使用 NIC,它也取决于 NIC 的数量:它会通过 ARP 或 ICMPv6 等辅助协议产生一些额外的负载。

然后,它进入应用程序从中获取数据包的套接字(socket)缓冲区。如果应用程序无法按时从socket中取出数据包,缓冲区将溢出,数据包将丢失。

因此,在应用层面丢失的可能性取决于:

  • socket 缓冲区大小
  • 应用程序获取数据的速度

诊断

网络适配器缓冲区溢出诊断

Linux

在 Linux 上,可以使用 netstat -i –udp <NIC> 命令检测网络适配器缓冲区溢出,其中 RX-DRP 列显示适配器丢弃的数据包数。

例如:

netstat -i –udp eth0
Iface	MTU		Met	RX-OK	RX-ERR	RX-DRP	RX-OVR	TX-OK	TX-ERR	TX-DRP	TX-OVR	Flg
eth0	1500	0	109208	0		3		0		82809	0		0		0		BMRU

此输出标识适配器丢弃了三个数据包。

为了缓解网络适配器缓冲区溢出,应增加网络适配器缓冲区的大小。

Windows

在 Windows 上,可以使用 netstat -e 命令检测网络适配器缓冲区溢出。

例如:

netstat -e

Interface Statistics
					Received	Sent
Bytes				2126595129	3580282555
Unicast packets		100602496	384905740
Non-unicast packets	3975342		1522900
Discards			2			0
Errors				3			0
Unknown protocols	0

Discards 显示 NIC 拒绝的数据包数量(可能是因为它们已损坏)。

Errors 显示在发送或接收过程中发生的错误数(可能是因为 NIC 出现问题)。

操作系统内核网络缓冲区溢出诊断

Linux

在 Linux 上 watch -d "cat /proc/net/snmp | grep -w Udp" 命令,InErrors 列显示操作系统 UDP 队列溢出时丢弃的 UDP 数据包数。

操作系统缓冲区溢出可以通过以下方式缓解:

  • 增加操作系统内核网络缓冲区的大小。
  • 通过使用用户空间网络堆栈/内核绕过(kernel-bypass)中间件(例如 Solarflare 的 OpenOnload)从数据包路径中排除操作系统内核网络缓冲区。
  • 关闭所有未使用的与网络相关的应用程序和服务,以最大限度地减少系统负载。
  • 在您的系统上只留下合理数量的工作网卡。

例如:

Udp:	InDatagrams	NoPorts	InErrors	OutDatagrams	RcvbufErrors	SndbufErrors
Udp:	1273				25			9				6722				0						0

此输出标识操作系统丢弃了九个数据包。

您还可以使用 watch -d "cat /proc/net/pid/snmp | grep -w Udp" 命令在每个进程的基础上看到这一点。

Windows

要检查 Windows 上的 UDP 统计信息,请使用命令:netstat -s -p udp

IPv4 的 UDP 统计信息

Datagrams Received	=	85463
No Ports			=	123
Receive Errors		=	0
Datagrams Sent		=	75022

Receive Errors指示与操作系统相关的接收错误的数量。

应用程序级套接字缓冲区溢出诊断

Linux

在 Linux 上 watch -d "cat /proc/net/snmp | grep -w Udp" 命令,RcvbufErrors 列显示应用程序套接字缓冲区溢出时丢弃的 UDP 数据包数。

例如:

Udp:	InDatagrams	NoPorts	InErrors	OutDatagrams	RcvbufErrors	SndbufErrors
Udp:	8273		25		0			8720			15				0

此输出标识应用程序丢弃了 15 个数据包。

您还可以使用 watch -d "cat /proc/net/pid/snmp | grep -w Udp" 命令在每个进程的基础上看到这一点。

应用程序级套接字缓冲区溢出可以通过以下方式缓解:

  • 应用程序更快地为其接收套接字缓冲区提供服务(例如,通过使用专用线程来接收 UDP 数据包和/或增加其优先级)。
  • 应用程序增加其接收套接字缓冲区的大小。 有时系统管理员还必须增加全局套接字缓冲区限制,否则应用程序级别的增加将不起作用。
  • 将应用程序(或其接收线程)分配给专用 CPU 内核。
  • 提高应用程序的优先级(例如使用 niceionice Linux 命令)。
  • 关闭所有未使用的与网络相关的应用程序和服务,以最大限度地减少系统负载。

调整

网络适配器缓冲区调整

Linux

要查看适配器的缓冲区设置,请运行 ethtool -g <NIC> 命令。

例如:

ethtool –g eth1:

Ring parameters for eth1:
Pre-set maximums:
RX:	4096
RX Mini:	0
RX Jumbo:	0
TX:	4096
Current hardware settings:
RX:	4096
RX Mini:	0
RX Jumbo:	0
TX:	1024

输出中有两个部分。 第一部分是预设最大值(Pre-set maximums),表示可以为每个可用参数设置的最大值。 第二部分显示每个参数的当前值。

要设置 RX 环形缓冲区(ring buffer)大小,请运行 ethtool -G <NIC> rx NEW-BUFFER-SIZE 命令。

更改将立即生效,无需重新启动系统甚至网络堆栈。

这些更改是针对网卡本身而不是针对操作系统进行的。 这不会更改内核网络堆栈参数,但会更改固件中的 NIC 参数。

较大的环形缓冲区大小可以吸收较大的数据包突发而不会丢失,但可能会因为工作集大小增加而降低效率。

现代网卡的典型环形缓冲区大小值约为 4096,如果您的网卡较少,请考虑硬件升级。

操作系统内核网络缓冲区调整

Linux

运行 sysctl -A | grep net | grep 'mem\|backlog' | grep 'udp_mem\|rmem_max\|max_backlog' 命令检查系统级缓冲区的当前设置。

例如:

net.core.rmem_max			=	131071
net.core.netdev_max_backlog	=	1000
net.ipv4.udp_mem			=	1501632	2002176	3003264

将最大套接字接收缓冲区大小增加到 64 MB:
sysctl -w net.core.rmem_max=67108864

增加可分配的最大总缓冲区空间。这是以页面为单位(4096 字节)测量的:
sysctl -w net.ipv4.udp_mem="262144 327680 393216"

请注意,net.ipv4.udp_mem 在页面中工作,因此要计算以字节为单位的大小,请将值乘以 PAGE_SIZE,其中 PAGE_SIZE = 4096 (4K)。那么最大 udp_mem 大小(以字节为单位)为 385152 * 4096 = 1,577,582,592。

增加传入数据包的队列大小:
sysctl -w net.core.netdev_max_backlog=2000

通过运行 sysctl -A | grep net | grep 'mem\|backlog' | grep 'udp_mem\|rmem_max\|max_backlog' 命令。

要使这些更改永久编辑或创建 /etc/sysctl.conf 文件并在那里添加更改。

应用程序级套接字缓冲区调整

Linux, Windows

为了减少数据包丢失,应用程序必须能够在最新的数据覆盖之前从套接字缓冲区获取数据。因此,应该增加套接字级别的缓冲区。在 OnixS 市场数据处理程序中,这可以通过使用 HandlerSettings::udpSocketBufferSize 配置设置来完成。推荐值为 8388608 (8 MiB)。

附加工具

如果你在应用程序中遇到多播数据包丢失,则可能值得运行一些独立工具来了解有关该问题的更多信息。

tcpdump

tcpdump 是一个强大的命令行数据包分析器,它允许绕过操作系统网络堆栈直接从 NIC 捕获所有多播数据。

例如:

tcpdump -n multicast -i <NIC>

Tcpdump 还支持多组不同的过滤策略。这允许捕获单个或多个多播组的网络数据包,并将其与应用程序接收的数据进行比较。如果应用程序显示一些数据包间隙,但 tcpdump 接收到所有数据,这意味着数据在网络堆栈或应用程序的某个地方丢失。否则,很可能是网络相关或网卡相关的原因。

组播测试
此工具可从 OnixS 支持团队 (support@onixs.biz) 获得。与 tcpdump 不同,它从应用程序级套接字读取数据。使用此工具允许以与应用程序相同的方式接收数据,这有助于检测应用程序内部的损失。

附录 A.“Solarflare 的应用程序加速/OpenOnload”

在这里插入图片描述

图 2

使用 Solarflare 的应用程序加速/OpenOnload 中间件允许数据包绕过系统内核。 这会带来一些性能优势,因为应用程序不执行与网络相关的内核调用。 如图 2 所示。

原文

标签:指南,组播,RX,应用程序,缓冲区,net,数据包,接字
来源: https://blog.csdn.net/sunny_98_98/article/details/122746661

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有