当前位置: 首页 > news >正文

【FastDDS】Layer DDS之Domain ( 06-Partitions )

在DDS(Data Distribution Service,数据分发服务)中,Partition(分区) 是一种在“域(Domain)”提供的物理隔离基础上,为发布者(Publisher)和订阅者(Subscriber)新增的逻辑隔离与通信筛选机制。它的核心作用是在“域”和“主题(Topic)”之外,进一步精细化控制哪些发布者和订阅者能够建立通信,本质是通过“分区成员资格”实现端点(Publisher/Subscriber)间的逻辑分组。

一、Partition的核心定位:解决“更灵活的通信隔离”问题

DDS中已存在“域(Domain)”和“主题(Topic)”两种隔离机制:

  • 域(Domain):物理隔离,不同域的端点无法通信(依赖域ID区分);
  • 主题(Topic):内容隔离,只有订阅与发布完全相同主题的端点才能通信。

但这两种机制存在局限性(如域和主题无法动态修改、一个端点只能关联一个主题)。而Partition正是为弥补这些不足而生,其核心价值体现在以下3个关键特性:

1. 动态可修改,低开销
  • 无需重启端点、不分配新内存、不启动新线程,也不影响历史数据记录;
  • 修改分区时,仅会触发QoS(服务质量)配置的重新宣告,可能导致新的端点匹配(如切换分区后与新分区的订阅者建立连接);
  • 对比:域(Domain)和主题(Topic)一旦创建无法动态修改,修改需销毁并重建端点,开销极高。
2. 多分区归属,减少网络负载
  • 一个端点(Publisher/Subscriber)可同时属于多个分区(通过“分区名称列表”配置);
  • 对发布者而言,无需为不同主题创建多个发布者,仅通过一个主题的单次数据更新,即可向多个分区推送数据,避免重复发送,显著降低网络开销;
  • 对比:主题(Topic)是“一对一”关联,一个发布者只能对应一个主题,若需向不同主题发数据,必须创建多个发布者。
3. 基于“共同分区”的通信规则
  • 发布者与订阅者要实现通信,至少需共享一个共同的分区(无论其他分区是否不同);
  • 若未显式配置分区,端点会自动加入“默认匿名分区”(无名称),因此“未配置分区的发布者”和“未配置分区的订阅者”可通过默认分区通信。

二、关键注意事项:分区与历史数据的关系

需特别注意:分区是与“端点”绑定的,而非与“数据更新”绑定——端点的历史数据记录不会感知分区的修改。
例如:

  1. 发布者先在“Partition_A”中发送了一条数据;
  2. 之后发布者切换到“Partition_B”;
  3. 若此时需要重发历史数据,该数据会被推送到“Partition_B”(当前分区),而非原始的“Partition_A”;
  4. 后果:晚加入“Partition_B”的订阅者,可能收到原本在“Partition_A”中产生的历史数据。

三、分区的通配符匹配(灵活分组的核心)

为简化多分区配置,Partition支持POSIX fnmatch API(1003.2-1992 B.6) 定义的通配符规则,允许通过通配符匹配多个分区名称,实现“一键加入多个分区”。

1. 通配符匹配规则
  • 匹配是双向检查的:只要两个分区名称(含通配符)中任意一个能匹配另一个,即视为“共享分区”;
  • 示例:
    • 发布者分区配置为 part*(匹配以“part”开头的所有分区);
    • 订阅者分区配置为 partition*(匹配以“partition”开头的所有分区);
    • 虽然 partition* 无法匹配 part*,但 part* 可以匹配 partition*(“partition”以“part”开头),因此两者可通信。
2. 特殊通配符“*”
  • 通配符 * 可匹配所有非默认分区(即显式命名的分区,如“Partition_1”“test”等);
  • 注意:* 无法匹配“默认匿名分区”,因此配置 * 的发布者/订阅者,无法与“未配置分区、依赖默认分区”的端点通信。

四、实例理解:分区匹配逻辑

文档中提供了一个完整示例,通过具体配置可清晰看到分区的通信规则,核心配置与匹配结果如下:

1. 各端点的分区配置
参与者(Participant)端点(Publisher/Subscriber)分区配置(Partition List)
Participant_1Pub_11{“Partition_1”, “Partition_2”}
Participant_1Pub_12{“*”}(匹配所有非默认分区)
Participant_2Pub_21{}(默认分区)
Participant_2Pub_22{“Partition*”}(匹配以“Partition”开头的分区)
Participant_3Subs_31{“Partition_1”}
Participant_3Subs_32{“Partition_2”}
Participant_3Subs_33{“Partition_3”}
Participant_3Subs_34{}(默认分区)
2. 最终通信矩阵(是否能通信:✓=是,✕=否)
订阅者(Participant_3)Pub_11(P1)Pub_12(P1)Pub_21(P2)Pub_22(P2)
Subs_31(Partition_1)✓(共享Partition_1)✓(Pub_12的“*”匹配Partition_1)✕(默认分区≠Partition_1)✓(Pub_22的“Partition*”匹配Partition_1)
Subs_32(Partition_2)✓(共享Partition_2)✓(“*”匹配Partition_2)✕(默认分区≠Partition_2)✓(“Partition*”匹配Partition_2)
Subs_33(Partition_3)✕(无共享分区)✓(“*”匹配Partition_3)✕(默认分区≠Partition_3)✓(“Partition*”匹配Partition_3)
Subs_34(默认分区)✕(Pub_11无默认分区)✕(“*”不匹配默认分区)✓(共享默认分区)✕(Pub_22无默认分区)

五、分区的配置方式(代码示例)

在Fast DDS中,可通过C++代码或XML配置文件设置分区,核心是配置PublisherQosSubscriberQos中的partition成员(一个字符串列表)。

1. C++代码配置
// 配置Pub_11(属于Partition_1和Partition_2)
PublisherQos pub_11_qos;
pub_11_qos.partition().push_back("Partition_1");
pub_11_qos.partition().push_back("Partition_2");// 配置Pub_12(属于“*”分区)
PublisherQos pub_12_qos;
pub_12_qos.partition().push_back("*");// 配置Pub_21(无显式分区,默认分区)
PublisherQos pub_21_qos;  // 无需添加任何分区名称// 配置Subs_31(属于Partition_1)
SubscriberQos subs_31_qos;
subs_31_qos.partition().push_back("Partition_1");
2. XML配置(更适合批量管理)
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com"><!-- 配置Pub_11 --><data_writer profile_name="pub_11"><qos><partition><names><name>Partition_1</name><name>Partition_2</name></names></partition></qos></data_writer><!-- 配置Pub_12 --><data_writer profile_name="pub_12"><qos><partition><names><name>*</name></names></partition></qos></data_writer><!-- 配置Subs_31 --><data_reader profile_name="subs_31"><qos><partition><names><name>Partition_1</name></names></partition></qos></data_reader>
</profiles>

总结

DDS中的Partition本质是**“动态、多归属、基于通配符匹配的逻辑通信分组”**,其核心价值是:

  1. 在域和主题之外,提供更灵活的通信隔离与筛选;
  2. 支持动态修改,降低资源开销;
  3. 允许一个端点关联多个分区,减少网络负载;
  4. 通过通配符简化多分区配置,适配复杂场景(如按业务模块、设备类型分组)。

理解Partition的关键是记住:通信的前提是“至少一个共同分区”,且分区与端点绑定、与数据更新无关。


文章转载自:

http://AV2Aw4Og.ygrwt.cn
http://3J9LMwrp.ygrwt.cn
http://kQfVQzAU.ygrwt.cn
http://SyL0irXN.ygrwt.cn
http://NVFqg9bD.ygrwt.cn
http://wy1lEgl2.ygrwt.cn
http://10DDhHsS.ygrwt.cn
http://5AZCMfQr.ygrwt.cn
http://K8VuXOno.ygrwt.cn
http://oeInZb1W.ygrwt.cn
http://tYtqx3yr.ygrwt.cn
http://9EjxPv3t.ygrwt.cn
http://hQNZ8g5v.ygrwt.cn
http://dRVQ4Ns7.ygrwt.cn
http://ZSG9GdEc.ygrwt.cn
http://35in8EsU.ygrwt.cn
http://oMQNHFIA.ygrwt.cn
http://xr3xPIFV.ygrwt.cn
http://uPKS78vy.ygrwt.cn
http://yoJONPnf.ygrwt.cn
http://VGV0uKTy.ygrwt.cn
http://hyC46Swf.ygrwt.cn
http://FUu0QX3n.ygrwt.cn
http://hpyyQiJC.ygrwt.cn
http://5hmXOhsJ.ygrwt.cn
http://0DfqlWNh.ygrwt.cn
http://1vNqTa29.ygrwt.cn
http://jjQ5vx4i.ygrwt.cn
http://teuQbkWZ.ygrwt.cn
http://r10jgtTE.ygrwt.cn
http://www.dtcms.com/a/364733.html

相关文章:

  • 【机器学习入门】5.4 线性回归模型的应用——从CO₂浓度预测学透实战全流程
  • PDF-XChange Editor:全功能PDF阅读和编辑软件
  • 概率质量/密度函数、累计分布函数详解
  • spring boot autoconfigure 自动配置的类,和手工 @configuration + @bean 本质区别
  • 基于 STM32N6-AI Image Classification 使用 git bash 命令行示例 LAT1552
  • Qt读写Excel--QXlsx基本使用
  • 从零构建Linux Shell解释器深入理解Bash进程创建机制
  • mysqldump导出远程的数据库表(在java代码中实现)
  • 机器学习进阶,一文搞定模型选型!
  • PPI网络与TF-miRNA调控网络的实现方法(基于《列腺癌研究.pdf》)
  • 亚马逊ASIN定位广告想爆单?先搞懂流量逻辑!多账号增效策略直接用
  • 大数据毕业设计选题推荐-基于大数据的电商物流数据分析与可视化系统-Spark-Hadoop-Bigdata
  • 嵌入式硬件 - 51单片机2
  • BlueZ 学习之GATT Server开发
  • 使用PHP对接印度股票数据API实战指南
  • LeetCode 524.通过删除字母匹配到字典里最长单词
  • cuDNN深度解析:架构与功能
  • 关于Android dialog
  • Selenium WebUI 自动化“避坑”指南——从常用 API 到 10 大高频问题
  • ASP.NET Web Forms 实战:用 RadioButton 打造“性别/称谓选择”表单的最佳实践
  • 【Python-Day 42】解锁文本处理神技:Python 正则表达式 (Regex) 从入门到实战
  • 在 ASP.NET 8 WebAPI 中使用不同的提供程序验证多个令牌(Token)及常见问题解答
  • 前端开发基础必备——操作系统、计网、数据结构与算法编译原理
  • SpringBoot Web 入门指南:从零搭建第一个SpringBoot程序
  • [TryHackMe]Oh My WebServer(nday漏洞+容器逃逸)
  • Archlinux KDE 下 Fcitx5 输入法的配置与美化
  • 重新测试所有AI代码生成器(2025年更新):GPT-5 vs Claude 4.1 vs Gemini 2.5 Pro——为何“赢家”仍取决于你的技术栈
  • 一文掌握Redisson分布式锁
  • 天然苏打水生产的原水抽取与三重除菌的3D模拟开发实战
  • 编辑器vim(Linux)