Thursday, 8 August 2013

Hazelcast is an in-memory data grid that provides a scaleable data store with a rich set of features. Over the past year I've been using it in other applications and I've been impressed with it's capabilities. A new feature in recently released Hazelcast 3.0, is the ability to plug-in your own serialization code. By allowing Argot to be used both in the in-memory data grid and as the transport for Internet of Things applications, it allows the same code developed for Argot to be used in Big-Data applications. The combination of Hazelcast and Argot means less code, less development time and more scale.

Recently the Hazelcast team made available a small benchmark code that provided both examples of how various serialization software could be embedded into Hazelcast and showed a rudimentary benchmark for the different methods. The code is made available here. I've forked the code and included Argot as an additional example.

The rest of this post covers the details of how I integrated with Hazelcast. It also includes a discussion of how Argot's performance compares to the other serialization techniques used in the benchmark.

Argot Hazelcast Integration

In this example the Argot definition for the 'sample' object is defined as follows. The default Argot common dictionary doesn't include the generic long_array or double_array, so I've also created them here:

The above elements would be required for any Argot
based implementation and is not a special requirement of the Hazelcast
implementation. I've included them here for completeness of the example.

The bridge between Hazelcast and Argot is defined by a StreamSerializer implementation. The ArgotSerializer provides the generic implementation that can be used by any object. The read and write methods read and write the object to stream.

The Hazelcast API makes registering and using custom serialization reasonable simple to configure. A class is bound to a serializer. In this example I'm binding the SampleObject class to the ArgotSerializer:

That's it, the Sample object can now be serialized to the Internet of Things and can also be stored in a Big-Data environment.

Argot Performance

Having not looked at Argot performance for some time, I was very interested to see how Argot would perform in the benchmark. While performance is not necessarily the number one decision in choosing a serialization protocol, it is reasonably important.

The first test I conducted didn't include either the array of long values or the array of double values. The results were:

Argot Serialization

4172 bytes

348 ms

Java Serialization

4336 bytes

411 ms

DataSerializable

4237 bytes

263 ms

IdentifiedDataSerializable

4186 bytes

170 ms

Portable

4205 bytes

228 ms

Kryo

4336 bytes

277 ms

Kryo-unsafe

4336 bytes

256 ms

While Argot didn't come first in the first performance test, it wasn't last which isn't bad, especially considering Argot hasn't had a lot of performance tuning done. Argot did win at using the least amount of data. This can be achieve as it uses meta data describe the structure of the binary format. This results in less data stored at runtime.

Being reasonably happy with Argot's performance, the next step I did was include the array of long values in the sample object. The benchmark stores 3000 long values to the array. The initial results were very bad for Argot and made me realise that the implementation of int64 in Argot was based on some old code that wrote individual bytes to the stream. After fixing this up, the following results were achieved:

Argot Serialization

28174 bytes

5587 ms

Java Serialization

28374 bytes

862 ms

DataSerializable

28241 bytes

918 ms

IdentifiedDataSerializable

28190 bytes

851 ms

Portable

28213 bytes

904 ms

Kryo

28374 bytes

786 ms

Kryo-unsafe

28374 bytes

727 ms

Ouch! The Argot performance of writing an array of 3000 int64's was six times worse than the closest performer. This test showed me two things; the first is that this benchmark is heavily biased towards arrays, and the second is that Argot's default array marshaller is terrible at dealing with large arrays of simple types.

After some further investigation I discovered that performance for arrays is all gained/lost in the number of calls to read or write to the stream. If you can minimize stream writes you can improve the performance greatly. Not to give up, I used Argot's ability to implement custom marshalling to implement a fast int64 array marshaller. The writer for the marshaller is as follows:

This implementation minimises writes to the stream by allocating the full byte stream and preparing the data before writing it out to the stream. A similar reader was written which reads the full array in before parsing it. To connect the new marshaller to the long array was a simple matter of changing the binding:

library.bind( library.getTypeId("long_array", "1.0"),

new LongArrayReader(), new LongArrayWriter(), long[].class);

After running the benchmark again, I got the following results:

Argot Serialization

28174 bytes

768 ms

Java Serialization

28374 bytes

832 ms

DataSerializable

28241 bytes

899 ms

IdentifiedDataSerializable

28190 bytes

816 ms

Portable

28213 bytes

887 ms

Kryo

28374 bytes

713 ms

Kryo-unsafe

28374 bytes

703 ms

With the optimized array marshaller Argot comes third in the benchmark! Not a bad result.

In conclusion, it's been very interesting to see how Argot compares to other serialization techniques in both implementation and performance. I've concluded that for objects with many simple fields, Argot is performing reasonably, however, additional buffering would likely bring Argot inline with some of the faster serialization implementations. I will put that on the task list for Argot 1.4. In addition, the serialization of large arrays are best done by specialised implementations. In implementations where performance is important it's good to know that Argot is flexible enough to allow this to be configured.

Sunday, 9 June 2013

Today I've released Argot v1.3.b4 (beta 4). This has a couple of changes found while developing the Arduino MQTT Argot tutorial which went online today. The changes include:

Modify the meta marshaller - During the development of the tutorial I found that a TODO in the code which related to building TypeMaps which use the MetaAbstract type. The code originally required that the full meta dictionary be included in all user defined TypeMaps. This has now been fixed and the new tutorial shows it nicely with having only 7 data types.

Update the compiler - Added the ability to use expressions in the simple definition syntax. This was mainly so I could use the meta.abstract data type simply in the tutorial. It was also on the TODO list, so nice to get this out of the way too.

Update the Argot marshaller annotation - The original annotation only allowed a select few marshallers to be used which were defined in an enumerated type. The enumerated type is now removed and the marshaller class is now added directly.

The new tutorial demonstrates using Argot with MQTT. The use of the Arduino was not required, however, it does nicely show an end-to-end use case of the software. The Arduino code is currently hand crafted to process the message received from Argot. Future releases will include an Arduino Argot library to automate the processing code.

Friday, 7 June 2013

I've been setting up to write some demos of using Argot over MQTT. To run tests I decided to use the Mosquitto MQTT broker. It's really quite simple to install on OSX if you follow this simple procedure.

Before you do anything ensure that you Xcode installed on your computer. This is a pre-requisite for building and installing Mosquitto. Go to the App store and search for and install Xcode.

After Xcode is installed open a Terminal window and install Brew. The output should look something like:

As directed I ran the 'brew doctor' command before installing anything.

$ brew doctor
Warning: Experimental support for using Xcode without the "Command Line Tools".
You have only installed Xcode. If stuff is not building, try installing the
"Command Line Tools for Xcode" package provided by Apple.
Warning: Your file-system on / appears to be CaSe SeNsItIvE.
Homebrew is less tested with that - don't worry but please report issues.

Now that brew is installed it's time to install Mosquitto. Next at the command prompt type 'brew install mosquitto'. The output looks something like:

/usr/local/etc/mosquitto/mosquitto.conf
Python client bindings can be installed from the Python Package Index
pip install mosquitto
Javascript client is available at
http://mosquitto.org/js/
To have launchd start mosquitto at login:
mkdir -p ~/Library/LaunchAgents
ln -sfv /usr/local/opt/mosquitto/*.plist ~/Library/LaunchAgents
Then to load mosquitto now:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mosquitto.plist
Or, if you don't want/need launchctl, you can just run:

mosquitto -c /usr/local/etc/mosquitto/mosquitto.conf
Warning: /usr/local/sbin is not in your PATH
You can amend this by altering your ~/.bashrc file
==> Summary
/usr/local/Cellar/mosquitto/1.1.3: 26 files, 564K, built in 8 seconds

Friday, 31 May 2013

As a step towards a full release of Argot, I've decided to release Argot 1.3.b3 (beta 3). This release includes a number of significant changes and is nearly ready for a full release. It includes the following changes:

Removed packages. The older 1.2.x versions of Argot includes packages which are designed to operate in a more traditional request/response environment. As the Argot 1.3 release is targeted towards MQTT and the Internet of Things, these packages will be released in a separate argot-remote package in the future.

Removed example. The older 1.2.x versions of Argot included a bookstore example which was modeled on older RPC mechanisms. Once again, as this release is targeted towards the Internet of Things I've decided to remove it. More relevant examples will be provided in the future.

Updated the meta dictionary. The Argot meta dictionary defines the core types from which all other data types are defined. The updates includes combining a number of extensions which are not strictly required by the meta dictionary, but make maintenance and implementation easier. This allowed removing a few classes from the library.

Documentation removed. The documentation provided with the older version is out of date and would be more confusing than anything else. Removed until this is updated in the future.

Additional cleanup. Changes such as updating the name of the bool type to boolean and various other small changes were made. The full list is maintained in the readme file.

Given this release contains no documentation and only one example is provided, it is only for the brave. The next steps are to create examples which show off the capability of Argot better and ensure the core library and compiler are thoroughly tested. To that end I've acquired a Freetronics EtherTen and a Freetronics Cube. These are both Arduino compatible and will provide great examples of Argot in action.

Saturday, 25 May 2013

A little less than a month ago, I committed to getting Argot online again. I have been spurred on by the rise of activity surrounding the Internet of Things, and in particular the transport layer MQTT. I feel that Argot provides a unique solution not currently available which will fit nicely with MQTT and the Internet of Things. The Argot website is still sparse, however over the next few weeks/months I will be releasing more software and documentation. To start, I have provided a simple example which demonstrates the development of an Argot application in Java. You can view this on the 'Quick Start' page and easily install it to Eclipse to try it out.

There's still a few things to be done before I can release the next release of Argot (v1.3.0). These include:

Update the Argot compiler to make it a little easier to use. The current Argot language is based around S-Expressions, however, for many this looks quite foreign. I plan a few small tweaks to make the most common data structures easy to define.

Strip out extensions from the core Argot library. In the past, a few extensions have crept into the main Argot library. These are being separated to simplify the core Argot library.

Following this, I will be continuing development of an Argot MQTT extension. The planning for this has already started and has been documented on the MQTT mailing list. I'll write more about this later.

In regards to the website, I'm particular pleased with the new logo and design which was put together with the assistance of my wonderful wife and sister.