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

【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://www.xdnf.cn/news/20060.html

相关文章:

  • 【Unity Shader学习笔记】(五)Unity Shader初识
  • 从 0 到 1 吃透 Nacos:服务发现与配置中心的终极实践指南
  • linux命名管道的使用
  • MobileCLIP2:优化多模态强化训练,实现低延迟下的图像文本模型性能突破
  • 弧焊工业机器人保护气节约的关键
  • 中文逆文本标准化 (ITN) 标注规范
  • Jmeter怎么实现接口关联?
  • 移动代理:操作原则、优势、私人使用变体的选择
  • 10 分钟掌握 Selenium 8 大元素定位法:从踩坑到精通
  • 华勤内推码
  • Alpha World赞助Hello Blockchain Thailand,AWT成为全球共识焦点
  • 联想开天X7:携手海光,开启信创PC高性能新时代
  • dvs dvfs avs avfs 低功耗技术的区别
  • uni-app与Vue3,实现3D圆柱形旋转画廊效果
  • 零基础学C++,自定义数据类型
  • 【冷知识】【Xshell 8密码解密】2025年8月19日
  • MySQL中的聚合函数与分组查询
  • SpringAI Alibaba Graph 流式对话
  • Nginx简介
  • SPI通讯协议
  • LightDock:高效蛋白质-DNA对接框架
  • 从数据孤岛到智能中枢:RAG与智能体协同架构如何重塑企业知识库
  • 代码随想录算法训练营第一天 | (二分查找类型)704.二分查找 35.探索插入位置 34.在排序数组中查找元素的第一个和最后一个位置
  • 涨粉14万,100个Coze智能体工作流模版案例:3分钟生成韩非子权谋爆款视频
  • 【C++】在 Windows 系统调用第三方程序(创建进程)
  • 专项智能练习(Photoshop软件基础)
  • mysql高级进阶(存储过程)
  • H3C UIS Cell 3020 G3服务器更换raid卡安装ONEStor记录
  • windows系统服务器测试部署springboot+vue+mysql项目
  • 企业网络安全建设三阶段实战指南