High Performance Durable Messaging

Overview

While there are a good number of high performance messaging systems available for Java, most avoid quoting benchmarks which include durable messaging and serialization/deserialization of messages.  This is done for a number of reasons;  1) you don't always need or want durable messages 2) you want the option of using your own serialization.  One important reason they are avoided is that both of these slow down messaging by as much as 10x which doesn't look so good.

Most messaging benchmarks will highlight the performance of passing raw bytes around without durability as this gives the highest numbers. Some also quote durable messaging numbers, but these are typically much slower.

What if you need to serialize and deserialize real data efficiently and you would like to record and replay messages even if you have learnt to do without these.

Higher performance serialization and durability

I have written a library which attempt to solve more of the problem, as I see it, to give you a better overall solution.  It is not the fastest messaging available but it is durable and includes serialization and de-serialization times. As I have noted already this can be 10x higher than the cost of transporting the serialized data so in real applications this solution can be much faster.

An Example: Sending prices

In this test InProcessChronicleTest.testPricePublishing() I send price events consisting of a long timestamp, a symbol, a bid price / volume and ask price / volume.  The time to write the data was 0.35 µS (0.0004 milli-seconds) and the time to receive it over a TCP connection was 0.59 µS.

Note: this connection is durable at both ends so you can see what data has been queue to be sent and what has been received.  If a connection is lost, it can continue from the place it was up to, or optionally playing any message the client has already received, even if the server is not available e.g. if the client is restarted.

To send and receive 5 million messages I used the -Xmx32m -verbosegc flags which show that little heap needed, and not a single GC occurs during this test.  This means the library will have little impact on the rest of your application.

Comparing with Externalize objects.

To put this in context, I have compared this with the time it takes to serialize and deserialize objects containing the same data in  InProcessChronicleTest. testSerializationPerformance().

The PriceUpdate object is Externalizable and this Benchmark for "Comparing various aspects of Serialization libraries on the JVM Platform" shows an Externalizable object can be one of the fastest serializations available.

The time this took on the same machine was 2.7 µS to serialize and 7.5 µS to deserialize.  Note: this doesn't include messaging or persistence, just to do the serialization and deserialization.


SerializationtransportTime to writeTime to read
Java ChronicleTCP and persistence   0.35 µS   0.59 µS
Externalizable         none   2.7 µS   7.5 µS
Serializable         none   3.8 µS 13.2 µS

Conclusion

When benchmarking messaging, you should include how long it takes to send and receive real messages, not just byte[], and include durability if that is desirable.


Comments

  1. Why don't you participate in https://github.com/eishay/jvm-serializers/wiki ?

    ReplyDelete
  2. I have looked at the project, but integrating won't be easy as it has a complex build. I prefer a simple maven build. I will do something like this when I have more time. ;)

    ReplyDelete

Post a Comment

Popular posts from this blog

Java is Very Fast, If You Don’t Create Many Objects

System wide unique nanosecond timestamps

Unusual Java: StackTrace Extends Throwable