Hadoop教程

客户端

和HBase集群进行交互,有很多种不同的客户端可供选择。

Java

例13-1.基本的表管理和访问

public class ExampleClient {public static void main(String[] args) throws IOException {Configuration config = HBaseConfiguration.create();// Create tableHBaseAdmin admin = new HBaseAdmin(config);HTableDescriptor htd = new HTableDescriptor("test");HColumnDescriptor hcd = new HColumnDescriptor("data");htd•addFamily(hcd);admin,createTable(htd);byte [] tablename = htd.getName();HTableDescriptor [] tables = admin.listTables();if (tables.length != 1 && Bytes.equals(tablename, tables[0].getName())) { throw new IOException("Failed create of table");}// Run some operations --a put, a get, and a scan --against the table. HTable table = new HTable(config, tablename); byte [] rowl = Bytes.toBytes("rowl");Put pl = new Put(rowl);byte [] databytes = Bytes.toBytes(” data” );pl.add(databytes, Bytes.toBytes("l"), Bytes.toBytes("valuel")); table.put(pl);Get g = new Get(rowl);Result result = table.get(g);System.out.println("Get: " + result);Scan scan = new Scan();ResultScanner scanner = table.getScanner(scan); try {for (Result scannerResult: scanner) {}} finally { scanner.close();}// Drop the tableadmin.disableTable(tablename);admin.deleteTable(tablename);}}

这个类只有一个主方法。为了简洁,我们没有给出导入包的信息。在这个类中,我 们首先创建一个 org.apache.hadoop.conf.Configuration 实例。我们让 org.apache.hadoop.hbase.HBaseConfiguration 类来创建这个实例。这个类 会返回一个读入了程序 classpath 下 hbase-site.xml 和 hbase-default.xml 文 件中HBase配置信息的Configuration。这个Configuration接下来会被用于 创建 HBaseAdmin 和 HTable 实例。HBaseAdmin 和 HTable 这两个类在 Java 的 org.apache.hadoop.hbase.client 包中。HBaseAdmin 用于管理 HBase 集群, 添加和丢弃表。HTable则用于访问指定的表。Configuration实例指向了执行这 些代码的集群上的这些类。

要创建一个表,我们需要首先创建一个HBaseAdmin的实例,然后让它来创建名为 test、只有一个列族data的表。在我们的示例中,表的模式是默认的。可以是用 org.apache.hadoop.hbase.HTableDescripttor 和 org.apache.hadoop. hbase.HColumnDescriptor中的方法来修改表的模式。接下来的代码测试了表是 否真的创建了。接着,程序对新建的表进行操作。

要对一个表进行操作,我们需要新建一个org.apache.hadoop.hbase.client.HTable 的实例,并把我们的Configuration实例和我们要操作的表的名称传递给它。在 新建 HTable 以后,我们新建一个 org.apache.hadoop.hbase.client 的实例。 我们使用Put把单个的单元格值valuel放入名为rowl的行的名为data:1的列上。列名通过两部分指定;列族名是字节类型的 在前面代码中是databytes 而接着列族修饰词用Bytes.toBytes( “1”)。接着,我们新建一个 org.apache.hadoop.hbase.client.Get来获取刚添加的单元格。然后,再使用 一个org.apache.hadoop.hbase.client.Scan来扫描新建的表,并打印扫描结果。

最后,我们首先禁用表,接着删除它。这样一来,便把表清空了。在丢弃表前必须先禁 用它。

MapReduce

org.apache.hadoop.hbase.mapreduce包中的类和工具有利于将HBase作为 MapReduce作业的源/输出。TableInputFormat类可以在区域的边界进行分割,使map能够拿到单个的区域进行处理。TAbleOutputFormat将把reduce的结果写 入HBase。例13-2中的RowCounter类可以在HBase的mapreduce包中找到。它 用TableInputFormat来运行一个map任务,以计算行数。

例13-2. —个计算HBase表中行数的MapReduce应用程序

public class RowCounter {/** Name of this 'program'. */static final String NAME = "nowcounten";static class RowCountenMappenextends TableMappen
 
   {/** Counter enumeration to count the actual nows. */ public static enum Counters {ROWS}@Overridepublic void map(ImmutableBytesWnitable row, Result values.Context context) throws IOException {for (KeyValue value: values.list()) { if (valuG.gGtValue().length > 0) {context.getCounten(Countens.ROWS).incnement(1); break;public static 3ob cneateSubmittable3ob(Configunation conf, Stning[] angs) throws IOException {String tableName = angs[0];3ob job = new Opb(conf, NAME ”_” + tableName); job.set3arByClass(RowCounter.class);// Columns are space delimited StringBuilder sb = new StringBuilder(); final int columnoffset = 1;for (int i = columnoffset; i < angs.length; i++) { if (i > columnoffset) { sb.append(” ” );}sb.append(args[i]);}Scan scan = new Scan();scan.setFilten(new FinstKeyOnlyFilten()); if (sb.length() > 0) {for (String columnName :sb.toStning().split(" ” )) {String [] fields = columnName.split(" :” ); if(fields.length == 1) {scan.addFamily(Bytes.toBytes(fields[0]));} else {scan.addColumn(Bytes.toBytes(fields[0]), Bytes.toBytes(fields[l]));// Second argument is the table name.job.setOutputFonmatClass(NullOutputFonmat.class);TableMapReduceUtil.initTableMapperDob(tabXeName, scan,RowCountenMappen.class, ImmutableBytesWritable.class, Result.class, job);job.setNumReduceTasks(0); return job;}Configuration conf = HBaseConfiguration.create();String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs(); if (otherArgs.length < 1) {System.err.println(” ERROR: Wrong'number of parameters: ” + args.length); System.err.println(w Usage: RowCounter <tablename >[<columnl > <column2 >...]’’ ); System.exit(-1);}Job job = createSubmittableDob(conf, otherArgs); System.exit(job.waitForCompletion(true) ? 0 : 1); } }
 

这个类使用了辅助类GenericOptionParser,Tool和ToolRunner”小节介 绍的GenericOptionParser,用于解析命令行参数。内部类RowCounterMapper 实现了 HBase 的 TableMapper 抽象。后者是 org.apache.hadoop.mapreduce. Mapper 的“特化” (specialization)。它设定 map 的输入类型由 TableInputFormat 来传递。


Avro、REST和Thrift

HBase提供了 Avro, REST和Thrift接口。在使用Java以外的编程语言和HBase 交互时,会用到这些接口。在所有情况下,Java服务器上都运行着一个HBase客 户端实例。它负责协调Avro、REST和Thrift请求和HBase集群间的双向交互。由 于需要代理这些请求和响应工作,因此使用这些接口比直接使用Java客户端 更慢。

REST

如果要启动一个stargate实例(stargate是HBaseREST服务的名称),可以运行下面 的命令:

% hbase-daemon.sh start rest

这将启动一个服务器实例,默认情况下使用端口号8080,在后台运行,并捕捉 HBase logs目录下日志文件中服务器的任何动静。

客户端可以要求响应以JSON格式、Google的protobuf格式或XML格式输出。采 用哪种格式取决于客户端的HTTP Accept头的设置:

% hbase-daemon.sh stop rest

Thrift

同样,可以运行以下命令启动运行Thrift客户端的服务器,从而启动Thrift服务:

 %hbase-daemon.sh start thrift

这将启动一个在后台运行的服务器实例,默认端口号为9090,捕捉HBase logs目 录下日志文件中的服务器的任何动静。HBase Thrift文档记录了用于生成类的Thrift版本。HBase Thrift IDL可以在HBase源代码的src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thift 中找到。

要终止Thrift服务器,键入以下命令即可:

% hbase-daemon.sh stop thrift

Avro

Avro服务器的启动和终止与启动和终止丁Thrift或REST服务方式相同。Avro服务 器在默认情况下使用端口号9090。

关注微信获取最新动态