Please do not hesitate to contact RTI with questions or comments about this release. We welcome any input on how to improve RTI Persistence Service to suit your needs.
RTI Persistence Service runs as a separate application; you can run it on the same node as the publishing application, the subscribing application, or some other node in the network.
When configured to run in PERSISTENT mode, RTI Persistence Service can use the filesystem or a relational database that provides an ODBC driver. For each persistent topic, it collects all the data written by the corresponding persistent DataWriters and stores them into persistent storage.
Refer to the RTI Persistence Service Release Notes for the list of supported relational databases.
When configured to run in TRANSIENT mode, RTI Persistence Service stores the data in memory.
For more information, please see the RTI Data Distribution Service User's Manual.
A script to run the RTI Persistence Service executable is located in $NDDSHOME/scripts.
To run RTI Persistence Service:
rtipersistenceservice [options] Options: -cfgFile <file> Configuration file. This parameter is optional since the configuration can be loaded from other locations -cfgName <name> Configuration name. This parameter is required and it is used to find a <persistence_service> matching tag in the configuration files -appName <name> Application name. Used to identify this execution for remote administration and to name the DDS participants Default: -cfgName -identifyExecution Appends the host name and process ID to the appName to help ensure unique names -domainId <int> DDS domain ID for the domain participants created by the service Default: Use XML value -remoteAdministrationDomainId <int> Enables remote administration and sets the domain ID for the communication Default: Use XML value -restore <0|1> Indicates whether or not persistence service must restore its state from the persistent storage Default: Use XML value -noAutoStart Use this option if you plan to start RTI Persistence Service remotely -infoDir <dir> The info directory of the running persistence service. The service writes a ps.pid file into this directory when is started. When the service finalizes the file is deleted Default: None -maxObjectsPerThread <int> DomainParticipantFactory parameter Default: DDS default -serviceStackSize <int> Service thread stack size Default: OS default -verbosity [0-6] RTI Persistence Service verbosity 0 - silent 1 - exceptions (DDS and service) 2 - warnings (service) 3 - information (service) 4 - warnings (DDS and service) 5 - tracing (service) 6 - tracing (DDS and service) Default: 1 (exceptions) -version Prints the RTI Persistence Service version -licenseFile <file> License file. This parameter is optional. -help Displays this information
For the syntax of the configuration file and details about each option, please see Configuring RTI Persistence Service, or the RTI Data Distribution Service User's Manual.
C: See the example in <RTI_Data_Distribution_Service_INSTALL_ROOT>/example/C/HelloWorldPersistence.
C++: See the example in <RTI_Data_Distribution_Service_INSTALL_ROOT>/example/CPP/HelloWorldPersistence.
Java: See the example in <RTI_Data_Distribution_Service_INSTALL_ROOT>/example/JAVA/HelloWorldPersistence.
1. Modify your RTI Data Distribution Service applications. The DURABILITY QosPolicy controls whether or not, and how, published samples are stored by RTI Persistence Service for delivery to late-joining DataReaders.
By default, the History and ResourceLimits QosPolicies for the Persistence Service DataWriter and DataReader (known as PRSTDataWriter and PRSTDataReader, respectively) with topic 'A' will be configured using the DurabilityService QosPolicy of the first-discovered DataWriter that is publishing 'A'. These values will overwrite the values specified in the XML file (unless you use the tag <use_durability_service> in the persistence group definition).
2. Create a configuration file, as described in XML Configuration File.
3. Start RTI Persistence Service with your configuration file. You can start it on the node for either application, or even an entirely different node (provided that node is included in the NDDS_DISCOVERY_PEERS lists for one of the applications).
The first three locations only contain QoS Profiles and are inherited from RTI Data Distribution Service:
The next locations are specific to RTI Persistence Service:
Example Configuration File
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- A Configuration file may be used by several persistence services specifying multiple <persistence_service> entries --> <dds> <!-- QoS LIBRARY SECTION --> <qos_library name="QosLib1"> <qos_profile name="QosProfile1"> <datawriter_qos name="WriterQos1"> <history> <kind>DDS_KEEP_ALL_HISTORY_QOS</kind> </history> </datawriter_qos> <datareader_qos name="ReaderQos1"> <reliability> <kind>DDS_RELIABLE_RELIABILITY_QOS</kind> </reliability> <history> <kind>DDS_KEEP_ALL_HISTORY_QOS</kind> </history> </datareader_qos> </qos_profile> </qos_library> <!-- PERSISTENCE SERVICE SECTION --> <persistence_service name="Srv1"> <!-- REMOTE ADMINISTRATION --> <administration> <domain_id>72</domain_id> </administration> <!-- PERSISTENT STORAGE SECTION --> <persistent_storage> <filesystem> <directory>/tmp</directory> <file_prefix>PS</file_prefix> </filesystem> </persistent_storage> <!-- DOMAIN PARTICIPANT SECTION --> <participant name="Part1"> <domain_id>71</domain_id> <!-- PERSISTENCE GROUP SECTION --> <persistence_group name="PerGroup1" filter="*"> <single_publisher>true</single_publisher> <single_subscriber>true</single_subscriber> <datawriter_qos base_name="QosLib1::QosProfile1"/> <datareader_qos base_name="QosLib1::QosProfile1"/> </persistence_group> </participant> </persistence_service> </dds>
" <tag> value </tag>"
"<tag>value</tag>"
<!-- comment -->.
<dds>
</dds>
Type | Format | Notes |
---|---|---|
DDS_Boolean | yes, 1, true, BOOLEAN_TRUE, or DDS_BOOLEAN_TRUE: true; no, 0, false, BOOLEAN_FALSE, or DDS_BOOLEAN_FALSE: false | Not case-sensitive
|
DDS_Enum | A string | Legal values are those listed in the online (HTML) documentation for the C or Java API
|
DDS_Long | -2147483648 to 2147483647 or 0x80000000 to 0x7fffffff or LENGTH_UNLIMITED or DDS_LENGTH_UNLIMITED | A 32-bit signed integer
|
DDS_UnsignedLong | 0 - 4294967296; 0 - 0xffffffff | A 32-bit unsigned integer
|
String | UTF-8 character string | All leading and trailing spaces are ignored between two tags |
XML Validation
Validation at Run-Time
RTI Persistence Service validates the input XML files using a builtin Document Type Definition (DTD). You can find a copy of the builtin DTD in $NDDSHOME/resource/rtipersistenceservice/schema/rti_persistence_service.dtd. (This is only a copy of what the RTI Persistence Service core uses. Changing this file has no effect unless you specify its path with the DOCTYPE tag, described below.)
You can overwrite the builtin DTD by using the XML tag, <!DOCTYPE>. For example, the following indicates that RTI Persistence Service must use a different DTD file to perform validation:
<!DOCTYPE dds SYSTEM "/local/usr/rti/dds/modified_rtipersistenceservice.dtd">
If you do not specify the DOCTYPE tag in the XML file, the builtin DTD is used.
The DTD path can be absolute or relative to the current working directory of the application.
Validation During Editing
RTI Persistence Service provides DTD and XSD files that describe the format of the XML content. We recommend including a reference to one of these documents in the XML file that contains the persistence service configuration; this provides helpful features in code editors such as Visual Studio and Eclipse, including validation and auto-completion while you are editing the XML file. Including a reference to the XSD file in the XML documents provides stricter validation and better auto-completion than the corresponding DTD file.
The DTD and XSD definitions of the XML elements are in $NDDSHOME/resource/rtipersistenceservice/schema/rti_persistence_service.dtd and $NDDSHOME/resource/rtipersistenceservice/schema/rti_persistence_service.xsd, respectively.
To include a reference to the XSD document in your XML file, use the attribute xsi:noNamespaceSchemaLocation in the <dds> tag. For example (in the following, replace NDDSHOME with the RTI Data Distribution Service installation directory):
<?xml version="1.0" encoding="UTF-8"?> <dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation= "<NDDSHOME>/resource/rtipersistenceservice/schema/rti_persistence_service.xsd"> ... </dds>
The following sections provide details on the XML file syntax:
<datawriter_qos name="DerivedWriterQos" base_name="QosLib::BaseWriterQos"> <history> <kind>DDS_KEEP_ALL_HISTORY_QOS</kind> </history> </datawriter_qos>
In the above example, the writer QoS named 'DerivedWriterQos' inherits the values from the writer QoS 'BaseWriterQos' contained in the library 'Lib'. The HistoryQosPolicy kind is set to DDS_KEEP_ALL_HISTORY_QOS.
Each XML tag with an associated name can be uniquely identified by its fully qualified name in C++ style.
Refer to chapter 15 in RTI Data Distribution Service User's Manual for further information on XML QoS configuration.
For example:
<dds> <persistence_service name="Srv1"> ... </persistence_service> </dds>
Because a configuration file may contain multiple <persistence_service> tags, one file can be used to configure multiple RTI Persistence Service executions.
The following table lists the tags you can specify for a persistence service.
Tag | Description | Number of Tags Allowed
|
---|---|---|
<annotation> | Provides a description for the persistence service configuration. Example:
<annotation> <documentation> Persists in the file system all topics published with PERSISTENT durability </documentation> </annotation> | 0 or 1
|
<administration> | Enables and configure remote administration | 0 or 1
|
<persistent_storage> | When this tag is present, the topic data will be persisted to disk. You can select between file storage and relational database storage. | 0 or 1
|
<participant> | The participant tag describes a DomainParticipant created by the persistence service to monitor a domain ID. | 1 or more
|
<synchronization> | A boolean that indicates if redundant persistence service instances should synchronize their states with one another.
When set to true, messages lost on the way to one service instance can be repaired by another without impacting the original publisher of that message. To synchronize the instances, the <synchronization> tag must be set to true in every instance involved in the synchronization.
Note: This synchronization mechanism is not equivalent to database replication. The extent to which database instances have identical contents depends on the destination ordering and other QoS settings for the persistence service instances. Default: 0 | 1 or more
|
The following remote commands are supported:
The <administration> tag is used to enable remote administration and configure its behavior.
The following table further describes the <administration> tags.
Tag | Description | Number of Tags Allowed
|
---|---|---|
<domain_id> | Specifies which domain ID RTI Persistence Service will use to enable remote administration | 1
|
<participant_qos> | Configures the DomainParticipant QoS for remote administration. If the tag is not defined, RTI Persistence Service will use the RTI Data Distribution Service defaults. | 0 or 1
|
<publisher_qos> | Configures the Publisher QoS for remote administration. If the tag is not defined, RTI Persistence Service will use the RTI Data Distribution Service defaults. | 0 or 1
|
<subscriber_qos> | Configures the Subscriber QoS for remote administration. If the tag is not defined, RTI Persistence Service will use the RTI Data Distribution Service defaults. | 0 or 1
|
<datareader_qos> | Configures the DataReader QoS for remote administration. If the tag is not defined, RTI Persistence Service will use the RTI Data Distribution Service defaults with the following changes:
reliability.kind = DDS_RELIABLE_RELIABILITY_QOS (this value cannot be changed) | 0 or 1
|
<datawriter_qos> | Configures the DataWriter QoS for remote administration. If the tag is not defined, RTI Persistence Service will use the RTI Data Distribution Service defaults with the following changes:
history.kind = DDS_KEEP_ALL_HISTORY_QOS | 0 or 1 |
For additional details on remote administration of RTI Persistence Service see please see the RTI Data Distribution Service User's Manual.
The following table further describes the <persistent_storage> tags.
Tag | Description | Number of Tags Allowed
|
---|---|---|
<filesystem> | When this tag is present, the topic data will be persisted into files. This tag is required if <external_database> is not specified | 0 or 1
|
<external_database> | When this tag is present, the topic data will be persisted in a relational database. This tag is required if <filesystem> is not specified. | 0 or 1
|
<restore> | Indicates if the topic data associated with a previous execution of the persistence service must be restored or not. If the topic data is not restored, it will be deleted from the database. Default: 1 | 0 or 1 |
The following table describes the <filesystem> tags.
Tag | Description | Number of Tags Allowed
|
---|---|---|
<directory> | Specifies the directory of the files in which topic data will be persisted. There will be one file per PRSTDataWriter/PRSTDataReader pair. Default: current working directory | 0 or 1
|
<file_prefix> | A name prefix associated with all the files created by RTI Persistence Service. Default: PS | 0 or 1
|
<journal_mode> | Sets the journal mode. This tag can take these values:
| 0 or 1
|
<vacuum> | Sets the auto-vacuum status of the storage. This tag can take these values:
Default: FULL | 0 or 1
|
<synchronization> | Determines the level of synchronization with the physical disk. This tag can take three values:
| 0 or 1
|
<trace_file> | Specifies the name of a trace file for debugging purposes. The trace file contains information about all SQL statements executed by the persistence service Default: No trace file is generated | 0 or 1 |
The following table describes the <external_database> tags.
Tag | Description | Number of Tags Allowed
|
---|---|---|
<dsn> | DSN used to connect to the database using ODBC. You should create this DSN through the ODBC settings on Windows systems, or in your .odbc.ini file on UNIX/Linux systems. This tag is REQUIRED. | 1
|
<username> | Username to connect to the database. Default: No username is used. | 0 or 1
|
<password> | Password to connect to the database. Default: No password is used. | 0 or 1
|
<restore> | Indicates if the topic data associated with a previous execution of the persistence service must be restored or not. If the topic data is not restored, it will be deleted from the database. Default: 1 | 0 or 1
|
<odbc_library> | Specifies the ODBC driver to load. By default, RTI Data Distribution Service will try to use the standard ODBC driver manager library (UnixOdbc on UNIX/Linux systems, the Windows ODBC driver manager on Windows systems). | 0 or 1
|
For example:
<persistence_service name="Srv1"> <participant name="Part1"> <domain_id>71</domain_id> ... </participant> <participant name="Part2"> <domain_id>72</domain_id> ... </participant> </persistence_service>
In the previous example, the persistence service will create two domain participants on domains 71 and 72. After the domain participants are created, the persistence service will monitor the discovery traffic looking for topics to persist.
The <domain_id> tag can also be specified as an attribute of <participant>. For example:
<persistence_service name="Srv1"> <participant name="Part1" domain_id="71"> ... </participant> </persistence_service>
The following table describes the participant tags.
Tag | Description | Number of Tags Allowed
|
---|---|---|
<domain_id> | Domain ID associated with the Participant. The domain ID can be specified as an attribute of the participant tag. Default: 0 | 0 or 1
|
<participant_qos> | Participant QoS. Default: DDS defaults. | 0 or 1
|
<persistence_group> | A persistence group describes a set of topics whose data that must be persisted by the persistence service. | 1 or more
|
For example:
<participant name="Part1"> <domain_id>71</domain_id> <persistence_group name="PerGroup1" filter="H*"> ... </persistence_group> </participant>
In the previous example, the persistence group 'PerGroup1' has associated all the topics published in the domain 71 whose name starts with 'H'.
A <participant> tag can contain multiple persistence groups; the set of topics that each one represents can intersect.
The following table further describes the persistence group tags.
Tag | Description | Number of Tags Allowed
|
---|---|---|
<filter> | A list of POSIX expressions separated by commas that describe the set of topics allowed in the persistence group. The filter can be specified as an attribute of persistence_group as well. Default: * | 0 or 1
|
<deny_filter> | A list of POSIX expressions separated by commas that describe the set of topics denied in the persistence group. This "black" list is applied after 'filter'. Default: empty | 0 or 1
|
<content_filter> | Content filter topic expression. A persistence group can subscribe to a specific set of data based on the value of this expression. A filter expression is similar to the WHERE clause in SQL. For more information on the syntax, please see the online documentation (From the Modules page, select DDS API Reference, Queries and Filters Syntax.) Default: no expression | 0 or 1
|
<single_publisher> | Indicates if the persistence service should create one Publisher per persistence group or one Publisher per PRSTDataWriter inside the persistence group. Default: 1 | 0 or 1
|
<single_subscriber> | Indicates if the persistence service should create one Subscriber per persistence group or one Subscriber per PRSTDataReader in the persistence group. Default: 1 | 0 or 1
|
<use_durability_service> | Indicates if the HISTORY and RESOURCE_LIMITS QoS policy of the PRSTDataWriters and PRSTDataReaders should be configured based on the DURABILITY SERVICE value of the discovered DataWriters. Default: 1 | 0 or 1
|
<share_database_connection> | A boolean that indicates if the persistence service will create an independent database connection per PRSTDataWriter in the group (0) or per Publisher (1) in the group.
When <single_publisher> is 0 and <share_database_connection> is 1, there is a single database connection per group. All the PRSTDataWriters will share the same connection.
When <single_publisher> is 1 or <share_database_connection> is 0, there is a database connection per PRSTDataWriter.
This parameter is only applicable to configurations persisting the data into a relational database using the tag <external_database> in <persistent_storage>. Default: 0 | 0 or 1
|
<reader_checkpoint_frequency> | This property controls how often (expressed in number of samples) the PRSTDataReader state is stored in the database. The PRSTDataReaders are the DDS DataReaders created by the persistence service. A high frequency will provide better performance. However, if the persistence service is restarted, it may receive some duplicate samples. The persistence service will send these duplicates samples on the wire but they will be filtered by the DDS DataReaders and they will not be propagated to the application. This property is only applicable when the persistence service operates in persistent mode (the <database_connection> tag is present). Default: 1 | 0 or 1
|
<writer_in_memory_state> | This property determines how much state will be kept in memory by the PRSTDataWriters in order to avoid accessing the database. The property is only applicable when the persistence service operates in persistent mode (the <database_connection> tag is present). When writer_in_memory_state is true, the PRSTDataWriters will keep a copy of the meta-data about all the instances in memory. They will also keep a fixed state overhead of 24 bytes per sample. However, user data samples will always be stored in the database, not in memory. This mode provides the best performance. However, the restore operation will be slower and the maximum number of samples that a PRSTDataWriter can manage will be limited by the available physical memory. If in_memory_state is false, all the state will be kept in the underlying database. In this mode, the maximum number of samples that a PRSTDataWriter can manage will not be limited by the available physical memory unless the underlying database is an in-memory database (TimesTen). Default: For KEEP_LAST or ResourceLimitsQosPolicy.max_samples != DS_UNLIMITED_LENGTH, the default is true. Otherwise, the default is false. | 0 or 1
|
<memory_management> | This tag configures the memory allocation policy for samples in the PRSTDataReaders and PRSTDataWriters. | 0 or 1
|
<propagate_dispose> | Specifies whether or not the persistence service should propagate the dispose messages it receives from data writers to the data readers. Default: 1 | 0 or 1
|
<propagate_source_timestamp> | Controls whether or not the persistence service propagates the source timestamp of the received samples. Default: false | 0 or 1
|
<propagate_unregister> | Specifies whether or not the persistence service should propagate the unregister messages it receives from data writers to the data readers. Default: 0 | 0 or 1
|
<topic_qos> | Topic QoS. Default: DDS defaults | 0 or 1
|
<publisher_qos> | Publisher QoS. Default: DDS defaults | 0 or 1
|
<subscriber_qos> | Subscriber QoS. Default: DDS defaults | 0 or 1
|
<datawriter_qos> | PRSTDataWriter QoS. Default: DDS defaults. Note: These fields cannot be set and are assigned automatically: protocol.virtual_guid, protocol.rtps_object_id, durability.kind. | 0 or 1
|
<datareader_qos> | PRSTDataReader QoS. Default: DDS defaults. Note: These fields cannot be set and are assigned automatically: protocol.virtual_guid, protocol.rtps_object_id, durability.kind. | 0 or 1
|
For example:
<participant name="Part1"> <domain_id>71</domain_id> <persistence_group name="PerGroup1" filter="*"> ... <publisher_qos base_qos_name="QosLib1::PubQos1"/> <subscriber_qos base_qos_name="QosLib1::SubQos1"/> <datawriter_qos base_qos_name="QosLib1::WriterQos1"/> <datareader_qos base_qos_name="QosLib1::ReaderQos1"/> ... </persistence_group> </participant>
For instance, the number of samples saved by RTI Persistence Service is configurable through the HISTORY QosPolicy of the PRSTDataWriters. If a QoS tag is not specified the persistence service will use the corresponding RTI Data Distribution Service default values.
<participant name="Part1"> <domain_id>71</domain_id> <persistence_group name="PerGroup1" filter="*"> ... <use_durability_service/>0</ use_durability_service> ... </persistence_group> </participant>
<participant name="Part1"> <domain_id>71</domain_id> <persistence_group name="PerGroup1" filter="*"> ... <single_publisher/>0</single_publisher> <single_subscriber/>0</single_subscriber> ... </persistence_group> </participant>
<participant name="Part1"> <domain_id>71</domain_id> <persistence_group name="PerGroup1" filter="*"> ... <share_database_connection>0</share_database_connection> ... </persistence_group> </participant>
Sharing a database connection optimizes the resource usage. However, the concurrency of the system decreases because the access to the database connection must be protected.
The serialized size of a sample is the number of bytes that requires on the wire. The maximum serialized size of a sample is the number of bytes that the largest sample for a given type requires on the wire.
By default, The PRSTDataReaders and PRSTDataWriters created by the persistence service try to allocate multiple samples to their maximum serialized size. This may cause memory allocation issues when the maximum serialized size is significantly large.
For PRSTDataReaders, the number of samples in the DataReaders queues can be controlled using the QoS values resource_qos.resource_limits.max_samples and resource_qos.resource_limits.initial_samples.
The PRSTDataWriters keep a cache of samples so that they do not have to access the database every time. The minimum size of this cache is 32 samples.
In addition, each PRSTDataWriter keeps an additional sample called DB sample that is used to move information from the DataWriter cache to the database and viceversa.
The <memory_management> tag in a persistence group can be used to control the memory allocation policy for the samples created by PRStDataReaders and PRSTDataWriters in the persistence group.
The following table further describes the memory management tags:
Tag | Description | Number of Tags Allowed
|
---|---|---|
<pool_sample_buffer_max_size> | This tag applies to both, PRSTDataReader and PRSTDataWriters. Its value determines the maximum size (in bytes) of the buffers that will be preallocated to store the samples. If the space required for a new sample is greater than this size, persistence service will allocate the memory dynamically to the exact size required by the sample. This parameter is used to control the memory allocated for the samples in the PRSTDataReader queues and the PRSTDataWriter caches. The size of the DB sample in the PRSTDataWriters is controlled by the value of the tag <persistent_sample_buffer_max_size>. Default: LENGTH_UNLIMITED (samples are allocated to the maximum size) | 0 or 1
|
<persistent_sample_buffer_max_size> | This tag is used to control the memory associated with the DB sample in a PRSTDataWriter. The persistence service will not be able to store a sample into persistent storage if the serialized size is greater than this value. Therefore, this parameter must be used carefully. Default: LENGTH_UNLIMITED (DB sample is allocated to the maximum size) | 0 or 1 |
Refer to the RTI Persistence Service Release Notes for the list of supported architectures.
You can configure, start and stop the service using the API described here: