I am trying to understand how durable subscription works in ActiveMQ Artemis. Currently my biggest question is about the storage.
I want to know if the messages are duplicated, which means for each consumer, the message is stored to disk or if the messages are stored in one place and consumers only knows the message at which they were disconnected and need to resume.
From my tests, i can see that : with a fixed message size and number of messages published, the space taken on disk is the same, no matter if I have 1,2 or 3 durable subscription. I took care of disconnecting them so that the messages are stored, don't worry. This would lead me to think that the queues only know about the index of the message that the consumer will need to start to consume when he comes back.
But on the opposite, i checked write Bytes per secondes with iostat cmd, and the more i have durable subscription queues, the more this stat grows. Which would mean messages are duplicated.
Do you guys have more informations, even the source code that is responsible for this.
By default ActiveMQ Artemis will store durable messages in a set of local files known as a "journal." In situations where more than one queue has the same message (e.g. in the case of a multiple durable subscriptions on the same JMS topic) the actual message data is only stored once and each queue gets a "reference" to that message. Storing the exact same message data multiple times would be hugely inefficient.
However, it's worth noting that the ActiveMQ Artemis journal files are initialized with zeroes when they are created which means that even an "empty" journal takes up space on the disk. Therefore, when messages are stored in the journal the amount of disk space they take will not change. The existing zeroes will simply be overwritten with the message data.
You can find the source code for ActiveMQ Artemis on GitHub.
If you want to see proof of this behavior you can use the artemis data print
command. This command prints the raw records from the journal in a human readable format. If you were to have 2 durable subscriptions using client IDs of durable-client1
and durable-client2
and subscription names of subscriber-1
and subscriber-2
respectively on a JMS topic named exampleTopic
and you send one message you would end up with an address, 2 queues, 1 actual message, and 2 references in the journal. You'd see something like this in the data print
command output:
********************************************
B I N D I N G S J O U R N A L
********************************************
...
### Surviving Records Summary ###
...
recordID=2;userRecordType=44;isUpdate=false;compactCount=0;PersistentAddressBindingEncoding [id=2, name=exampleTopic, routingTypes={MULTICAST}, autoCreated=false]
recordID=18;userRecordType=21;isUpdate=false;compactCount=0;PersistentQueueBindingEncoding [id=18, name=durable-client1.subscriber-1, address=exampleTopic, filterString=null, user=null, autoCreated=false, maxConsumers=-1, purgeOnNoConsumers=false, exclusive=false, lastValue=false, lastValueKey=null, nonDestructive=false, consumersBeforeDispatch=0, delayBeforeDispatch=-1, routingType=0, configurationManaged=false, groupRebalance=false, groupBuckets=-1, groupFirstKey=null, autoDelete=false, autoDeleteDelay=0, autoDeleteMessageCount=0]
recordID=23;userRecordType=21;isUpdate=false;compactCount=0;PersistentQueueBindingEncoding [id=23, name=durable-client1.subscriber-2, address=exampleTopic, filterString=null, user=null, autoCreated=false, maxConsumers=-1, purgeOnNoConsumers=false, exclusive=false, lastValue=false, lastValueKey=null, nonDestructive=false, consumersBeforeDispatch=0, delayBeforeDispatch=-1, routingType=0, configurationManaged=false, groupRebalance=false, groupBuckets=-1, groupFirstKey=null, autoDelete=false, autoDeleteDelay=0, autoDeleteMessageCount=0]
...
********************************************
M E S S A G E S J O U R N A L
********************************************
...
### Surviving Records Summary ###
recordID=27;userRecordType=45;isUpdate=false;compactCount=0;Message(messageID=27;userMessageID=41705395-b2d1-11e9-91f9-a0afbd82eaba;msg=CoreMessage[messageID=27,durable=true,userID=41705395-b2d1-11e9-91f9-a0afbd82eaba,priority=4, timestamp=Tue Jul 30 08:52:22 CDT 2019,expiration=0, durable=true, address=exampleTopic,size=232,properties=TypedProperties[__AMQ_CID=durable-client1,_AMQ_ROUTING_TYPE=0]]@454305524
recordID=27;userRecordType=32;isUpdate=true;compactCount=0;AddRef;QueueEncoding [queueID=18]
recordID=27;userRecordType=32;isUpdate=true;compactCount=0;AddRef;QueueEncoding [queueID=23]
...