Chapter 6. Persisting message data
Persisting messages means that messages are saved to disk and survive broker restarts, which protects against data loss. AMQ Broker can persist messages in journals on the file system or in a database. Alternatively, you can use AMQ Broker with message persistence disabled.
- Persisting messages in journals
- This is the default option. Journal-based persistence is a high-performance option that writes messages to journals on the file system. For more information, see Persisting messages in journals.
- Persisting messages in a database
- This option uses a Java Database Connectivity (JDBC) connection to persist messages to a database of your choice. For more information, see Persisting messages in a database.
You can also configure the broker not to persist any message data. For more information, see Section 6.3, “Disabling persistence”.
The broker uses a different solution for persisting large messages outside the message journal. See Chapter 8, Handling large messages for more information.
The broker can also be configured to page messages to disk in low-memory situations. See Section 7.1, “Configuring message paging” for more information.
For current information regarding which databases and network file systems are supported by AMQ Broker see Red Hat AMQ 7 Supported Configurations on the Red Hat Customer Portal.
6.1. Persisting message data in journals Copy linkLink copied to clipboard!
A broker journal is made up of a set of append-only files stored on disk. These files are pre-created to a fixed size and initially contain padding. Records are appended to the end of the journal as messaging operations are performed on the broker.
Appending records to the end of the journal allows the broker to minimize disk head movement and random access operations, which are typically the slowest operation on a disk. When one journal file is full, the broker creates a new one.
The journal file size is configurable, minimizing the number of disk cylinders used by each file. Modern disk topologies are complex, however, and the broker cannot control which cylinder(s) the file is mapped to. Therefore, journal file sizing is difficult to control precisely.
Other persistence-related features that the broker uses are:
- A garbage collection algorithm that determines whether a particular journal file is still in use. If the journal file is no longer in use, the broker can reclaim the file for reuse.
- A compaction algorithm that removes dead space from the journal and compresses the data. This results in the journal using fewer files on disk.
- Support for local transactions.
- Support for Extended Architecture (XA) transactions when using JMS clients.
Most of the journal is written in Java. However, interaction with the actual file system is abstracted, so that you can use different, pluggable implementations. AMQ Broker includes the following implementations:
- NIO
- NIO (New I/O) uses standard Java NIO to interface with the file system. This provides extremely good performance and runs on any platform with a Java 6 or later runtime. For more information about Java NIO, see Java NIO.
- AIO
AIO (Asynchronous I/O) uses a thin native wrapper to talk to the Linux Asynchronous I/O Library (
libaio). With AIO, the broker is called back after the data has made it to disk, avoiding explicit syncs altogether. By default, the broker tries to use an AIO journal, and falls back to using NIO if AIO is not available.AIO typically provides even better performance than Java NIO. To learn how to install
libaio, see Section 6.1.1, “Installing the Linux Asynchronous I/O Library”.
The procedures in the sub-sections that follow show how to configure the broker for journal-based persistence.
6.1.1. Installing the Linux Asynchronous I/O Library Copy linkLink copied to clipboard!
AMQ Broker includes two journal implementations, Java NIO and Linux Asynchronous IO (AIO), which differ in how they interface with the file system. You should use the AIO journal for better persistence performance. To use this journal, you must install the Linux Asynchronous I/O Library (libaio).
It is not possible to use the AIO journal with other operating systems or earlier versions of the Linux kernel.
Procedure
To install
libaio, use theyumcommand, as shown below:yum install libaio
yum install libaioCopy to Clipboard Copied! Toggle word wrap Toggle overflow
6.1.2. Configuring journal-based persistence Copy linkLink copied to clipboard!
By default, the broker is configured to use journal-based persistence. You can modify the configuration parameters related to journal-based persistence, as required.
Procedure
Open the
<broker_instance_dir>/etc/broker.xmlconfiguration file.Copy to Clipboard Copied! Toggle word wrap Toggle overflow persistence-enabled-
If the value of this parameter is set to
true, the broker uses the file-based journal for message persistence. journal-type-
Type of journal to use. If set to
ASYNCIO, the broker first attempts to use AIO. If AIO is not found, the broker uses NIO. bindings-directory-
File system location of the bindings journal. The default value is relative to the
<broker_instance_dir>directory. journal-directory-
File system location of the message journal. The default value is relative to the
<broker_instance_dir>directory. journal-datasync-
If the value of this parameter is set to
true, the broker uses thefdatasyncfunction to confirm disk writes. journal-min-files- Number of journal files to initially create when the broker starts.
journal-pool-files-
Number of files to keep after reclaiming unused files. The default value of
-1means that no files are deleted during cleanup. journal-device-block-size- Maximum size, in bytes, of the data blocks used by the journal on your storage device. The default value is 4096 bytes.
journal-file-size- Maximum size, in bytes, of each journal file in the specified journal directory. When this limit is reached, the broker starts a new file. This parameter also supports byte notation (for example, K, M, G), or the binary equivalents (Ki, Mi, Gi). If this parameter is not explicitly specified in your configuration, the default value is 10485760 bytes (10MiB).
journal-buffer-timeout- Specifies how often, in nanoseconds, the broker flushes the journal buffer. AIO typically uses a higher flush rate than NIO, so the broker maintains different default values for both NIO and AIO. If this parameter not explicitly specified in your configuration, the default value for NIO is 3333333 nanoseconds (that is, 300 times per second). The default value for AIO is 50000 nanoseconds (that is, 2000 times per second).
journal-max-ioMaximum number of write requests that can be in the IO queue at any one time. If the queue becomes full, the broker blocks further writes until space is available.
If you are using NIO, this value should always be
1. If you are using AIO andthis parameter not explicitly specified in your configuration, the default value is500.
- Based on the preceding descriptions, adjust your persistence configuration as needed for your storage device.
Additional resources
6.1.3. About the bindings journal Copy linkLink copied to clipboard!
The bindings journal stores bindings-related data, such as the set of queues deployed on the broker and their attributes. It also stores data such as ID sequence counters. By default, the bindings journal is preconfigured. You can change the directory where it is stored, if required.
The bindings journal always uses NIO because it is typically low throughput when compared to the message journal. Files on this journal are prefixed with activemq-bindings. Each file also has an extension of .bindings and a default size of 1048576 bytes.
The bindings journal parameters are configured in the core element of the <broker_instance_dir>/etc/broker.xml configuration file.
bindings-directory-
Directory for the bindings journal. The default value is
<broker_instance_dir>/data/bindings. create-bindings-dir-
If the value of this parameter is set to
true, the broker automatically creates the bindings directory in the location specified inbindings-directory, if it does not already exist. The default value istrue.
6.1.4. About the JMS journal Copy linkLink copied to clipboard!
The JMS journal stores all JMS-related data, including JMS queues, topics, and connection factories, as well as any JNDI bindings for these resources. The broker creates the JMS journal only if JMS is being used. The JMS journal shares its configuration with the bindings journal.
Any JMS resources created via the management API are persisted to this journal, but any resources configured via configuration files are not.
Files in the JMS journal are prefixed with activemq-jms. Each file also has an extension of .jms and a default size of 1048576 bytes.
Additional resources
6.1.5. Configuring journal retention Copy linkLink copied to clipboard!
You can control how long AMQ Broker retains a copy of journal files. If journal retention is enabled, you can recover messages by replaying them in the journal file copies, which sends the messages to the broker again.
6.1.5.1. Configuring journal retention Copy linkLink copied to clipboard!
You can control how long AMQ Broker retains a copy of journal files. This retention can be set for a specific time duration, until a storage limit is reached, or both.
Procedure
-
Open the
<broker_instance_dir>/etc/broker.xmlconfiguration file. Within the
coreelement, add thejournal-retention-directoryattribute. Specify aperiodorstorage-limit, or both, to control the retention of journal files. In addition, specify the file system location for the journal file copies. The following example configures AMQ Broker to keep journal file copies in thedata/retentiondirectory for7days or until the files use10GBof storage.Copy to Clipboard Copied! Toggle word wrap Toggle overflow period- Time period to keep the journal file copies. When the time period expires, AMQ Broker removes any files that are older than the specified time period.
unit-
The unit of measure to apply to the retention period. The default value is
DAYS. The other valid values areHOURS,MINUTESandSECONDS. directory- File system location of the journal file copies. The specified directory is relative to the <broker_instance_dir> directory.
storage-limit- The maximum storage that can be used by all journal file copies. If the storage limit is reached, the broker removes the oldest journal file to provide space for a new journal file copy. Setting a storage limit is an effective way of ensuring that the journal file retention does not cause the broker to run out of disk space and shut down.
6.1.5.2. Replaying messages in journal file copies for addresses that exist on the broker Copy linkLink copied to clipboard!
You can recover messages by replaying the messages from the journal file copies, which sends them to the broker again. The way in which you replay messages depends on whether the address of messages that you want to replay is currently present on AMQ Broker.
If the address of messages that you want to replay from journal file copies does not exist on AMQ Broker, see Replaying messages in journal file copies for addresses removed from the broker.
You can replay messages either to the original address on the broker or to a different address.
Procedure
- Log in to AMQ Management Console. For more information see Accessing AMQ Management Console.
- In the main menu, click Artemis.
- In the folder tree, click addresses to display a list of addresses.
- Click the Addresses tab.
- In the Action column for the address from which you want to replay messages, click operations.
Select a replay operation.
- If you want the replay operation to search for messages to replay in all journal file copies, click the replay(String,String) operation.
- If you want the replay operation to search for messages to replay only in journal file copies created within a specific time period, select the replay(String,String, String,String) operation. In the startScanDate and endScanDate fields, specify the time period.
Specify the replay options.
- In the target field, specify the address on the broker to send replayed messages. If you leave this field blank, messages are replayed to the original address on the broker.
-
(Optional) In the filter field, specify a string to replay messages only that match the filter string. For example, if messages have a storeID property, you can use a filter of
storeID=”1000”to replay all messages that have a store ID value of 1000. If you don’t specify a filter, all messages in the scanned journal file copies are replayed to AMQ Broker.
- Click Execute.
Additional resources
6.1.5.3. Replaying messages in journal file copies for addresses removed from the broker Copy linkLink copied to clipboard!
You can recover messages by replaying the messages from the journal file copies, which sends them to the broker again. The way in which you replay messages depends on whether the address of messages that you want to replay is currently present on AMQ Broker.
If the address of messages that you want to replay from journal file copies is currently present on AMQ Broker, see Replaying messages in journal file copies for addresses that exist on the broker.
Procedure
- Log in to AMQ Management Console. For more information see Accessing AMQ Management Console.
- In the main menu, click Artemis.
- In the folder tree, click the top-level server.
- Click the Operations tab.
Select a replay operation.
- If you want the replay operation to search for messages to replay in all journal file copies, click the replay(String,String,String) operation.
- If you want the replay operation to search for messages to replay only in journal file copies created within a specific time period, select the replay(String,String, String,String,String) operation. In the startScanDate and endScanDate fields, specify the time period.
Specify the replay options.
- In the address field, specify the address of messages to replay.
- In the target field, specify the address on the broker to send replayed messages.
-
(Optional) In the filter field, specify a string to replay messages only that match the filter string. For example, if messages have a storeID property, you can use a filter of
storeID=”1000”to replay all messages that have a store ID value of 1000. If you don’t specify a filter, all messages in the scanned journal file copies are replayed to AMQ Broker.
- Click Execute.
Additional resources
6.1.6. Compacting journal files Copy linkLink copied to clipboard!
AMQ Broker includes a compaction algorithm that removes dead space from the journal and compresses the data so that it uses fewer files on disk.
You can configure the broker to automatically compact journal files when certain criteria are met or you can run compaction manually.
6.1.6.1. Configuring journal file compaction Copy linkLink copied to clipboard!
You can control when automatic journal compaction starts by specifying a minimum number of journal files that must exist and a minimum amount of live data that must be contained in those journal files. When both limits are reached, the broker starts compaction.
The compaction process parses the journal and removes all dead records. Consequently, the journal comprises fewer files.
Procedure
-
Open the
<broker_instance_dir>/etc/broker.xmlconfiguration file. Within the
coreelement, add thejournal-compact-min-filesandjournal-compact-percentageparameters and specify values. For example:Copy to Clipboard Copied! Toggle word wrap Toggle overflow journal-compact-min-files-
The minimum number of journal files that the broker has to create before compaction begins. The default value is
10. Setting the value to0disables compaction. You should take care when disabling compaction, because the size of the journal can grow indefinitely. journal-compact-percentage-
The percentage of live data in the journal files. When less than this percentage is considered live data (and the configured value of
journal-compact-min-fileshas also been reached), compaction begins. The default value is30.
6.1.6.2. Running compaction from the command-line interface Copy linkLink copied to clipboard!
You can run compaction manually from the command-line if automatic compaction is disabled or if you want to bypass the thresholds at which automatic compaction starts.
Procedure
As the owner of the
<broker_instance_dir>directory, stop the broker. The example below shows the useramq-broker.su - amq-broker cd <broker_instance_dir>/bin $ ./artemis stop
su - amq-broker cd <broker_instance_dir>/bin $ ./artemis stopCopy to Clipboard Copied! Toggle word wrap Toggle overflow (Optional) Run the following CLI command to get a full list of parameters for the data tool. By default, the tool uses settings found in
<broker_instance_dir>/etc/broker.xml../artemis help data compact.
$ ./artemis help data compact.Copy to Clipboard Copied! Toggle word wrap Toggle overflow Run the following CLI command to compact the data.
./artemis data compact.
$ ./artemis data compact.Copy to Clipboard Copied! Toggle word wrap Toggle overflow After the tool has successfully compacted the data, restart the broker.
./artemis run
$ ./artemis runCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Additional resources
6.1.7. Disabling the disk write cache Copy linkLink copied to clipboard!
Disk write caching improves performance by writing data to memory before it is written to disk. This means that there is no guarantee that all the data is written to disk, which exposes the risk of data loss if a failure occurs. You should, therefore, disable disk write caching.
Some more expensive disks have non-volatile or battery-backed write caches that do not necessarily lose data in event of failure, but you should test them. If your disk does not have such features, you should ensure that write cache is disabled. Be aware that disabling disk write cache can negatively affect performance.
Procedure
-
On Linux, to manage the disk write cache settings, use the tools
hdparm(for IDE disks) orsdparmorsginfo(for SDSI/SATA disks). - On Windows, to manage the disk writer cache settings, right-click the disk. Select Properties.
6.2. Persisting message data in a database Copy linkLink copied to clipboard!
When you persist message data in a database, the broker uses a Java Database Connectivity (JDBC) connection to store message and bindings data in database tables. The data in the tables is encoded using AMQ Broker journal encoding.
For information about supported databases, see Red Hat AMQ 7 Supported Configurations on the Red Hat Customer Portal.
An administrator might choose to store message data in a database based on the requirements of an organization’s wider IT infrastructure. However, use of a database can negatively effect the performance of a messaging system. Specifically, writing messaging data to database tables via JDBC has a significant performance impact for the broker.
6.2.1. Configuring JDBC persistence Copy linkLink copied to clipboard!
To establish a connection between the broker and the JDBC database, you must provide the broker with the JAR file that contains the appropriate JDBC driver, and the connection details for the database.
Procedure
Add the appropriate JDBC client libraries to the broker runtime. To do this, add the relevant
.JARfiles to the<broker_instance_dir>/libdirectory.If you want to add the
.JARfiles to a different directory, you must add that directory to the Java classpath. For more information see Section 1.5, “Extending the JAVA Classpath”.-
Open the
<broker_instance_dir>/etc/broker.xmlconfiguration file. Within the
coreelement, add astoreelement that contains adatabase-storeelement.Copy to Clipboard Copied! Toggle word wrap Toggle overflow Within the
database-storeelement, add configuration parameters for JDBC persistence and specify values. For example:Copy to Clipboard Copied! Toggle word wrap Toggle overflow - jdbc-connection-url
- Full JDBC connection URL for your database server. The connection URL should include all configuration parameters and the database name.
- jdbc-user
- Encrypted user name for your database server. For more information about encrypting user names and passwords for use in configuration files, see Section 5.10, “Encrypting passwords in configuration files”.
- jdbc-password
- Encrypted password for your database server. For more information about encrypting user names and passwords for use in configuration files, see Section 5.10, “Encrypting passwords in configuration files”.
- bindings-table-name
- Name of the table in which bindings data is stored. Specifying a table name enables you to share a single database between multiple servers, without interference.
- message-table-name
- Name of the table in which message data is stored. Specifying this table name enables you to share a single database between multiple servers, without interference.
- large-message-table-name
- Name of the table in which large messages and related data are persisted. In addition, if a client streams a large message in chunks, the chunks are stored in this table. Specifying this table name enables you to share a single database between multiple servers, without interference.
- page-store-table-name
- Name of the table in which paged store directory information is stored. Specifying this table name enables you to share a single database between multiple servers, without interference.
- node-manager-store-table-name
- Name of the table in which the shared store high-availability (HA) locks for primary and backup brokers and other HA-related data is stored on the broker server. Specifying this table name enables you to share a single database between multiple servers, without interference. Each primary-backup pair that uses shared store HA must use the same table name. You cannot share the same table between multiple (and unrelated) primary-backup pairs.
- jdbc-driver-class-name
- Fully-qualified class name of the JDBC database driver. For information about supported databases, see Red Hat AMQ 7 Supported Configurations on the Red Hat Customer Portal.
- jdbc-network-timeout
-
JDBC network connection timeout, in milliseconds. The default value is 20000 milliseconds. When using a JDBC for shared store HA, it is recommended to set the timeout to a value less than or equal to
jdbc-lock-expiration. - jdbc-lock-renew-period
-
Length, in milliseconds, of the renewal period for the current JDBC lock. When this time elapses, the broker can renew the lock. It is recommended to set a value that is several times smaller than the value of
jdbc-lock-expiration. This gives the broker sufficient time to extend the lease and also gives the broker time to try to renew the lock in the event of a connection problem. The default value is 2000 milliseconds. - jdbc-lock-expiration
Time, in milliseconds, that the current JDBC lock is considered owned (that is, acquired or renewed), even if the value of
jdbc-lock-renew-periodhas elapsed.The broker periodically tries to renew a lock that it owns according to the value of
jdbc-lock-renew-period. If the broker fails to renew the lock (for example, due to a connection problem) the broker keeps trying to renew the lock until the value ofjdbc-lock-expirationhas passed since the lock was last successfully acquired or renewed.An exception to the renewal behavior described above is when another broker acquires the lock. This can happen if there is a time misalignment between the Database Management System (DBMS) and the brokers, or if there is a long pause for garbage collection. In this case, the broker that originally owned the lock considers the lock lost and does not try to renew it.
After the expiration time elapses, if the JDBC lock has not been renewed by the broker that currently owns it, another broker can establish a JDBC lock.
The default value of
jdbc-lock-expirationis 20000 milliseconds.- jdbc-journal-sync-period
- Duration, in milliseconds, for which the broker journal synchronizes with JDBC. The default value is 5 milliseconds.
- jdbc-max-page-size-bytes
-
Maximum size, in bytes, of each page file when AMQ Broker persists messages to a JDBC database. The default value is
102400, which is 100KB. The value that you specify also supports byte notation such as "K" "MB", and "GB".
6.2.2. Configuring JDBC connection pooling Copy linkLink copied to clipboard!
A connection pool is a set of database connections that are kept open and reused to reduce the overhead of repeatedly creating and closing new connections. If the connection between a broker and the database fails, the broker attempts to reconnect to the database using a different connection from the pool.
The following example shows how to configure JDBC connection pooling.
If you do not explicitly configure JDBC connection pooling, the broker uses connection pooling with a default configuration. The default configuration uses values from your existing JDBC configuration. For more information, see Default connection pooling configuration.
Prerequisites
- This example builds on the example for configuring JDBC persistence. See Section 6.2.1, “Configuring JDBC persistence”
To enable connection pooling, AMQ Broker uses the Apache Commons DBCP package. Before configuring JDBC connection pooling for the broker, you should be familiar with what this package provides. For more information, see:
Procedure
-
Open the
<broker-instance-dir>/etc/broker.xmlconfiguration file. Within the
database-storeelement that you previously added for your JDBC configuration, remove thejdbc-driver-class-name,jdbc-connection-url,jdbc-user,jdbc-password, parameters. Later in this procedure, you will replace these with corresponding DBCP configuration parameters.NoteIf you do not explicitly remove the preceding parameters, the corresponding DBCP parameters that you add later in this procedure take precedence.
Within the
database-storeelement, add adata-source-propertieselement. For example:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Within the new
data-source-propertieselement, add DBCP data source properties for connection pooling. Specify key-value pairs. For example:Copy to Clipboard Copied! Toggle word wrap Toggle overflow driverClassName- Fully-qualified class name of the JDBC database driver.
url- Full JDBC connection URL for your database server.
username- Encrypted user name for your database server. You can also specify this value as unencrypted, plain text. For more information about encrypting user names and passwords for use in configuration files, see Section 5.10, “Encrypting passwords in configuration files”.
password- Encrypted password for your database server. You can also specify this value as unencrypted, plain text. For more information about encrypting user names and passwords for use in configuration files, see Section 5.10, “Encrypting passwords in configuration files”.
poolPreparedStatements-
When the value of this parameter is set to
true, the pool can have an unlimited number of cached prepared statements. This reduces initialization costs. maxTotal-
Maximum number of connections in the pool. When the value of this parameter is set to
-1, there is no limit.
If you do not explicitly configure JDBC connection pooling, the broker uses connection pooling with a default configuration. The default configuration is described in the table.
Expand Table 6.1. Default connection pooling configuration DBCP configuration parameter Default value driverClassNameThe value of the existing
jdbc-driver-class-nameparameterurlThe value of the existing
jdbc-connection-urlparameterusernameThe value of the existing
jdbc-userparameterpasswordThe value of the existing
jdbc-passwordparameterpoolPreparedStatementstruemaxTotal-1NoteReconnection works only if no client is actively sending messages to the broker. If there is an attempt to write to the database tables during reconnection, the broker fails and shuts down.
Additional resources
6.3. Disabling persistence Copy linkLink copied to clipboard!
In some situations, it might be a requirement that a messaging system does not store any data. To meet this requirement, you can disable persistence on the broker.
Procedure
-
Open the
<broker_instance_dir>/etc/broker.xmlconfiguration file. Within the
coreelement, set the value of thepersistence-enabledparameter tofalse.Copy to Clipboard Copied! Toggle word wrap Toggle overflow No message data, bindings data, large message data, duplicate ID cache, or paging data is persisted.