閱讀879 返回首頁    go 阿裏雲 go 技術社區[雲棲]


HBase客戶端API使用

Java API

HBase提供了一套Java API來支持Java程序對HBase數據庫的請求操作,在hbase shell中能夠使用的都可以通過這套API來實現

HBase有兩套API,分別是1.0和2.0,在較新版本的HBase中使用1.0的API時,很多類和方法都被標記為Deprecated,官方表示舊版本的API將會在3.0版本中刪除,所以推薦使用2.0 
本篇中使用的API均為2.0 
2.0官方API文檔

需要導入的jar包

  • com.google.protobuf:rpc通信依賴
  • org.apache.zookeeper:連接zk依賴
  • hbase-client:hbase客戶端
  • hbase-common:hbase組件

使用maven可以簡單方便地管理jar包,pom文件示例如下:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <hbase.version>1.1.2</hbase.version>
    <zookeeper.version>3.4.5</zookeeper.version>
</properties>
<dependencis>
    <!--hadoop/hbase都要依賴(RPC通信)-->
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>2.5.0</version>
    </dependency>
    <!--hbase-->
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>${zookeeper.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-client</artifactId>
        <version>${hbase.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-common</artifactId>
        <version>${hbase.version}</version>
    </dependency>
</dependencis>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

開發流程

HBase API的使用可以歸納為一下幾個步驟:

1.獲得Configuration實例:其中保存了環境和配置信息 
2.在Configuration中設置zk和master的相關信息,如果hbase的配置文件在環境變量中則不需要配置 
3.獲得Connection實例連接到zk 
4.通過Connection實例獲得Admin和Table實例調用其方法進行操作

其中Admin和Table為HBase API中提供的一個統一操作接口,在1.0中對應的是HAdmin和HTable 
Admin對應的是DDL操作 
Table對應的是相關表的DML操作

代碼示例

//1.獲得Configuration實例並進行相關設置
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "localhost:2181");
configuration.set("hbase.master", "localhost:16010");
//2.獲得Connection實例
Connection connection = ConnectionFactory.createConnection(configuration);
//3.1獲得Admin接口
Admin admin = connection.getAdmin();
//3.2獲得Table接口,需要傳入表名
Table table = connection.getTable(tableName)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

為了程序的可維護性和方便調用,這裏將HBase API提供的接口劃分成了三個類

1.HBaseInfo:保存了Configuration和Connection,並進行一些初始化的設置,如zk地址等 
2.HBaseDDLUtil:繼承HBaseInfo,通過父類的Configuration和Connection獲得Admin實例並使用其提供的方式進行DDL操作 
3.HBaseDMLUtil:繼承HBaseInfo,通過父類的Configuration和Connection獲得Table實例並使用其提供的方式進行DML操作

DDL操作

/**
  * 創建表
  * @param tableName 表名
  * @param familyNames 列族名
  * */
 public static void createTable(String tableName, String... familyNames) throws IOException {
     if (admin.tableExists(TableName.valueOf(tableName))) {
         return;
     }
     //通過HTableDescriptor類來描述一個表,HColumnDescriptor描述一個列族
     HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf(tableName));
     for (String familyName : familyNames) {
         tableDescriptor.addFamily(new HColumnDescriptor(familyName));
     }
     admin.createTable(tableDescriptor);
 }

 /**
   * 刪除表
   * @param tableName 表名
   * */
  public static void dropTable(String tableName) throws IOException {
      //刪除之前要將表disable
      if (!admin.isTableDisabled(TableName.valueOf(tableName))) {
          admin.disableTable(TableName.valueOf(tableName));
      }
      admin.deleteTable(TableName.valueOf(tableName));

  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

DML操作

HBase中的CRUD都是通過對應的對象來操作的,例如: 
Put為新增,如果記錄已經存在會用新值覆蓋,相當於修改 
Delete為刪除 
Get為查詢

/**
 * 指定行/列中插入數據
 * @param tableName 表名
 * @param rowKey 主鍵rowkey
 * @param family 列族
 * @param column 列
 * @param value 值
 * TODO: 批量PUT
 */
public static void insert(String tableName, String rowKey, String family, String column, String value) throws IOException {
    table = connection.getTable(TableName.valueOf(tableName));
    Put put = new Put(Bytes.toBytes(rowKey));
    put.addColumn(Bytes.toBytes(family), Bytes.toBytes(column), Bytes.toBytes(value));
    table.put(put);
}


/**
 * 刪除表中的指定行
 * @param tableName 表名
 * @param rowKey rowkey
 * TODO: 批量刪除
 */
public static void delete(String tableName, String rowKey) throws IOException {
    table = connection.getTable(TableName.valueOf(tableName));
    Delete delete = new Delete(Bytes.toBytes(rowKey));
    table.delete(delete);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

篇幅有限,HBase工具類的代碼已上傳至Github 
API文檔中還有許多實用的函數沒有接觸到,希望在實踐中可以操作一下

MapReduceApi

要使用HBase的MapReduce API需要在pom文件中添加以下依賴:

<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-server</artifactId>
    <version>${hbase.version}</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

HBase實現了TableInputFormat和TableOutputFormat用於讀寫HBase表 
TableMapper類和TableReducer類,在使用MapReduce操作HBase的時候可以借助這兩個類從HBase中讀數據和寫數據

TableInputFormat

用於讀取HBase表數據並生成鍵值對 
將數據表按照Region分割成split,既有多少個Regions就有多個splits 
然後將Region按行鍵分成

TableMapper

和普通的Mapper的區別在於 
TableMapper將輸入的

TableReducer

該類將Reducer的輸出類型限製為Mutation,Mutation是HBase中Delete/Put/Get/Append類的父類,也就是說TableReducer將輸出類型限製在這幾個類之中 
自定義的Reducer類繼承TableReducer,指定其輸入的

TableOutputFormat

該類負責將Reducer的輸出數據寫入到HBase中

代碼示例

MyTableMapper

public class MyTableMapper extends TableMapper<ImmutableBytesWritable, ImmutableBytesWritable> {

    ImmutableBytesWritable k = new ImmutableBytesWritable();
    ImmutableBytesWritable v = new ImmutableBytesWritable();

    /**
     * 表中的每行都會調用一次map函數
     * */
    @Override
    protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, InterruptedException {
        //遍曆改行中的結果集
        for (Cell cell : value.rawCells()) {
            //獲得rowkey
            byte[] row = CellUtil.cloneRow(cell);
            //獲得值
            byte[] rowValue = CellUtil.cloneValue(cell);
            k.set(row);
            v.set(rowValue);
            context.write(k, v);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

MyTableReducer

public class MyTableReducer extends TableReducer<ImmutableBytesWritable, ImmutableBytesWritable, ImmutableBytesWritable> {
    @Override
    protected void reduce(ImmutableBytesWritable key, Iterable<ImmutableBytesWritable> values, Context context) throws IOException, InterruptedException {
        for (ImmutableBytesWritable value : values) {
            Put put = new Put(key.get());
            put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("c3"), value.get());
            context.write(key, put);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

驅動程序

public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration configuration = HBaseConfiguration.create();
        //設置讀取的表
        configuration.set(TableInputFormat.INPUT_TABLE, "client");

        Job job = Job.getInstance(configuration, "hbase-mr-api");
        //可以和普通mr程序一樣進行設置
        job.setJarByClass(Driver.class);
        job.setInputFormatClass(TableInputFormat.class);
        job.setMapperClass(MyTableMapper.class);
        job.setMapOutputKeyClass(ImmutableBytesWritable.class);
        job.setMapOutputValueClass(ImmutableBytesWritable.class);
        //也可以使用hbase提供的工具類來設置job
        TableMapReduceUtil.initTableReducerJob("t1", MyTableReducer.class, job);
        job.waitForCompletion(true);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

示例代碼以上傳至Github

關於驅動程序中設置job的方法

在上麵的代碼中可以看到,設置job的方法有兩種:MapReduce常用方式和HBase提供的TableMapReduceUtil工具類

兩種方式的設置效果是相同的,通過普通的方式進行設置的時候需要配置TableInputFormat/TableOutputFormat的相關屬性,如上的

//設置讀取的表
configuration.set(TableInputFormat.INPUT_TABLE, "client");
  • 1
  • 2

而是使用TableMapReduceUtil的initTableMapperJob/initTableReducerJob則是通過參數傳遞這些配置,下麵給出具體的配置項

TableInputFormat

TableInputFormat

TableOutputFormat

TableOutputFormat

initTableMapperJob

initTableMapperJob

initTableReducerJob

initTableReducerJob

最後更新:2017-09-20 17:03:49

  上一篇:go  大數據資源爭奪戰此起彼伏 對用戶而言是福是禍?
  下一篇:go  安防企業如何策略調整 翻轉績效