【FastDDS】Persistence Service

发布于:2025-09-08 ⋅ 阅读:(23) ⋅ 点赞:(0)

7. 持久化服务

使用默认 QoS 时,数据写入器(DataWriter)的历史记录仅在数据写入器的生命周期内对数据读取器(DataReader)可用。这意味着历史记录不会在数据写入器初始化之间保留,因此在数据写入器创建时处于空状态。同样,数据读取器的历史记录也不会在数据读取器的生命周期内保留,因此在数据读取器创建时也处于空状态。不过,eProsima Fast DDS 提供了将数据写入器的历史记录配置为存储在持久化数据库中的功能,以便数据写入器可以在创建时从该数据库加载其历史记录。此外,数据读取器可以配置为将最后通知的变更存储在数据库中,以便它们可以在创建时恢复其状态。

这种机制允许在启动数据分发服务时恢复之前的状态,从而在发生意外关闭等情况时增加应用程序的稳健性。通过配置持久化服务,数据写入器和数据读取器可以从关闭时的状态继续运行。

注意
请注意,数据读取器不会将其历史记录存储到数据库中,而是存储来自数据写入器的最后通知的变更。这意味着它们将从停止的地方继续运行,但不会拥有之前的信息,因为这些信息已经通知给应用程序了。

7.1. 配置

持久化服务的配置是通过设置适当的数据写入器和数据读取器的持久性 QoS 策略(DurabilityQosPolicy),并为每个实体(域参与者(DomainParticipant)、数据写入器或数据读取器)的属性策略 QoS(PropertyPolicyQos)指定合适的属性来完成的。

要使持久化服务生效,DurabilityQosPolicyKind 需要设置为 TRANSIENT_DURABILITY_QOSPERSISTENT_DURABILITY_QOS

必须使用 dds.persistence.guid 属性为实体设置一个持久化标识符(Guid_t)。此标识符用于从数据库加载相应的数据,还用于在重启之间同步数据写入器和数据读取器。GUID 由 16 个字节组成,分为两组:

  • 前 12 个字节对应于 GuidPrefix_t
  • 后 4 个字节对应于 EntityId_t

持久化标识符使用由 12 个点分隔的字节组成的字符串指定,以十六进制表示,后跟一个竖线分隔符(|)和另外 4 个点分隔的字节,也以十六进制表示(参见示例)。关于为数据读取器和数据写入器选择合适的 GUID,请参考 RTPS 标准(第 9.3.1 节 全局唯一标识符(GUID))。

如果未指定 dds.persistence.guid,持久性行为将退化为 TRANSIENT_LOCAL_DURABILITY_QOS

必须使用 dds.persistence.plugin 属性配置一个用于管理数据库的持久化插件(参见内置插件 PERSISTENCE:SQLITE3):

7.2. 内置插件 PERSISTENCE:SQLITE3

此插件通过 SQLite3 API 使用本地数据库文件提供持久化功能。要激活该插件,必须将域参与者、数据写入器或数据读取器的属性策略 QoS(PropertyPolicyQos)中添加 dds.persistence.plugin 属性,其值为 builtin.SQLITE3。此外,必须在实体的属性策略 QoS 中添加 dds.persistence.sqlite3.filename 属性,指定数据库文件名。这些属性汇总在下表中:

持久化:SQLITE3 配置属性
属性名称 属性值
dds.persistence.plugin builtin.SQLITE3
dds.persistence.sqlite3.filename 用于持久化存储的文件名。默认值:persistence.db

注意
为避免并发访问 SQLite3 数据库导致的不必要延迟,建议为每个数据写入器和数据读取器指定不同的数据库文件。

重要
域参与者的属性策略 QoS 中设置的插件仅在数据写入器/数据读取器的属性策略 QoS 中未设置插件或插件无效时适用。

7.3. 示例

此示例展示了如何使用内置插件 PERSISTENCE:SQLITE3 配置持久化服务,包括 C++ 代码和使用 eProsima Fast DDS XML 配置文件的方式(参见 XML 配置文件)。

C++

/*
 * 为了使此示例自成一体,所有实体都是通过编程方式创建的,包括数据类型和类型支持。
 * 这是使用 Fast DDS 动态类型 API 完成的,但如果有 IDL 文件,也可以替换为 Fast DDS-Gen 生成的类型支持。
 * 此处创建的动态类型等同于以下 IDL:
 *
 *     struct persistence_topic_type
 *     {
 *         unsigned long index;
 *         string message;
 *     };
 */

// 为域参与者配置持久化服务插件
DomainParticipantQos pqos;
pqos.properties().properties().emplace_back("dds.persistence.plugin", "builtin.SQLITE3");
pqos.properties().properties().emplace_back("dds.persistence.sqlite3.filename", "persistence.db");
DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, pqos);

/********************************************************************************************************
* 创建类型和类型支持
*********************************************************************************************************
* 如果有 IDL 文件和 Fast DDS-Gen,这部分可以替换。
* 创建的类型名称为 "persistence_topic_type"
* 此外,创建一个数据对象并填充数据,只是为了展示如何操作
********************************************************************************************************/

// 为名称为 "persistence_topic_type" 的类型创建一个结构体构建器
const std::string topic_type_name = "persistence_topic_type";

TypeDescriptor::_ref_type struct_type_descriptor {
   
   traits<TypeDescriptor>

网站公告

今日签到

点亮在社区的每一天
去签到