KahaDB is the recommended message store to use with Fuse Message Broker in order to achieve maximum performance. The KahaDB supports several options that you can customize to obtain optimum performance.
Figure 2.1 gives an overview of the sequence of steps for a message dispatched synchronously through a persistent broker.
After receiving a message from a producer, the broker dispatches the messages to the consumers, as follows:
The broker pushes the message into the message store. Assuming that the
enableJournalDiskSyncs
option istrue
, the message store also writes the message to disk, before the broker proceeds.The broker now sends the message to all of the interested consumers (but does not wait for consumer acknowledgments). For topics, the broker dispatches the message immediately, while for queues, the broker adds the message to a destination cursor.
The broker then sends a receipt back to the producer. The receipt can thus be sent back before the consumers have finished acknowledging messages (in the case of topic messages, consumer acknowledgments are usually not required anyway).
To speed up the performance of the broker, you can enable the concurrent store and dispatch optimization, which allows storing the message and sending to the consumer to proceed concurrently.
Note | |
---|---|
Concurrent store and dispatch is enabled, by default, for queues. |
Figure 2.1 gives an overview of message dispatch when the concurrent store and dispatch optimization is enabled.
After receiving a message from a producer, the broker dispatches the messages to the consumers, as follows:
The broker pushes the message onto the message store and, concurrently, sends the message to all of the interested consumers. After sending the message to the consumers, the broker then sends a receipt back to the producer, without waiting for consumer acknowledgments or for the message store to synchronize to disk.
As soon as the broker receives acknowledgments from all the consumers, the broker removes the message from the message store. Because consumers typically acknowledge messages faster than a message store can write them to disk, this often means that write to disk is optimized away entirely. That is, the message is removed from the message store before it is ever physically written to disk.
One drawback of concurrent store and dispatch is that it does reduce reliability.
The concurrent store and dispatch feature can be enabled separately for queues and
topics, by setting the concurrentStoreAndDispatchQueues
flag and the
concurrentStoreAndDispatchTopics
flag. By default, it is enabled
for queues, but disabled for topics. To enable concurrent store and dispatch for
both queues and topics, configure the kahaDB
element in the broker configuration as follows:
<broker brokerName="broker" persistent="true" useShutdownHook="false"> ... <persistenceAdapter> <kahaDB directory="activemq-data" journalMaxFileLength="32mb" concurrentStoreAndDispatchQueues="true" concurrentStoreAndDispatchTopics="true" /> </persistenceAdapter> </broker>
Note | |
---|---|
In versions of Fuse Message Broker prior to 5.4.0, it was possible to enable concurrent store and dispatch for transactions as well, but this option is no longer supported. Transaction are now always executed serially (as in Figure 2.1). |
After a queue message is written to persistent storage, a copy of the message remains in memory, pending dispatch to a consumer. If the relevant consumer is very slow, however, this can lead to a build-up of messages in the broker and, in some cases, can lead to an out-of-memory error. If you observer this problem in your broker, you can enable an option to reduce the memory footprint of the pending messages; but you should note that this option is not compatible with concurrent store and dispatch.
To reduce the memory footprint of pending queue messages, define a destination
policy for the relevant queues, enabling the reduceMemoryFootprint
option, as follows:
<broker ... > ... <destinationPolicy> <policyMap> <policyEntries> <policyEntry queue=">" reduceMemoryFootprint="true" /> </policyEntries> </policyMap> </destinationPolicy> ... </broker>
When the reduceMemoryFootprint
option is enabled, a message's
marshalled content is cleared immediately after the message is written to persistent
storage. This results in approximately a 50% reduction in the amount of memory
occupied by the pending messages.