Wednesday, February 23, 2011

JMS speed test: ActiveMQ vs HornetQ

A while ago I was asked by a client to evaluate different open source JMS providers. The ultimate goal was to set up a highly available messaging system that can manage high throughput.

Me and my colleagues dug deep in our memories and on the internet to find all of the open source JMS providers. And there are plenty. In the end we looked at the following:
  • ActiveMQ
  • OpenMQ
  • RabbitMQ
  • OpenJMS
  • HornetQ
Besides the requirements of high availability and throughput there were some other requirements:
  • must be JMS 1.1 compliant
  • must be easy to set up and administer
  • vibrant community for support
Because of these reasons we quickly abandoned OpenJMS, which seems to have stopped evolving somewhere in 2006.
RabbitMQ is not JMS compliant, which we really need.
OpenMQ was dropped a little later, since in the first performance tests we found that it was noticably slower than ActiveMQ and HornetQ.

In a next phase we did quite extensive load tests on HornetQ and ActiveMQ, which I'll summarize below.

For our tests we used the following setup:
3 similar machines with 2 quad cores, 8GB of RAM, RHEL 5, Java Hotspot VM 64 bit (1.6.0_21-b06). 2 machines were used for hosting the JMS providers. One machine contains a master, the other a backup instance. The third machine is used for generating load.

The load generation is done using the Sonic test harness. This framework allowed us to generate load on the the JMS providers with different producers and consumers of the JMS queues.

These are some of the results we got (based on size of message, whether messages are persisted, if a transaction is used, number of concurrent producers and receivers):

As you can see both JMS providers are about equal when you look at non peristent messaging.BUT when looking at persistent messaging, HornetQ is just amazing. The throughput you get there is just mindblowing. This has without a doubt to do with the Asynchronous IO feature of HornetQ. This is only available on *NIX based systems but it is well worth it when you are looking for a performant open source JMS provider.

There are other sources of comparisons like these, but they were in our opinion either biased or did not give us enough insight for our situation:
Authored by: Jeroen

Monday, February 7, 2011

RHEL: install Yum and add DVD as repository

Installing Yum using RPM. As you can see this is done by discovering the dependencies the hard way, exactly the reason why we need Yum.

[root@i8c-ODB11R2 Server]# rpm -i yum-3.2.22-26.el5.noarch.rpm
warning: yum-3.2.22-26.el5.noarch.rpm: Header V3 DSA signature: NOKEY, key ID 1e 5e0159
error: Failed dependencies:
python-elementtree is needed by yum-3.2.22-26.el5.noarch
python-iniparse is needed by yum-3.2.22-26.el5.noarch
python-sqlite is needed by yum-3.2.22-26.el5.noarch
rpm-python is needed by yum-3.2.22-26.el5.noarch
urlgrabber >= 3.1.0 is needed by yum-3.2.22-26.el5.noarch
yum-metadata-parser >= 1.1.0 is needed by yum-3.2.22-26.el5.noarch
Installing the Yum dependencies:
[root@i8c-ODB11R2 Server]# rpm -i python-elementtree-1.2.6-5.x86_64.rpm python-iniparse-0.2.3-4.el5.noarch.rpm python-sqlite-1.1.7-1.2.1.x86_64.rpm rpm-python- python-urlgrabber-3.1.0-5.el5.noarch.rpm m2crypto-0.16-6.el5.6.x86_64.rpm python-urlgrabber-3.1.0-5.el5.noarch.rpm yum-metadata-parser-1.1.2-3.el5.x86_64.rpm yum-3.2.22-26.el5.noarch.rpm libxml2-python-2.6.26- createrepo-0.4.11-3.el5.noarch.rpm

Once Yum is installed, you need a Yum repository to install packages from and allow Yum to search the metadata. The repository is created using the createrepo command. We'll create the repository under /root/yumrepo
[root@i8c-ODB11R2 Server]# mkdir /root/yumrepo
[root@i8c-ODB11R2 Server]# cd /root/yumrepo
[root@i8c-ODB11R2 Server]# createrepo -vpo /root/yumrepo /media/
[root@i8c-ODB11R2 Server]# .... listing all packages ...
[root@i8c-ODB11R2 Server]#
3180/3187 - VT/qspice-0.3.0-54.el5.x86_64.rpm
3181/3187 - VT/qspice-libs-0.3.0-54.el5.x86_64.rpm
3182/3187 - VT/qspice-libs-devel-0.3.0-54.el5.x86_64.rpm
3183/3187 - VT/virt-manager-0.6.1-12.el5.x86_64.rpm
3184/3187 - VT/virt-viewer-0.0.2-3.el5.x86_64.rpm
3185/3187 - VT/xen-3.0.3-105.el5.x86_64.rpm
3186/3187 - VT/xen-devel-3.0.3-105.el5.i386.rpm
3187/3187 - VT/xen-devel-3.0.3-105.el5.x86_64.rpm
Saving Primary metadata
Saving file lists metadata
Saving other metadata
Now under /root/yumrepo add symbolic links to the folders of the DVD. Of course when you want to use the repository the DVD must be mounted (to /media in this case).
[root@i8c-ODB11R2 yumrepo]# ln -s /media/Server/ Server
[root@i8c-ODB11R2 yumrepo]# ln -s /media/VT VT
[root@i8c-ODB11R2 yumrepo]# ln -s /media/images/ images
[root@i8c-ODB11R2 yumrepo]# ln -s /media/isolinux/ isolinux
[root@i8c-ODB11R2 yumrepo]# ln -s /media/Cluster Cluster
[root@i8c-ODB11R2 yumrepo]# ln -s /media/ClusterStorage/ ClusterStorage

Next thing is to make the repository known to Yum. This is done by creating a file /etc/yum.repos.d/DVD.repo with the following content:
name=RHEL5 DVD
Now this is done you can use the repo by issuing commands like "yum install" or "yum update", as shown below:
[root@i8c-ODB11R2 yumrepo]# yum update
dvd | 951 B 00:00
dvd/primary | 830 kB 00:00
dvd 3187/3187
Setting up Update Process
Resolving Dependencies
--> Running transaction check
---> Package kernel.x86_64 0:2.6.18- set to be installed
---> Package kernel-headers.x86_64 0:2.6.18- set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

Package Arch Version Repository Size
kernel x86_64 2.6.18- dvd 20 M
kernel-headers x86_64 2.6.18- dvd 1.1 M

Transaction Summary
Install 1 Package(s)
Upgrade 1 Package(s)

Total download size: 21 M
Is this ok [y/N]: y
Downloading Packages:
Total 12 GB/s | 21 MB 00:00
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : kernel 1/3
Updating : kernel-headers 2/3
Cleanup : kernel-headers 3/3

kernel.x86_64 0:2.6.18-

kernel-headers.x86_64 0:2.6.18-

Authored by: Jeroen