linux - Linux 多播中队列/缓冲延迟的可能位置在哪里?

标签 linux networking multicast latency queueing

我们在 LAN 上的许多 Linux 服务器上大量使用多播消息传递。我们看到很多延误。我们基本上发送大量的小包裹。我们更关心延迟而不是吞吐量。这些机器都是现代的多核(至少四核,一般是八核,如果算上超线程则为 16 个)机器,负载始终为 2.0 或更低,通常负载小于 1.0。网络硬件的容量也低于 50%。

我们看到的延迟看起来像排队延迟:数据包的延迟将很快开始增加,直到看起来堵塞,然后恢复正常。

消息结构基本上是这样的:在“发送线程”中,从队列中提取消息,添加时间戳(使用 gettimeofday() ),然后调用 send() 。接收程序接收消息,为接收时间加上时间戳,并将其插入队列。在单独的线程中,处理队列,分析发送和接收时间戳之间的差异。 (请注意,我们的内部队列不是问题的一部分,因为时间戳是在我们的内部队列之外添加的。)

我们真的不知道从哪里开始寻找这个问题的答案。我们对 Linux 的内部结构并不熟悉。我们怀疑内核正在对数据包进行排队或缓冲,无论是在发送端还是接收端(或两者)。但我们不知道如何追踪和追踪它。

就其值(value)而言,我们使用的是 CentOS 4.x(RHEL 内核 2.6.9)。

最佳答案

这是一个很好的问题。在 CentOS 上,像大多数 *nix 版本一样,每个多播套接字都有一个 UDP 接收/发送缓冲区。该缓冲区的大小由 sysctl.conf 控制,您可以通过调用/sbin/sysctl -a

查看缓冲区的大小

以下项目显示我的默认和最大 udp 接收大小(以字节为单位)。这些数字越大,缓冲就越多,如果您的应用程序消耗数据的速度太慢,网络/内核可能会引入更多的延迟。如果您对数据丢失具有良好的容忍度,则可以将这些缓冲区设置得非常小,并且您将不会看到上述延迟的增加和恢复。代价是缓冲区溢出时数据丢失 - 您可能已经看到了这一点。

[~]$/sbin/sysctl -a |内存 net.core.rmem_default = 16777216 net.core.wmem_default = 16777216 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216

在大多数情况下,您需要将 default = 设置为最大值,除非您在创建套接字时控制它。

您可以做的最后一件事(取决于您的内核版本)是查看进程的 PID 的 UDP 统计信息,或者至少查看整个盒子。

猫/proc/net/snmp | grep -i UDP Udp:InDatagrams NoPorts InErrors OutDatagrams UDP:81658157063 145 616548928 3896986

cat/proc/PID/net/snmp | 目录grep -i UDP Udp:InDatagrams NoPorts InErrors OutDatagrams UDP:81658157063 145 616548928 3896986

如果我的帖子还不清楚,那么延迟是由于您的应用程序消耗数据的速度不够快,并迫使内核在上述结构中缓冲流量。网络、内核,甚至网卡环形缓冲区都会增加延迟,但所有这些项目通常只会增加几毫秒。

请告诉我您的想法,我可以为您提供更多信息,告诉您在应用程序中应注意哪些方面以提高性能。

关于linux - Linux 多播中队列/缓冲延迟的可能位置在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2285152/

相关文章:

multicast - 具有多播和单播的 DDS 配置

amazon-web-services - AWS 是否支持多播和 IGMP 监听?

通过树莓派切换套接字状态的Java函数

iPhone:什么时候应该使用网络事件指示器

networking - 100% 无服务器(去中心化)对等发现的可能解决方案?

amazon-web-services - AWS Elasticsearch VPC 连接

networking - 在同一Intranet上区分两台计算机

mysql - 如何向mysql表中插入数据?

linux - 管道 (|) 在 Linux 中的使用

c - 调用 execve() 时环境的各个方面是根据什么保留的?