一、HBase协处理器实战 大纲: 协处理器介绍 协处理器的分类 演示endpoint对表中某个列进行计数服务端编写 1.1 协处理器介绍 定义:HBase可以让用户的部分逻辑在数据存放端及hbase服务端进行计算的机制(框架)。协处理器允许用户在hbase服务端上运行自己的代码。 HBase作为列数据库最经常被人诟病的特性包括:无法轻易建立“二级索引”,难以执行求和、计数、排序等操作。 比如,在旧版本(<0.92)的Hbase中,统计数据表的总行数,需要使用Counter方法,执行一次MapReduce Job才能得到。 虽然HBase在数据存储层中集成了MapReduce,能够有效用于数据表的分布式计算。然而在很多情况下,做一些简单的相加或者聚合计算的时候,如果直接将计算过程放置在server端,能够减少通讯开销,从而获得很好的性能提升。于是, HBase在0.92之后引入了协处理器(coprocessors)。 协处理器实现了一些激动人心的新特性:能够轻易建立二次索引、复杂过滤器(谓词下推)以及访问控制等。 HBase协处理器的灵感来自于Jeff Dean 09年的演讲。它根据该演讲实现了类似于bigtable的协处理器,包括以下特性: 每个表服务器的任意子表都可以运行代码。 客户端的高层调用接口 (客户端能够直接访问数据表的行地址,多行读写会自动分片成多个并行的RPC调用)。 提供一个非常灵活的、可用于建立分布式服务的数据模型。 能够自动化扩展、负载均衡、应用请求路由。 HBase的协处理器灵感来自 bigtable,但是实现细节不尽相同。 HBase建立了一个框架,它为用户提供类库和运行时环境,使得他们的代码能够在HBase region server和master上处理。 1.2 协处理器的分类 分类:协处理器框架为了更好支持其行为的灵活性,提供了两个不同方面的插件。 一个是观察者(observer),类似于关系数据库的触发器。 另一个是终端(endpoint),动态的终端有点像存储过程。 1.2.1 Observer 分为RegionObserver、RegionServerObserver、MasterObserver、WalObserver。 观察者的设计意图是允许用户通过插入代码来重载协处理器框架的upcall方法,而具体的事件触发的callback方法由HBase的核心代码来执行。 协处理器框架处理所有的callback调用细节,协处理器自身只需要插入添加或者改变的功能。 以HBase0.92版本为例,它提供了三种观察者接口: RegionObserver:提供客户端的数据操纵事件钩子: Get、 Put、 Delete、Scan等。 WALObserver:提供WAL相关操作钩子。 MasterObserver:提供DDL-类型的操作钩子。如创建、删除、修改数据表等。 这些接口可以同时使用在同一个地方,按照不同优先级顺序执行。用户可以任意基于协处理器实现复杂的HBase功能层。 HBase有很多种事件可以触发观察者方法,这些事件与方法从HBase0.92版本起,都会集成在HBase API中。不过这些API可能会由于各种原因有所改动,不同版本的接口改动比较大。 RegionObserver工作原理: 1.2.2 EndPoint 终端是动态RPC插件的接口,它的实现代码被安装在服务器端,从而能够通过HBase RPC唤醒。客户端类库提供了非常方便的方法来调用这些动态接口,它们可以在任意时候调用一个终端,它们的实现代码会被目标region远程执行,结果会返回到终端。用户可以结合使用这些强大的插件接口,为HBase添加全新的特性。 终端的使用如下面流程所示: 定义一个新的protocol接口,必须继承CoprocessorProtocol。 实现终端接口,该实现会被导入region环境执行。 继承抽象类BaseEndpointCoprocessor。 在客户端,终端可以被两个新的HBase Client API调用。 单个region: HTableInterface.coprocessorProxy(Class<T> protocol, byte[] row) regions区域: HTableInterface.coprocessorExec(Class<T> protocol, byte[] startKey, byte[] endKey, Batch.Call<T,R> callable) 整体的EndPoint调用过程范例,如图所示: 官方给的示例程序大体流程: 对Endpoint进行设置的三个方法: A. 启动全局aggregation,能过操纵所有的表上的数据。通过修改hbase-site.xml这个文件来实现,只需要添加如下代码: <property> <name>hbase.coprocessor.user.region.classes</name> <value> org.apache.hadoop.hbase.coprocessor.RowCountEndpoint </value> </property> B. 启用表aggregation,只对特定的表生效。通过HBase Shell 来实现。 (1)disable指定表。 hbase> disable 'mytable' (2)添加aggregation 。 hbase> alter 'mytable','coprocessor'=>'|org.apache.hadoop.hbase.coprocessor.example.RowCountEndpoint ||' (3)重启指定表 。 hbase> enable 'mytable' C. API调用 HTableDescriptor htd=new HTableDescriptor("testTable"); htd.setValue("CORPROCESSOR$1" , path.toString+"|"+RowCountEndpoint.class.getCanonicalName()+"|"+Coprocessor.Priority.USER); 其中path为jar在HDFS中的路径。 Demo1: package Coprocessor; import java.io.IOException; import java.util.Iterator; import java.util.Map; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.HConnection; import org.apache.hadoop.hbase.client.HConnectionManager; import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.coprocessor.example.generated.ExampleProtos; import org.apache.hadoop.hbase.ipc.BlockingRpcCallback; import org.apache.hadoop.hbase.ipc.ServerRpcController; import com.google.protobuf.ServiceException; public class CoprocessorRowCounter { private String rootDir; private String zkServer; private String port; private Configuration conf; private HConnection hConn = null; private CoprocessorRowCounter(String rootDir,String zkServer,String port) throws IOException{ this.rootDir = rootDir; this.zkServer = zkServer; this.port = port; conf = HBaseConfiguration.create(); conf.set("hbase.rootdir", rootDir); conf.set("hbase.zookeeper.quorum", zkServer); conf.set("hbase.zookeeper.property.clientPort", port); hConn = HConnectionManager.createConnection(conf); } public static void main(String[] args) throws ServiceException, Throwable { String rootDir = "hdfs://hadoop1:8020/hbase"; String zkServer = "hadoop1"; String port = "2181"; CoprocessorRowCounter conn = new CoprocessorRowCounter(rootDir,zkServer,port); //Configuration conf = HBaseConfiguration.create(); HTable table = new HTable(conn.conf, "students"); //发送请求 final ExampleProtos.CountRequest request = ExampleProtos.CountRequest.getDefaultInstance(); //回调函数 call方法 Map<byte[],Long> results = table.coprocessorService(ExampleProtos.RowCountService.class, null, null, new Batch.Call<ExampleProtos.RowCountService,Long>() { public Long call(ExampleProtos.RowCountService counter) throws IOException { ServerRpcController controller = new ServerRpcController(); BlockingRpcCallback<ExampleProtos.CountResponse> rpcCallback = new BlockingRpcCallback<ExampleProtos.CountResponse>(); //实现在server端 counter.getRowCount(controller, request, rpcCallback); ExampleProtos.CountResponse response = rpcCallback.get(); if (controller.failedOnException()) { throw controller.getFailedOn(); } //返回 return (response != null && response.hasCount()) ? response.getCount() : 0; } }); int sum = 0; int count = 0; /* Iterator<Long> iter = results.values().iterator(); Long val = iter.next();*/ for (Long l : results.values()) { sum += l; count++; } System.out.println("row count = " + sum); System.out.println("region count = " + count); } } 运行结果: row count = 4 region count = 1 注意: 协处理器配置的加载顺序:先加载配置文件中定义的协处理器,后加载表描述符中的协处理器。 COPROCESSOR$<number>中的number定义了加载的顺序。 协处理器配置格式 移除协处理器 Demo2: package Coprocessor; import java.io.IOException; import java.util.List; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver; import org.apache.hadoop.hbase.coprocessor.ObserverContext; import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; import org.apache.hadoop.hbase.util.Bytes; public class RegionObserver extends BaseRegionObserver{ private static byte[] fixed_rowkey = Bytes.toBytes("Ivy"); //preGetOp代替preGet /*public void preGetOp(ObserverContext<RegionCoprocessorEnvironment> e, Get get, List<Cell> results) throws IOException { if (Bytes.equals(get.getRow(), fixed_rowkey)) { //行键 列族 列 Cell cell = new KeyValue(get.getRow(), Bytes.toBytes("time"), Bytes.toBytes("time")); results.add(cell); } }*/ @Override public void preGet(ObserverContext<RegionCoprocessorEnvironment> c, Get get, List<KeyValue> result) throws IOException { if (Bytes.equals(get.getRow(), fixed_rowkey)) { //行键 列族 列 KeyValue kv = new KeyValue(get.getRow(), Bytes.toBytes("time"), Bytes.toBytes("time"),Bytes.toBytes(System.currentTimeMillis())); result.add(kv); } } } 打成jar包,上传到hdfs上面。 增加协处理器 disable 'students' alter 'students','coprocessor'=>'hdfs://nameservice1/liguodong/coprocessor.jar|Coprocessor.RegionObserver||' enable 'students' package HbaseAPI; import java.io.IOException; 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.Get; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.client.HConnection; import org.apache.hadoop.hbase.client.HConnectionManager; import org.apache.hadoop.hbase.client.HTableInterface; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.io.compress.Compression.Algorithm; import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding; import org.apache.hadoop.hbase.util.Bytes; public class HBaseConnection { private String rootDir; private String zkServer; private String port; private Configuration conf; private HConnection hConn = null; private HBaseConnection(String rootDir,String zkServer,String port) throws IOException{ this.rootDir = rootDir; this.zkServer = zkServer; this.port = port; conf = HBaseConfiguration.create(); conf.set("hbase.rootdir", rootDir); conf.set("hbase.zookeeper.quorum", zkServer); conf.set("hbase.zookeeper.property.clientPort", port); hConn = HConnectionManager.createConnection(conf); } //获取数据 public Result getData(String tableName,String rowkey) throws IOException{ HTableInterface table = hConn.getTable(tableName); //用来获取单个行的相关信息 Get get = new Get(Bytes.toBytes(rowkey)); return table.get(get); } public void format(Result result){ //行键 String rowkey = Bytes.toString(result.getRow()); //Return an cells of a Result as an array of KeyValues KeyValue[] kvs = result.raw(); for (KeyValue kv : kvs) { //列族名 String family = Bytes.toString(kv.getFamily()); //列名 String qualifier = Bytes.toString(kv.getQualifier()); //String value = Bytes.toString(result.getValue(Bytes.toBytes(family), Bytes.toBytes(qualifier))); String value = Bytes.toString(kv.getValue()); System.out.println("rowkey->"+rowkey+", family->" +family+", qualifier->"+qualifier); System.out.println("value->"+value); } } public static void main(String[] args) throws IOException { String rootDir = "hdfs://hadoop1:8020/hbase"; String zkServer = "hadoop1"; String port = "2181"; //初始化 HBaseConnection conn = new HBaseConnection(rootDir,zkServer,port); //输出结果 Result result = conn.getData("students", "Ivy"); conn.format(result); result = conn.getData("students", "Tom"); conn.format(result); } } Loading... <h2>一、HBase协处理器实战</h2> 大纲: 协处理器介绍 协处理器的分类 演示endpoint对表中某个列进行计数服务端编写<!--more--> <h3>1.1 协处理器介绍</h3> 定义:HBase可以让用户的部分逻辑在数据存放端及hbase服务端进行计算的机制(框架)。协处理器允许用户在hbase服务端上运行自己的代码。 HBase作为列数据库最经常被人诟病的特性包括:无法轻易建立“二级索引”,难以执行求和、计数、排序等操作。 比如,在旧版本(<0.92)的Hbase中,统计数据表的总行数,需要使用Counter方法,执行一次MapReduce Job才能得到。 虽然HBase在数据存储层中集成了MapReduce,能够有效用于数据表的分布式计算。然而在很多情况下,做一些简单的相加或者聚合计算的时候,如果直接将计算过程放置在server端,能够减少通讯开销,从而获得很好的性能提升。于是, HBase在0.92之后引入了协处理器(coprocessors)。 协处理器实现了一些激动人心的新特性:能够轻易建立二次索引、复杂过滤器(谓词下推)以及访问控制等。 HBase协处理器的灵感来自于Jeff Dean 09年的演讲。它根据该演讲实现了类似于bigtable的协处理器,包括以下特性: <ol> <li>每个表服务器的任意子表都可以运行代码。</li> <li>客户端的高层调用接口 (客户端能够直接访问数据表的行地址,多行读写会自动分片成多个并行的RPC调用)。</li> <li>提供一个非常灵活的、可用于建立分布式服务的数据模型。</li> <li>能够自动化扩展、负载均衡、应用请求路由。</li> </ol> HBase的协处理器灵感来自 bigtable,但是实现细节不尽相同。 HBase建立了一个框架,它为用户提供类库和运行时环境,使得他们的代码能够在HBase region server和master上处理。 <h3>1.2 协处理器的分类</h3> 分类:协处理器框架为了更好支持其行为的灵活性,提供了两个不同方面的插件。 一个是观察者(observer),类似于关系数据库的触发器。 另一个是终端(endpoint),动态的终端有点像存储过程。 <h4>1.2.1 Observer</h4> 分为RegionObserver、RegionServerObserver、MasterObserver、WalObserver。 观察者的设计意图是允许用户通过插入代码来重载协处理器框架的upcall方法,而具体的事件触发的callback方法由HBase的核心代码来执行。 协处理器框架处理所有的callback调用细节,协处理器自身只需要插入添加或者改变的功能。 以HBase0.92版本为例,它提供了三种观察者接口: RegionObserver:提供客户端的数据操纵事件钩子: Get、 Put、 Delete、Scan等。 WALObserver:提供WAL相关操作钩子。 MasterObserver:提供DDL-类型的操作钩子。如创建、删除、修改数据表等。 这些接口可以同时使用在同一个地方,按照不同优先级顺序执行。用户可以任意基于协处理器实现复杂的HBase功能层。 HBase有很多种事件可以触发观察者方法,这些事件与方法从HBase0.92版本起,都会集成在HBase API中。不过这些API可能会由于各种原因有所改动,不同版本的接口改动比较大。 RegionObserver工作原理: <img class="size-full wp-image-4140 aligncenter" src="http://www.xiaoten.com/usr/uploads/2016/10/1-2.png" alt="1" width="821" height="503" style=""> <h4>1.2.2 EndPoint</h4> 终端是动态RPC插件的接口,它的实现代码被安装在服务器端,从而能够通过HBase RPC唤醒。客户端类库提供了非常方便的方法来调用这些动态接口,它们可以在任意时候调用一个终端,它们的实现代码会被目标region远程执行,结果会返回到终端。用户可以结合使用这些强大的插件接口,为HBase添加全新的特性。 终端的使用如下面流程所示: 定义一个新的protocol接口,必须继承CoprocessorProtocol。 实现终端接口,该实现会被导入region环境执行。 继承抽象类BaseEndpointCoprocessor。 在客户端,终端可以被两个新的HBase Client API调用。 单个region: <code>HTableInterface.coprocessorProxy(Class<T> protocol, byte[] row)</code> regions区域: <code>HTableInterface.coprocessorExec(Class<T> protocol, byte[] startKey, byte[] endKey, Batch.Call<T,R> callable)</code> 整体的EndPoint调用过程范例,如图所示: <img class="size-full wp-image-4141 aligncenter" src="http://www.xiaoten.com/usr/uploads/2016/10/2-2.png" alt="2" width="859" height="442" style=""> 官方给的示例程序大体流程: <img class="size-large wp-image-4142 aligncenter" src="http://www.xiaoten.com/usr/uploads/2016/10/3-2-1024x587.png" alt="3" width="620" height="355" style=""> 对Endpoint进行设置的三个方法: A. 启动全局aggregation,能过操纵所有的表上的数据。通过修改hbase-site.xml这个文件来实现,只需要添加如下代码: <pre class="lang:default decode:true "><property> <name>hbase.coprocessor.user.region.classes</name> <value> org.apache.hadoop.hbase.coprocessor.RowCountEndpoint </value> </property></pre> B. 启用表aggregation,只对特定的表生效。通过HBase Shell 来实现。 (1)disable指定表。 <code>hbase> disable 'mytable'</code> (2)添加aggregation 。 <code>hbase> alter 'mytable','coprocessor'=>'|org.apache.hadoop.hbase.coprocessor.example.RowCountEndpoint ||'</code> (3)重启指定表 。 <code>hbase> enable 'mytable'</code> C. API调用 <pre class="lang:default decode:true ">HTableDescriptor htd=new HTableDescriptor("testTable"); htd.setValue("CORPROCESSOR$1" , path.toString+"|"+RowCountEndpoint.class.getCanonicalName()+"|"+Coprocessor.Priority.USER);</pre> 其中path为jar在HDFS中的路径。 Demo1: <img class="aligncenter wp-image-4143 size-large" src="http://www.xiaoten.com/usr/uploads/2016/10/4-2-1024x393.png" alt="4" width="620" height="238" style=""> <img class="size-large wp-image-4144 aligncenter" src="http://www.xiaoten.com/usr/uploads/2016/10/5-2-1024x296.png" alt="5" width="620" height="179" style=""> <img class="aligncenter wp-image-4145 size-full" src="http://www.xiaoten.com/usr/uploads/2016/10/6-2.png" alt="6" width="903" height="247" style=""> <pre class="lang:default decode:true ">package Coprocessor; import java.io.IOException; import java.util.Iterator; import java.util.Map; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.HConnection; import org.apache.hadoop.hbase.client.HConnectionManager; import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.coprocessor.example.generated.ExampleProtos; import org.apache.hadoop.hbase.ipc.BlockingRpcCallback; import org.apache.hadoop.hbase.ipc.ServerRpcController; import com.google.protobuf.ServiceException; public class CoprocessorRowCounter { private String rootDir; private String zkServer; private String port; private Configuration conf; private HConnection hConn = null; private CoprocessorRowCounter(String rootDir,String zkServer,String port) throws IOException{ this.rootDir = rootDir; this.zkServer = zkServer; this.port = port; conf = HBaseConfiguration.create(); conf.set("hbase.rootdir", rootDir); conf.set("hbase.zookeeper.quorum", zkServer); conf.set("hbase.zookeeper.property.clientPort", port); hConn = HConnectionManager.createConnection(conf); } public static void main(String[] args) throws ServiceException, Throwable { String rootDir = "hdfs://hadoop1:8020/hbase"; String zkServer = "hadoop1"; String port = "2181"; CoprocessorRowCounter conn = new CoprocessorRowCounter(rootDir,zkServer,port); //Configuration conf = HBaseConfiguration.create(); HTable table = new HTable(conn.conf, "students"); //发送请求 final ExampleProtos.CountRequest request = ExampleProtos.CountRequest.getDefaultInstance(); //回调函数 call方法 Map<byte[],Long> results = table.coprocessorService(ExampleProtos.RowCountService.class, null, null, new Batch.Call<ExampleProtos.RowCountService,Long>() { public Long call(ExampleProtos.RowCountService counter) throws IOException { ServerRpcController controller = new ServerRpcController(); BlockingRpcCallback<ExampleProtos.CountResponse> rpcCallback = new BlockingRpcCallback<ExampleProtos.CountResponse>(); //实现在server端 counter.getRowCount(controller, request, rpcCallback); ExampleProtos.CountResponse response = rpcCallback.get(); if (controller.failedOnException()) { throw controller.getFailedOn(); } //返回 return (response != null && response.hasCount()) ? response.getCount() : 0; } }); int sum = 0; int count = 0; /* Iterator<Long> iter = results.values().iterator(); Long val = iter.next();*/ for (Long l : results.values()) { sum += l; count++; } System.out.println("row count = " + sum); System.out.println("region count = " + count); } }</pre> 运行结果: <pre class="lang:default decode:true ">row count = 4 region count = 1</pre> <strong>注意:</strong> <ol> <li>协处理器配置的加载顺序:先加载配置文件中定义的协处理器,后加载表描述符中的协处理器。</li> <li><code>COPROCESSOR$<number></code>中的number定义了加载的顺序。</li> <li>协处理器配置格式</li> </ol> <img class="size-full wp-image-4146 aligncenter" src="http://www.xiaoten.com/usr/uploads/2016/10/7-2.png" alt="7" width="835" height="132" style=""> <img class="size-full wp-image-4147 aligncenter" src="http://www.xiaoten.com/usr/uploads/2016/10/8-2.png" alt="8" width="972" height="442" style=""> <strong>移除协处理器 </strong> <img class="size-full wp-image-4148 aligncenter" src="http://www.xiaoten.com/usr/uploads/2016/10/9-2.png" alt="9" width="830" height="123" style=""> Demo2: <img class="size-full wp-image-4149 aligncenter" src="http://www.xiaoten.com/usr/uploads/2016/10/10-1.png" alt="10" width="1023" height="134" style=""> <pre class="lang:default decode:true ">package Coprocessor; import java.io.IOException; import java.util.List; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver; import org.apache.hadoop.hbase.coprocessor.ObserverContext; import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment; import org.apache.hadoop.hbase.util.Bytes; public class RegionObserver extends BaseRegionObserver{ private static byte[] fixed_rowkey = Bytes.toBytes("Ivy"); //preGetOp代替preGet /*public void preGetOp(ObserverContext<RegionCoprocessorEnvironment> e, Get get, List<Cell> results) throws IOException { if (Bytes.equals(get.getRow(), fixed_rowkey)) { //行键 列族 列 Cell cell = new KeyValue(get.getRow(), Bytes.toBytes("time"), Bytes.toBytes("time")); results.add(cell); } }*/ @Override public void preGet(ObserverContext<RegionCoprocessorEnvironment> c, Get get, List<KeyValue> result) throws IOException { if (Bytes.equals(get.getRow(), fixed_rowkey)) { //行键 列族 列 KeyValue kv = new KeyValue(get.getRow(), Bytes.toBytes("time"), Bytes.toBytes("time"),Bytes.toBytes(System.currentTimeMillis())); result.add(kv); } } }</pre> 打成jar包,上传到hdfs上面。 <img class="size-full wp-image-4150 aligncenter" src="http://www.xiaoten.com/usr/uploads/2016/10/11-1.png" alt="11" width="915" height="107" style=""> 增加协处理器 <pre class="lang:default decode:true ">disable 'students' alter 'students','coprocessor'=>'hdfs://nameservice1/liguodong/coprocessor.jar|Coprocessor.RegionObserver||' enable 'students'</pre> <img class="size-large wp-image-4151 aligncenter" src="http://www.xiaoten.com/usr/uploads/2016/10/12-1-1024x82.png" alt="12" width="620" height="50" style=""> <pre class="lang:default decode:true">package HbaseAPI; import java.io.IOException; 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.Get; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.client.HConnection; import org.apache.hadoop.hbase.client.HConnectionManager; import org.apache.hadoop.hbase.client.HTableInterface; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.io.compress.Compression.Algorithm; import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding; import org.apache.hadoop.hbase.util.Bytes; public class HBaseConnection { private String rootDir; private String zkServer; private String port; private Configuration conf; private HConnection hConn = null; private HBaseConnection(String rootDir,String zkServer,String port) throws IOException{ this.rootDir = rootDir; this.zkServer = zkServer; this.port = port; conf = HBaseConfiguration.create(); conf.set("hbase.rootdir", rootDir); conf.set("hbase.zookeeper.quorum", zkServer); conf.set("hbase.zookeeper.property.clientPort", port); hConn = HConnectionManager.createConnection(conf); } //获取数据 public Result getData(String tableName,String rowkey) throws IOException{ HTableInterface table = hConn.getTable(tableName); //用来获取单个行的相关信息 Get get = new Get(Bytes.toBytes(rowkey)); return table.get(get); } public void format(Result result){ //行键 String rowkey = Bytes.toString(result.getRow()); //Return an cells of a Result as an array of KeyValues KeyValue[] kvs = result.raw(); for (KeyValue kv : kvs) { //列族名 String family = Bytes.toString(kv.getFamily()); //列名 String qualifier = Bytes.toString(kv.getQualifier()); //String value = Bytes.toString(result.getValue(Bytes.toBytes(family), Bytes.toBytes(qualifier))); String value = Bytes.toString(kv.getValue()); System.out.println("rowkey->"+rowkey+", family->" +family+", qualifier->"+qualifier); System.out.println("value->"+value); } } public static void main(String[] args) throws IOException { String rootDir = "hdfs://hadoop1:8020/hbase"; String zkServer = "hadoop1"; String port = "2181"; //初始化 HBaseConnection conn = new HBaseConnection(rootDir,zkServer,port); //输出结果 Result result = conn.getData("students", "Ivy"); conn.format(result); result = conn.getData("students", "Tom"); conn.format(result); } }</pre> © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏
1 条评论
满满的都是干货!