Here at Sematext we really like performance metrics and we like HBase. We like them so much we’ve created a service for HBase Performance Monitoring (and for Solr, too). In the process we’ve done some experiments with Hadoop and HBase around performance monitoring and are sharing our experience and some relevant code in this post.
The Hadoop metrics framework is simple to extend and customise. For example, you can very easily write a custom MetricsContext which sends metrics to your own storage solution.
All you need to do is extend the AbstractMetricsContext class and implement
protected void emitRecord(String context, String record, OutputRecord outputrecord) throws IOException;
To demonstrate, I wrote HBaseMetricsContext which stores Hadoop metrics in HBase. Since HBase itself uses the Hadoop metrics framework, you can use it to store its own metrics inside itself. Useful? Maybe. This is just an example after all.
If you’d like to try it out, get the source from GitHub. Then build the project using:
mvn package
Put the resulting Jar file in the HBase lib directory.
You will need to create a table with the relevant column families. We assume the column families are a composite of:
columnFamily = contextName + "." + recordName
In the HBase shell create your table:
create 'metrics', 'hbase.master', 'hbase.regionserver'
Edit your hadoop-metrics.properties file to include:
hbase.class=com.sematext.hadoop.metrics.HBaseMetricsContext hbase.tableName=metrics hbase.period=10
Restart HBase and it will start inserting to the metrics table every 10 seconds.
The row key of each record is made up of the timestamp and the tags (for disambiguation) like so:
rowKey = bytes(maxlong - timestamp) + bytes(tagName) + bytes(tagValue) + …
Subtracting the timestamp from maxlong ensures the scans get the most recent record first.
Each tag and metric is stored in it’s own column. This gives us a table that looks something like this:
hbase.master | hbase.regionserver | ||||
---|---|---|---|---|---|
cluster_requests | hostName | hostName | flushQueueSize | regions | |
rowKey2 | rs1.example.org | 0 | 1 | ||
rowKey1 | 101 | master.example.org |
For clarity timestamps are not included in the above table, as each cell is timestamped. All cells for a record will have the same timestamp.