Definición de HBase
- NoSQL (Not Only SQL)
- Es la implementación de código abierto de BigTable de Google
- Podemos definir HBase como un HashMap (pares clave-valor) persistente, distribuido, multidimensional (es decir, podemos tener valores que a su vez sean HashMaps -mapa de mapas-) y ordenado (a nivel de claves)
- Comparándolo con Java, podríamos decir que sería algo bastante parecido a esto:HashMap<String, HashMap<String, Valor>>, pero adicionalmente las claves estarían ordenadas para tener datos posiblemente relacionados "cerca".
Palabras clave
Para referirnos a los distintos niveles de anidación, usaremos un ejemplo relacionado con la temática del blog:
"carrera
memorial lolete" :
{
"papidal"
:
{
"tiempo"
: "42:00:00",
"distancia"
: "8000",
}
;
Familia de columna: papidal (2º nivel)
Columnas de “papidal”: tiempo y distancia (3º nivel)
Clasificación (qualifier): tiempo, distancia
Si queremos consultar el tiempo de papidal, sería algo de este estilo: “papidal:tiempo”
Instalando y configurando HBase en Ubuntu
- Descargamos hbase-0.94.11-security.tar.gz desde http://apache.rediris.es/hbase/stable/
- cd /home/hduser
- sudo tar -zxf /home/hduser/hbase-0.94.11-security.tar.gz
- sudo chown -R hduser:hadoop hbase-0.94.11-security/
- sudo ln -s hbase-0.94.11-security hbase
- sudo chown -R hduser:hadoop hbase
- Editar conf/hbase-env.sh, para usar la versión de Java deseada, en mi caso, le pongo la misma que había utilizado con hadoop (export JAVA_HOME=/usr/lib/jvm/java-6-sun/)
- start-hbase.sh
- Consultar el log hbase-hduser-master-ubuntu.out, si os encontráis un error del estilo "org.apache.hadoop.hbase.client.RetriesExhaustedException: Failed setting up proxy interface org.apache.hadoop.hbase.ipc.HRegionInterface to localhost/127.0.0.1"
- Vais a etc/hosts y editais el fichero. Típicamente será sustituir el 127.0.1.1 por 127.0.0.1, tanto localhost (que generalmente ya estará correcto) como la ip asociada al nombre de la máquina que uséis (que generalmente tendréis que cambiar por 127.0.0.1)
- Volvéis a lanzar "start-hbase.sh" para levantar el servicio y hbase shell (si queréis) para hacer pruebecillas con los comandos list, scan, ...
- También se recomienda editar la configuración del directorio raíz en hbase-site.xml:
<configuration> <property> <name>hbase.rootdir</name> <value>file:///home/hduser/hbase</value> </property> </configuration>
Integrando HBase y Java
Necesitaremos añadir a nuestro proyecto el jar hbase-0.94.11-security.jar que está en el directorio de hbase.
Además, también nos harán falta unos pocos jars más que encontraremos en la carpeta lib, como el de zookeeper, slf4j, protobuf y alguno más (por el error que nos vaya indicando lo vamos añadiendo al classpath).
Una vez hecho esto, podéis partir de esta clase como base para hacer vuestras pruebas:
Una vez hecho esto, podéis partir de esta clase como base para hacer vuestras pruebas:
package papidal.hbase; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.MasterNotRunningException; import org.apache.hadoop.hbase.ZooKeeperConnectionException; import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.util.Bytes; public class HBaseTest { private static Configuration conf = null; static { conf = HBaseConfiguration.create(); } public static void createTable(String tableName, String[] familys) throws Exception { HBaseAdmin admin = new HBaseAdmin(conf); if (admin.tableExists(tableName)) { System.out.println("La tabla todavía existe!"); } else { HTableDescriptor tableDesc = new HTableDescriptor(tableName); for (int i = 0; i < familys.length; i++) { tableDesc.addFamily(new HColumnDescriptor(familys[i])); } admin.createTable(tableDesc); System.out.println("Creada tabla " + tableName); } } public static void deleteTable(String tableName) throws Exception { try { HBaseAdmin admin = new HBaseAdmin(conf); admin.disableTable(tableName); admin.deleteTable(tableName); System.out.println("Eliminada tabla " + tableName); } catch (MasterNotRunningException e) { e.printStackTrace(); } catch (ZooKeeperConnectionException e) { e.printStackTrace(); } } public static void addRecord(String tableName, String rowKey, String family, String qualifier, String value) throws Exception { try { HTable table = new HTable(conf, tableName); Put put = new Put(Bytes.toBytes(rowKey)); put.add(Bytes.toBytes(family), Bytes.toBytes(qualifier), Bytes .toBytes(value)); table.put(put); System.out.println("Insertado registro " + rowKey + " en la tabla " + tableName); } catch (IOException e) { e.printStackTrace(); } } public static void deleteRecord(String tableName, String rowKey) throws IOException { HTable table = new HTable(conf, tableName); List<Delete> list = new ArrayList<Delete>(); Delete del = new Delete(rowKey.getBytes()); list.add(del); table.delete(list); System.out.println("Eliminado registro " + rowKey + " de la tabla "+tableName); } public static void getOneRecord (String tableName, String rowKey) throws IOException{ HTable table = new HTable(conf, tableName); Get get = new Get(rowKey.getBytes()); Result rs = table.get(get); for(KeyValue kv : rs.raw()){ System.out.print(new String(kv.getRow()) + " " ); System.out.print(new String(kv.getFamily()) + ":" ); System.out.print(new String(kv.getQualifier()) + " " ); //System.out.print(kv.getTimestamp() + " " ); System.out.println(new String(kv.getValue())); } } public static void getAllRecord (String tableName) { try{ HTable table = new HTable(conf, tableName); Scan s = new Scan(); ResultScanner ss = table.getScanner(s); for(Result r:ss){ for(KeyValue kv : r.raw()){ System.out.print(new String(kv.getRow()) + " "); System.out.print(new String(kv.getFamily()) + ":"); System.out.print(new String(kv.getQualifier()) + " "); //System.out.print(kv.getTimestamp() + " "); System.out.println(new String(kv.getValue())); } } } catch (IOException e){ e.printStackTrace(); } } public static void main(String[] agrs) { try { String tablename = "corredor"; String[] familys = { "carrera", "localidad"}; HBaseTest.createTable(tablename, familys); // registro identificado por segundo parámetro HBaseTest.addRecord(tablename, "papidal", "carrera", "memorial lolete", "43:00:00"); HBaseTest.addRecord(tablename, "papidal", "localidad", "", "Ferrol"); HBaseTest.addRecord(tablename, "papidal", "carrera", "ruta naval", "54:00:00"); HBaseTest.addRecord(tablename, "juan", "carrera", "ruta naval", "30:00:00"); HBaseTest.addRecord(tablename, "juan", "localidad", "", "Foz"); System.out.println("===========Consultar datos papidal========"); HBaseTest.getOneRecord(tablename, "papidal"); System.out.println("===========Mostrar todos los registros========"); HBaseTest.getAllRecord(tablename); System.out.println("===========Eliminar un registro y mostrar resultado========"); HBaseTest.deleteRecord(tablename, "juan"); HBaseTest.getAllRecord(tablename); } catch (Exception e) { e.printStackTrace(); } } }