From 9f88d7468b649a33dae35944893280787cdc2605 Mon Sep 17 00:00:00 2001 From: Dejan Bosanac Date: Wed, 15 Feb 2017 14:28:03 +0100 Subject: [PATCH] [docs] migration guide - introduction --- docs/migration-guide/en/README.md | 37 ++++++++++++++++++ docs/migration-guide/en/SUMMARY.md | 4 ++ docs/migration-guide/en/book.json | 12 ++++++ .../en/images/artemis-logo.jpg | Bin 0 -> 18517 bytes docs/migration-guide/en/notice.md | 17 ++++++++ 5 files changed, 70 insertions(+) create mode 100644 docs/migration-guide/en/README.md create mode 100644 docs/migration-guide/en/SUMMARY.md create mode 100644 docs/migration-guide/en/book.json create mode 100644 docs/migration-guide/en/images/artemis-logo.jpg create mode 100644 docs/migration-guide/en/notice.md diff --git a/docs/migration-guide/en/README.md b/docs/migration-guide/en/README.md new file mode 100644 index 0000000000..562ec14280 --- /dev/null +++ b/docs/migration-guide/en/README.md @@ -0,0 +1,37 @@ +![ActiveMQ Artemis logo](images/artemis-logo.jpg) + +Apache ActiveMQ Artemis Migration Guide +===================================== + +As more and more people start using Artemis, it's valuable to have a migration guide that will help experienced ActiveMQ users adapt to the new broker. From outside, two brokers might seem very similar, but there are subtle differences in their inner-workings that can lead to confusions. The goal of this guide is to explain these differences and help make a transition. + +Migration is a fairly broad term in systems like these, so what are we talking about here? This guide will be focused only on broker server migration. We'll assume that the current system is a working ActiveMQ 5.x broker with OpenWire JMS clients. We'll see how we can replace the broker with Artemis and leave the clients intact. This guide will not cover a message store migration. That topic and aspects of migrating clients that use some other protocol will be the subject of future guides. + +This guide is aimed at experienced ActiveMQ users that want to learn more about what's different in Artemis. We will assume that you know the concepts that are covered in these articles. They will not be explained from the first principles, for that you're advised to see appropriate manuals of the ActiveMQ and Artemis brokers. + +Before we dig into more details on the migration, let's talk about basic conceptual differences between two brokers. + +## Architectural differences + +Although they are designed to do the same job, things are done differently internally. Here are some of the most notable architectural differences you need to be aware of when you're planning the migration. + +In ActiveMQ, we have a few different implementations of the IO connectivity layer, like tcp (synchronous one) and nio (non-blocking one). In Artemis, the IO layer is implemented using Netty, which is a nio framework. This means that there's no more need to choose between different implementations as the non-blocking one is used by default. + +The other important part of every broker is a message store. Most of the ActiveMQ users are familiar with KahaDB. It consists of a message journal for fast sequential storing of messages (and other command packets) and an index for retrieving messages when needed. + +Artemis has its own message store. It consists only of the append-only message journal. Because of the differences in how paging is done, there's no need for the message index. We'll talk more about that in a minute. It's important to say at this point that these two stores are not interchangeable, and data migration if needed must be carefully planed. + +What do we mean by paging differences? Paging is the process that happens when broker can't hold all incoming messages in its memory. The strategy of how to deal with this situation differs between two brokers. ActiveMQ have *cursors*, which are basically a cache of messages ready to be dispatched to the consumer. It will try to keep all incoming messages in there. When we run out of the the available memory, messages are added to the store, but the caching stops. When the space become available again, the broker will fill the cache again by pulling messages from the store in batches. Because of this, we need to read the journal from time to time during a broker runtime. In order to do that, we need to maintain a journal index, so that messages' position can be tracked inside the journal. + +In Artemis, things work differently in this regard. The whole message journal is kept in memory and messages are dispatched directly from it. When we run out of memory, messages are paged *on the producer side* (before they hit the broker). Theay are stored in sequential page files in the same order as they arrived. Once the memory is freed, messages are moved from these page files into the journal. With paging working like this, messages are read from the file journal only when the broker starts up, in order to recreate this in-memory version of the journal. In this case, the journal is only read sequentially, meaning that there's no need to keep an index of messages in the journal. + +This is one of the main differences between ActiveMQ 5.x and Artemis. It's important to understand it early on as it affects a lot of destination policy settings and how we configure brokers in order to support these scenarios properly. + +## Addressing differences + +Another big difference that's good to cover early on is the difference is how message addressing and routing is done. ActiveMQ started as a open source JMS implementation, so at its core all JMS concepts like queues, topics and durable subscriptions are implemented as the first-class citizens. It's all based on OpenWire protocol developed within the project and even KahaDB message store is OpenWire centric. This means that all other supported protocols, like MQTT and AMQP are translated internally into OpenWire. + +Artemis took a different approach. It implements only queues internally and all other messaging concepts are achieved by routing messages to appropriate queue(s) using addresses. Messaging concepts like publish-subscribe (topics) and point-to-point (queues) are implemented using different type of routing mechanisms on addresses. *Multicast* routing is used to implement *publish-subscribe* semantics, where all subscribers to a certain address will get their own internal queue and messages will be routed to all of them. *Anycast* routing is used implement *point-to-point* semantics, where there'll be only one queue for the address and all consumers will subscribe to it. The addressing and routing scheme is used across all protocols. So for example, you can view the JMS topic just as a multicast address. We'll cover this topic in more details in the later articles. + + + diff --git a/docs/migration-guide/en/SUMMARY.md b/docs/migration-guide/en/SUMMARY.md new file mode 100644 index 0000000000..6e89af34e6 --- /dev/null +++ b/docs/migration-guide/en/SUMMARY.md @@ -0,0 +1,4 @@ +# Summary + +* [Legal Notice](notice.md) + diff --git a/docs/migration-guide/en/book.json b/docs/migration-guide/en/book.json new file mode 100644 index 0000000000..a5a22a3153 --- /dev/null +++ b/docs/migration-guide/en/book.json @@ -0,0 +1,12 @@ +{ + "title": "ActiveMQ Artemis Documentation", + "description": "ActiveMQ Artemis Migration Guide", + "github": "apache/activemq-artemis", + "githubHost": "https://github.com/", + "gitbook": "3.x.x", + "links": { + "home": "http://activemq.apache.org/", + "issues": "http://activemq.apache.org/", + "contribute": "http://activemq.apache.org/contributing.html" + } +} diff --git a/docs/migration-guide/en/images/artemis-logo.jpg b/docs/migration-guide/en/images/artemis-logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d2c2c6b23904e2cbcbffdb07d47054739ef85628 GIT binary patch literal 18517 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 gq<`h!q6zNm=