DDS 调整信息

本页提供了一些参数调整指导,这些参数可以解决在实际情况下使用 Linux 上各种 DDS 实现时遇到的问题。我们在 Linux 上或使用某个供应商时发现的问题可能会出现在此处未记录的其他平台和供应商上。

下面的建议是调整的起点;它们适用于特定的系统和环境,但调整可能因多种因素而异。调试时可能需要根据信息大小、网络拓扑结构等因素增减数值。

必须认识到,调整参数可能会耗费资源,而且可能会影响到系统中超出预期改进范围的部分。应根据具体情况权衡提高可靠性的好处和坏处。

跨供应商调整

问题: 通过有损连接(通常是 WiFi)发送数据会出现问题,因为有些 IP 片段会被丢弃,可能导致接收端的内核缓冲区满载。

当 UDP 数据包缺少至少一个 IP 片段时,接收到的其余片段就会填满内核缓冲区。默认情况下,Linux 内核会在尝试重新组合数据包片段 30 秒后超时。由于此时内核缓冲区已满(默认大小为 256KB),没有新的片段可以进入,因此连接看起来会 "挂起 "很长时间。

这个问题在所有 DDS 供应商中都很普遍,因此解决方案涉及调整内核参数。

解决方案 使用尽力而为的 QoS 设置,而不是可靠的 QoS 设置。

尽力而为的设置可减少网络流量,因为 DDS 实现无需承担可靠通信的开销,在可靠通信中,发布者需要对发送给订阅者的信息进行确认,并且必须重新发送未正确接收的样本。

不过,如果内核的 IP 片段缓冲区满了,症状还是一样(阻塞 30 秒)。这个解决方案应该能在一定程度上改善问题,而无需调整参数。

解决方案 降低 ipfrag_time 参数。

net.ipv4.ipfrag_time / /proc/sys/net/ipv4/ipfrag_time (默认为 30 秒):内存中保留 IP 片段的时间(秒)。

例如,通过运行将数值减小到 3 秒:

sudo sysctl net.ipv4.ipfrag_time=3

降低该参数的值还会减少没有接收到碎片的时间窗口。该参数对所有接收到的碎片都是全局性的,因此需要根据不同的环境来考虑降低其值的可行性。

解决方案 增加 ipfrag_high_thresh 参数。

net.ipv4.ipfrag_high_thresh / /proc/sys/net/ipv4/ipfrag_high_thresh (默认值:262144 字节):用于重新组装 IP 片段的最大内存。

例如,通过运行"...... "将值增加到 128MB:

sudo sysctl net.ipv4.ipfrag_high_thresh=134217728 # (128 MB)

大幅提高该参数的值是为了确保缓冲区永远不会完全满。不过,这个值可能必须非常高,才能容纳在"...... "时间窗口内收到的所有数据。 ipfrag_time假设每个 UDP 数据包都缺少一个片段。

问题: 发送带有非原始类型的大型可变大小数组的自定义消息会导致较高的序列化/解序列化开销和 CPU 负载。这可能会导致发布器停滞,因为在 发布() 等工具 玫瑰2 主题 赫兹 报告接收信息的实际频率不足。请注意,例如 内置接口/时间 也被视为非原始类型,会产生更高的序列化开销。由于序列化开销增加,在将自定义消息类型从 ROS 1 简单过渡到 ROS 2 时,会出现严重的性能下降。

解决方法 使用多个基元数组,而不是自定义类型的单个数组,或打包成字节数组,例如在 点云2 信息。例如,与其定义一个 FooArray 留言为:

Foo[] my_large_array

Foo 定义为

uint64 foo_1
uint32 foo_2

而不是定义 FooArray 作为

uint64[] foo_1_array
uint32[] foo_2_array

快速 RTPS 调整

问题: 通过 WiFi 运行时,快速 RTPS 会让网络充斥大量数据或快速发布的数据。

请参阅下面的解决方案 跨供应商调整.

旋风 DDS 调整

问题: 尽管使用了可靠的设置并通过有线网络传输,但 Cyclone DDS 无法可靠地传输大型信息。

这个问题应 尽快解决.在此之前,我们想出了以下解决方案(使用 本测试程序):

解决方案 增加 Cyclone 使用的最大 Linux 内核接收缓冲区大小和最小套接字接收缓冲区大小。

为解决 9MB 报文问题而进行的调整:

设置最大接收缓冲区大小、 rmem_max通过跑步:

sudo sysctl -w net.core.rmem_max=2147483647

或者通过编辑 /etc/sysctl.d/10-cyclone-max.conf 文件的内容:

net.core.rmem_max=2147483647

接下来,要设置 Cyclone 请求的最小套接字接收缓冲区大小,请编写一个配置文件,供 Cyclone 在启动时使用,就像这样:

<?xml version="1.0" encoding="UTF-8" ?>;
<CycloneDDS xmlns="https://cdds.io/config"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xsi:schemaLocation="https://cdds.io/config
https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/master/etc/cyclonedds.xsd";>;
    <Domain id="任何";>;
        <内部>;
            <SocketReceiveBufferSize min="10MB";/>;
        </内部>;
    </域>;
</CycloneDDS>;

然后,无论何时运行节点,都要设置以下环境变量:

CYCLONEDDS_URI=file:///absolute/path/to/config_file.xml

RTI Connext 调整

问题: 尽管使用了可靠的设置并通过有线网络传输,但 Connext 无法可靠地传输大型信息。

解决方案Connext QoS 配置文件同时增加 rmem_max 参数。

设置最大接收缓冲区大小、 rmem_max通过跑步:

sudo sysctl -w net.core.rmem_max=4194304

通过调整 net.core.rmem_max 这样,QoS 配置文件就能产生真正可靠的性能。

事实证明,这种配置可以通过 SHMEM|UDPv4 和单机 UDPv4 可靠地传送信息。还测试了多机配置,使用 rmem_max 4MB和 20MB(两台机器使用 1Gbps 以太网连接)时,没有出现丢信现象,平均信息传送时间分别为 700ms 和 371ms。

如果不配置内核的 rmem_max而同样的 Connext QoS 配置文件则需要 12 秒才能完成数据传输。不过,它至少总能完成传输。

解决方案 使用 Connext QoS 配置文件 不带 调整 rmem_max.

ROS2TEST_QOS_PROFILES.xml 文件是使用 RTI 的文档配置的。 配置流量控制器.它有慢速、中速和快速流量控制器(见 Connext QoS 配置文件链接)。

在我们的案例中,中流量控制器产生的效果最好。不过,控制器仍需根据其运行的特定机器/网络/环境进行调整。Connext 流量控制器可用于调整带宽及其发送数据的攻击性,不过一旦超过特定设置的带宽,性能就会开始下降。