Saturday, March 30, 2013

An Intro to ZeroMQ(ØMQ) On Ubuntu 12.04

What is ØMQ?


ØMQ (also spelled as ZeroMQ, 0MQ, zmq) is an open source (LGPL), brokerless high-performance asynchronous messaging library. It is main aim is for scalable distributed or concurrent applications   It gives you sockets that carry atomic messages across various transports like in-process, inter-process, TCP, and multicast (N-to-N with patterns like fanout, pub-sub, task distribution, and request-reply). The library is designed to have a familiar socket-style API.  

It is easy to use. Simply reference the ØMQ library, and you can happily send messages between your applications.

It's fast (see the following post Message Queue Shootout!).  



It is available in many languages (bindings) in C++, C#, Clojure, CL, Delphi, Erlang, F#, Felix,  Go, Haskell, Haxe, Java, Lua, Node.js, Objective-C, Perl, PHP, Python, Q, Racket, Ruby, Scala, Tcl, Ada, Basic, ooc.  But written in C++.

It is brokerless i.e. ØMQ does not require any server process. In effect, your application endpoints play the server role. This makes deployment simpler, but there are no obvious place to look at when things go wrong.  A simple example of this problem is to kill the server example in the "Hello World" below while the client is running. The client will hang forever (... I only waited a few minutes...) even when the server is restarted.

It is not part of the Advanced Message Queuing Protocol (AMQP) group of Message Brokers like RabbitMQ or ActiveMQ, and in a lots of ways is a different beast from those "traditional" messaging systems.  IMO, only Kafka can be considered similar at least in terms of performance but even then the comparison is skewed as ØMQ has no guarantee of delivery (non-durable queues).


Ubuntu Installation

There is a PPA available on the web (https://launchpad.net/~chris-lea/+archive/zeromq) for 12.04 (Precise):
deb http://ppa.launchpad.net/chris-lea/zeromq/ubuntu precise main 
deb-src http://ppa.launchpad.net/chris-lea/zeromq/ubuntu precise main 

Which I did not try since I used the tar ball available on the ØMQ download page.  

To grab the release, in this case 3.2.2:

    wget http://download.zeromq.org/zeromq-3.2.2.tar.gz
    tar -zxf zeromq-3.2.2.tar.gz
    cd zeromq-3.2.2

The ØMQ build instructions informs you that the following dependencies are required libtoolautoconfautomake as well as uuid-dev, and of course build-essential.

    sudo apt-get install libtool autoconf automake uuid-dev build-essential

Build and install:

    ./configure
    make
   # To install system wide
   sudo make install
   # Run ldconfig to create teh necessary links
   sudo ldconfig

To see all configuration options, run ./configure --help. Read INSTALL for more details.

A "Hello World" example

This is well documented on the ØMQ guide. Using the C example, first, the client.c file (from the ØMQ guide):

// Hello World client
#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main (void)
{
printf ("Connecting to hello world server…\n");
void *context = zmq_ctx_new ();
void *requester = zmq_socket (context, ZMQ_REQ);
zmq_connect (requester, "tcp://localhost:5555");
int request_nbr;
for (request_nbr = 0; request_nbr != 10; request_nbr++) {
char buffer [10];
printf ("Sending Hello %d…\n", request_nbr);
zmq_send (requester, "Hello"50);
zmq_recv (requester, buffer, 100);
printf ("Received World %d\n", request_nbr);
}
zmq_close (requester);
zmq_ctx_destroy (context);
return 0;
}

A slightly modified server.c file that indicates the ØMQ version at startup:

// Hello World server
#include <zmq.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
int main (void)
{
    int major, minor, patch;
zmq_version (&major, &minor, &patch);
printf ("Current 0MQ version is %d.%d.%d\n", major, minor, patch);

// Socket to talk to clients
void *context = zmq_ctx_new ();
void *responder = zmq_socket (context, ZMQ_REP);
int rc = zmq_bind (responder, "tcp://*:5555");
assert (rc == 0);

    printf("0MQ server start at %d.", 5555);
while (1) {
char buffer [10];
zmq_recv (responder, buffer, 100);
printf ("Received Hello\n");
zmq_send (responder, "World"50);
sleep (1); // Do some 'work'
}
return 0;
} 

The only thing to remember when compiling is to specify the linked library (g++/gcc linking refresher) when compiling:
  
    g++ -0 client client.c -lzmq
    g++ -0 server server.c -lzmq

Start the server, then the client:

    ./server
    ./client

The client will send 10 "Hello"s to the server that will reply with "World".

That is it.

More info: http://www.zeromq.org/. Now, read the guide

Some interesting links: 

Wednesday, March 20, 2013

Installing Ganglia 3.x on Ubuntu 12.04.1

While Ganglia is a well known monitoring solution, it was difficult to find and regroup information for a successful and clean install on a 12.04.1 Ubuntu cluster of 30 nodes.  In particular, linking the UI and Apache was a bit hackish until I found the symbolic link trick (ie the alias).

What is Ganglia?


Ganglia is BSD-licensed open-source project implementing a scalable distributed monitoring system for high-performance computing systems such as clusters and Grids. It leverages widely used technologies such as XML for data representation, XDR for compact, portable data transport, and RRD tool for data storage and visualization. It has very low per-node overheads and high concurrency. The implementation is robust, has been ported to an extensive set of operating systems and processor architectures, and is currently in use on thousands of clusters around the world.

Overview/Concepts


Major components

There are 3 main parts to Ganglia: The nodes generating the statistics, the node(s) collecting the statistics, and a web front-end for displaying them.

  • gmond: A process running on the monitored nodes. For Ubuntu, this is installed with the ganglia-monitor package:
sudo apt-get install ganglia-monitor
        Configuration in /etc/gmond.conf, and associated service is ganglia-monitor.
  • gmetad: A process running on one or multiple machines that collects the statistics sent by the various gmond processes in the associated grid. For Ubuntu, this is the package ganglia-webfrontend package:
         sudo apt-get install ganglia-webfrontend
        Configuration in /etc/gmetad.conf, and associated service is gmetad.
  • A web UI: The web front end is installed/contained within the same package as gmetad. The UI is used to display the collected data. 
One of the tricky things about Ganglia is how it connects to itself.  Any gmond processes sends its collected information towards a gmetad.  Generally, the  collector node(s) is both a node that will generate statistics and a collection point. Such a node will run the the same daemon gmond but will be tweaked to also run the gmetad daemon. In turn, the gmetad daemon provides data to the web front end.

On a multi-nodes deployment, it is possible to verify (or test) the gmond process and to receive an XML dump:
telnet localhost 8649
Note: The above example uses the default port.  This port can be changed in /etc/gmond.conf.

Installation

On each Ubuntu nodes used to collect statistics:
# Install service ganglia-monitor -> gmond
sudo apt-get install ganglia-monitor 

For the Ubuntu node that collects data and that is used to run the web UI:
# Install ganglia frontend + gmetad
sudo apt-get install ganglia-webfrontend

Note that the above is not sufficient for ganglia to be accessible via HTTP.  The Ganglia UI must be deployed within a web application server (e.g. Apache tomcat) to be accessible.  

Note:  Apache tomcat is installed as a dependency when the ganglia-frontend package is installed. It it also possible to install it separately by entering the following command:
sudo apt-get install apache2
In order to deploy and run Ganglia in Apache tomcat, it is required to copy the apache.conf file from /etc/ganglia-webfrontend/apache.conf to /etc/apache2/sites-enabled/:
sudo cp /etc/ganglia-webfrontend/apache.conf /etc/apache2/sites-enabled/ganglia.conf
Note: The file is renamed to clarify what it is used for.

The /etc/ganglia-webfrontend/apache.conf contains a simple alias for /ganglia towards /sur/share/ganglia-webfrontend.

In my opinion, it is simpler and cleaner to create a symbolic link from etc/ganglia-webfrontend/apache.conf to /etc/apache2/sites-enabled/ such as:
cd /etc/apache2/sites-enabled
sudo ln -s /etc/ganglia-webfrontend/apache.conf ganglia.conf
sudo service apache2 stop
sudo service apache2 start

With the above, and the Apache tomcat server running, the Ganglia UI is available at: <host ip>/ganglia.

Stop/start

Uing Ubuntu services:
sudo service gmetad start
sudo service ganglia-monitor start

Monitoring hadoop 1.0.4

Ganglia can be used to monitor a Hadoop cluster.

In file  $HADOOP_HOME/conf/hadoop-metrics2.properties, enable the various sink properties referring to ganglia (remove '#'). Near the end of the file, when specifying the addresses to sink to, use the same address as the mcast_join value found in /etc/gmond.conf, i.e if using multicast:

namenode.sink.ganglia.servers=239.2.11.71:8649
datanode.sink.ganglia.servers=239.2.11.71:8649
tasktracker.sink.ganglia.servers=239.2.11.71:8649
...

Monitoring HBase 0.94.5

Ganglia can also be used to monitor an HBase cluster.

In the file $HBASE_HOME/conf/hadoop-metrics.properties, enable the various configuration options for ganglia.

In the example below, ganglia 3.1.7 is used, and ganglia collects data using multicast (mcast_join value set to =239.2.11.71):

    hbase.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
  hbase.period=10
  hbase.servers=239.2.11.71:8649
  jvm.class=org.apache.hadoop.metrics.ganglia.GangliaContext31
  jvm.period=10
  jvm.servers=239.2.11.71:8649

References