Chapter 7. Paging Messages AMQ Broker transparently supports huge queues containing millions of messages while the server is running with limited memory. In such a situation it's not possible to store all of the queues in memory at any one time, so AMQ Broker transparently pages messages into and out of memory as they are needed, thus allowing massive queues with a low memory footprint. Paging is done individually per address. AMQ Broker will start paging messages to disk when the size of all messages in memory for an address exceeds a configured maximum size. For more information about addresses, see Configuring addresses and queues . By default, AMQ Broker does not page messages. You must explicitly configure paging to enable it. See the paging example located under INSTALL_DIR /examples/standard/ for a working example showing how to use paging with AMQ Broker. 7.1. About Page Files Messages are stored per address on the file system. Each address has an individual folder where messages are stored in multiple files (page files). Each file will contain messages up to a max configured size ( page-size-bytes ). The system will navigate on the files as needed, and it will remove the page file as soon as all the messages are acknowledged up to that point. Browsers will read through the page-cursor system. Consumers with selectors will also navigate through the page-files and ignore messages that don't match the criteria. Note When you have a queue, and consumers filtering the queue with a very restrictive selector you may get into a situation where you won't be able to read more data from paging until you consume messages from the queue. Example: in one consumer you make a selector as 'color="red"' but you only have one color red one million messages after blue, you won't be able to consume red until you consume blue ones. This is different to browsing as we will "browse" the entire queue looking for messages and while we "depage" messages while feeding the queue. 7.2. Configuring the Paging Directory Location To configure the location of the paging directory, add the paging-directory configuration element to the broker's main configuration file BROKER_INSTANCE_DIR /etc/broker.xml , as in the example below. <configuration ...> ... <core ...> <paging-directory>/somewhere/paging-directory</paging-directory> ... </core> </configuration> AMQ Broker will create one directory for each address being paged under the configured location. 7.3. Configuring an Address for Paging Configuration for paging is done at the address level by adding elements to a specific address-settings , as in the example below. <address-settings> <address-setting match="jms.paged.queue"> <max-size-bytes>104857600</max-size-bytes> <page-size-bytes>10485760</page-size-bytes> <address-full-policy>PAGE</address-full-policy> </address-setting> </address-settings> In the example above, when messages sent to the address jms.paged.queue exceed 104857600 bytes in memory, the broker will begin paging. Note Paging is done individually per address. If you specify max-size-bytes for an address, each matching address does not exceed the maximum size that you specified. It DOES NOT mean that the total overall size of all matching addresses is limited to max-size-bytes . This is the list of available parameters on the address settings. Table 7.1. Paging Configuration Elements Element Name Description Default max-size-bytes The maximum size in memory allowed for the address before the broker enters page mode. -1 (disabled). When this parameter is disabled, the broker uses global-max-size as a memory-usage limit for paging instead. For more information, see Section 7.4, "Configuring a Global Paging Size" . page-size-bytes The size of each page file used on the paging system. 10MiB (10 \* 1024 \* 1024 bytes) address-full-policy Valid values are PAGE , DROP , BLOCK , and FAIL . If the value is PAGE then further messages will be paged to disk. If the value is DROP then further messages will be silently dropped. If the value is FAIL then the messages will be dropped and the client message producers will receive an exception. If the value is BLOCK then client message producers will block when they try and send further messages. PAGE page-max-cache-size The system will keep up to this number of page files in memory to optimize IO during paging navigation. 5 page-sync-timeout Time, in nanoseconds, between periodic page synchronizations. If you are using an asynchronous IO journal (that is, journal-type is set to ASYNCIO in the broker.xml configuration file), the default value is 3333333 nanoseconds (that is, 3.333333 milliseconds). If you are using a standard Java NIO journal (that is, journal-type is set to NIO ), the default value is the configured value of the journal-buffer-timeout parameter. 7.4. Configuring a Global Paging Size Sometimes configuring a memory limit per address is not practical, such as when a broker manages many addresses that have different usage patterns. In these situations, use the global-max-size parameter to set a global limit to the amount of memory the broker can use before it enters into the page mode configured for the address associated with the incoming message. The default value for global-max-size is half of the maximum memory available to the Java virtual machine (JVM). You can specify your own value for this parameter by configuring it in the broker.xml configuration file. The value for global-max-size is in bytes, but you can use byte notation ("K", "Mb", "GB", for example) for convenience. The following procedure shows how to configure the global-max-size parameter in the broker.xml configuration file. Configuring the global-max-size parameter Procedure Stop the broker. If the broker is running on Linux, run the following command: If the broker is running on Windows as a service, run the following command: Open the broker.xml configuration file located under BROKER_INSTANCE_DIR /etc . Add the global-max-size parameter to broker.xml to limit the amount of memory, in bytes, the broker can use. Note that you can also use byte notation ( K , Mb , GB ) for the value of global-max-size , as shown in the following example. <configuration> <core> ... <global-max-size>1GB</global-max-size> ... </core> </configuration> In the preceding example, the broker is configured to use a maximum of one gigabyte, 1GB , of available memory when processing messages. If the configured limit is exceeded, the broker enters the page mode configured for the address associated with the incoming message. Start the broker. If the broker is running on Linux, run the following command: If the broker is running on Windows as a service, run the following command: Related Information See Section 7.3, "Configuring an Address for Paging" for information about setting the paging mode for an address. 7.5. Limiting Disk Usage when Paging You can limit the amount of physical disk the broker uses before it blocks incoming messages rather than pages them. Add the max-disk-usage to the broker.xml configuration file and provide a value for the percentage of disk space the broker is allowed to use when paging messages. The default value for max-disk-usage is 90 , which means the limit is set at 90 percent of disk space. Configuring the max-disk-usage Procedure Stop the broker. If the broker is running on Linux, run the following command: If the broker is running on Windows as a service, run the following command: Open the broker.xml configuration file located under BROKER_INSTANCE_DIR /etc . Add the max-disk-usage configuration element and set a limit to the amount disk space to use when paging messages. <configuration> <core> ... <max-disk-usage>50</max-disk-usage> ... </core> </configuration> In the preceding example, the broker is limited to using 50 percent of disk space when paging messages. Messages are blocked and no longer paged after 50 percent of the disk is used. Start the broker. If the broker is running on Linux, run the following command: If the broker is running on Windows as a service, run the following command: 7.6. How to Drop Messages Instead of paging messages when the max size is reached, an address can also be configured to just drop messages when the address is full. To do this just set the address-full-policy to DROP in the address settings 7.6.1. Dropping Messages and Throwing an Exception to Producers Instead of paging messages when the max size is reached, an address can also be configured to drop messages and also throw an exception on the client-side when the address is full. To do this just set the address-full-policy to FAIL in the address settings 7.7. How to Block Producers Instead of paging messages when the max size is reached, an address can also be configured to block producers from sending further messages when the address is full, thus preventing the memory from being exhausted on the server. Note Blocking works only if the protocol being used supports it. For example, an AMQP producer will understand a Block packet when it is sent by the broker, but a STOMP producer will not. When memory is freed up on the server, producers will automatically unblock and be able to continue sending. To do this just set the address-full-policy to BLOCK in the address settings. In the default configuration, all addresses are configured to block producers after 10 MiB of data are in the address. 7.8. Caution with Addresses with Multicast Queues When a message is routed to an address that has multicast queues bound to it, for example, a JMS subscription in a Topic, there is only one copy of the message in memory. Each queue handles only a reference to it. Because of this the memory is only freed up after all queues referencing the message have delivered it. If you have a single lazy subscription, the entire address will suffer IO performance hit as all the queues will have messages being sent through an extra storage on the paging system. For example: An address has 10 queues One of the queues does not deliver its messages (maybe because of a slow consumer). Messages continually arrive at the address and paging is started. The other 9 queues are empty even though messages have been sent. In this example, all the other 9 queues will be consuming messages from the page system. This may cause performance issues if this is an undesirable state.

Commands:
<configuration ...> <core ...> <paging-directory>/somewhere/paging-directory</paging-directory> </core> </configuration>
<address-settings> <address-setting match="jms.paged.queue"> <max-size-bytes>104857600</max-size-bytes> <page-size-bytes>10485760</page-size-bytes> <address-full-policy>PAGE</address-full-policy> </address-setting> </address-settings>
BROKER_INSTANCE_DIR /bin/artemis stop
BROKER_INSTANCE_DIR \bin\artemis-service.exe stop
<configuration> <core> <global-max-size>1GB</global-max-size> </core> </configuration>
BROKER_INSTANCE_DIR /bin/artemis run
BROKER_INSTANCE_DIR \bin\artemis-service.exe start
BROKER_INSTANCE_DIR /bin/artemis stop
BROKER_INSTANCE_DIR \bin\artemis-service.exe stop
<configuration> <core> <max-disk-usage>50</max-disk-usage> </core> </configuration>
BROKER_INSTANCE_DIR /bin/artemis run
BROKER_INSTANCE_DIR \bin\artemis-service.exe start