Using HBase From Groovy

The normal HBase Java API may be used directly in Groovy. This page describes a 'builder' class to make some HBase methods more convenient. Namely, table structure manipulation is done in a heirarchical fashion similar to DDL, and scanners and batch updates are performed in a closure scope to ease iteration and resource clean-up.

Note that this is not part of the 'official' HBase API, but a community contribution. It is a single class that should be easy enough to include in your own project source. The code is released under the ASF 2.0 license. To get support or submit enhancements to this code, please email the HBase mailing lists.

The code may be downloaded from Github.

Examples

Creating or modifying a table:

   1 /* Create:  this will create a table if it does not exist, or disable
   2    & update column families if the table already does exist.  The table 
   3    will be enabled when the create statement returns */
   4 
   5 def hbase = HBaseBuilder.connect()
   6 
   7 hbase.create( 'myTable' ) {
   8  family( 'familyOne' ) {
   9    inMemory = true
  10    bloomFilter = false
  11  }
  12  // create second family w/ the default options:
  13  family 'familyTwo'
  14 }

Inserting or updating rows:

   1 // Insert or update rows:
   2 hbase.update( 'myTable' ) {
   3  row( 'rowOne' ) {
   4    family( 'familyOne' ) {
   5      col 'one', 'someValue'
   6      col 'two', 'anotherValue'
   7      col 'three', 1234
   8      // note that doubles aren't supported as of HBase v0.18, but will be 'soon'
   9    }
  10    // alternate form that doesn't use nested family name:
  11    col 'familyOne:four', 12345
  12  }
  13  row( 'rowTwo' ) { /* more column values */ }
  14  // etc
  15  // TODO - row method that accepts rowKey & map of column name/ values
  16 }

Scanning:

   1 hbase.tableName = 'myTable' // set a default table name
   2 
   3 /* Scan a table, passing each RowResult to the given closure.  Since RowResult 
   4    implements SortedMap, all of Groovy's Map operations are available here (like
   5    each, [], etc.  But keep in mind the values are byte arrays if accessed in this
   6    fashion.  So as a convenience, the RowResult has some methods added to it - 
   7    getString, getInt, getLong, and getDate */
   8 
   9 hbase.scan( cols : ['fam1:col1', 'fam2:*'],
  10            // all other named params are optional:
  11            start : '001', end : '200',
  12            // any timestamp args may be long, Date or Calendar
  13            timestamp : Date.parse( 'yy/mm/dd HH:MM:ss', '08/11/25 05:00:00' )
  14            ) { row ->
  15 
  16   println "${row.key} : ${row.getString('fam1:col1')}" 
  17 }

A More Realistic Example

Say you wanted to do batch loading of data from CSV files and insert the data to HBase. The code could be written as a Groovy script that looks like this:

   1 hbase.update( 'myTable' ) {
   2   new File( 'someFile.csv' ).eachLine { line ->
   3     def values = line.split(',')
   4     row( values[0] ) {
   5       col 'fam1:val1', values[1]
   6       col 'fam1:val2', values[2]
   7     }
   8   }
   9 }

Changelog

Hbase/Groovy (last edited 2009-09-20 23:54:37 by localhost)