程式扎記: [ InAction Note ] Ch5. Message Storage - The JDBC message store

標籤

2016年10月28日 星期五

[ InAction Note ] Ch5. Message Storage - The JDBC message store

Preface: 
The flexibility of the ActiveMQ pluggable message store API allows for many different implementation choices. The oldest and more common store implementation uses JDBC for messaging persistence. The most common reason why so many organizations choose the JDBC message store is because they already have expertise administering relational databases. JDBC persistence is definitely not superior in performance to the aforementioned message store implementations. The fact of the matter is that many businesses have invested in the use of relational databases so they prefer to make full use of them. 

But the use of a shared database is particularly useful for making a redundant master/slave topology out of multiple brokers. When a group of ActiveMQ brokers is configured to use a shared database, they’ll all try to connect and grab a lock in the lock table, but only one will succeed and become the master. The remaining brokers will be slaves, and will be in a wait state, not accepting client connections until the master fails. This is a common deployment scenario for ActiveMQ, which will be covered in more detail in chapter 10. 

When using the JDBC message store, the default JDBC driver used in ActiveMQ is Apache Derby. But many other relational databases are supported. 

Databases supported by the JDBC message store: 
This isn’t an exhaustive list, the JDBC store has been shown to operate with the following relational databases: 
* Apache Derby
* MySQL
* PostgreSQL
* Oracle
* SQL Server
* Sybase
* Informix
* MaxDB

Some users prefer to use a relational database for message persistence simply because of the ability to query the database to examine messages. The following sections will discuss this topic. 

The JDBC message store schema: 
The JDBC message store uses a schema consisting of three tables. Two of the tables are used to hold messages, and the third is used as a lock table to ensure that only one ActiveMQ broker can access the database at one time. Here’s a detailed breakdown of these tables. 

The message table, shown in table 5.3, is by default named ACTIVEMQ_MSGS and is defined as follows. 
 

Messages are broken down and stored into the ACTIVEMQ_MSGS table for both queues and topics. 

There’s a separate table for holding durable subscriber information and an ID to the last message the durable subscriber received. This information is held in the ACTIVEMQ_ACKS table, which is shown in table 5.4. 
 

For durable subscribers, the LAST_ACKED_ID sequence is used as a simple pointer into the ACTIVEMQ_MSGS and enables messages for a particular durable subscriber to be easily selected from the ACTIVEMQ_MSGS table. 

The lock table, called ACTIVEMQ_LOCK, is used to ensure that only one ActiveMQ broker instance can access the database at one time. If an ActiveMQ broker can’t grab the database lock, that broker won’t initialize fully, and will wait until the lock becomes free, or it’s shut down. The table structure of the lock table is defined in table 5.5. 
 

Configuring the JDBC message store: 
Configuring the default JDBC message store is straightforward and the default JDBC store uses Apache Derby in the broker configuration as shown: 


The preceding configuration sets the persistence adaptor for the ActiveMQ broker to be the JDBC message store (which uses Apache Derby by default) and sets the data directory to be used by the embedded Apache Derby instance. 


One of the key properties on the JDBC persistence adapter (the interface onto the JDBC message store) is the dataSource property. This property defines a factory from which connections to a relational database are created. Configuring the dataSource object enables the JDBC persistence adaptor to use physical databases other than the default. Here’s an example of an ActiveMQ configuration for the JDBC message store using the MySQL database: 


The preceding example uses the Apache Commons DBCP BasicDataSource to wrap the MySQL JDBC driver for connection pooling. In the example, the driverClassName is the name of the JDBC driver to use. Some properties that you can configure are passed directly to the database driver itself. For example, maxActive is a property for the MySQL database connector, which tells the database how many active connections to hold open at one time. 


Just as a point of comparison, here’s an example of a configuration to use the Oracle database: 

This example uses the Apache Commons DBCP BasicDataSource to wrap the Oracle JDBC driver for connection pooling. 


Using the JDBC message store with the ActiveMQ journal: 
Though the performance of the JDBC message store isn’t wonderful, it can be improved through the use of the ActiveMQ journal. The journal ensures the consistency of JMS transactions. Because it incorporates fast message writes with caching technology, it can significantly improve the
performance of the ActiveMQ broker


Here’s an example configuration using the journal with JDBC (aka journaled JDBC). In this case, Apache Derby is being used. 


The journal can be used with any JDBC datasource, but it’s important to know when it should and shouldn’t be used. 


The journal offers considerable performance advantages over the use of a standard JDBC message store, especially when the JDBC database is co-located on the same machine as the ActiveMQ broker. The only time when it’s not possible to use the journal is in a shared database master/slave configuration. Because messages from the master may be stored locally in the journal before they’ve been committed to the database, using the journal in this configuration could lead to lost messages if the master failed because the journal isn’t replicated.

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!