HBase客户端API使用

本文涉及的产品
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1010885678/article/details/51985735 篇幅中使用的HBase版本为1.
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1010885678/article/details/51985735

篇幅中使用的HBase版本为1.1.2

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>

开发流程

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)

为了程序的可维护性和方便调用,这里将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));

  }

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);
}

篇幅有限,HBase工具类的代码已上传至Github
API文档中还有许多实用的函数没有接触到,希望在实践中可以操作一下

MapReduceApi

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

<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-server</artifactId>
    <version>${hbase.version}</version>
</dependency>

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);
        }
    }
}

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);
        }
    }
}

驱动程序

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);
    }

示例代码以上传至Github

关于驱动程序中设置job的方法

在上面的代码中可以看到,设置job的方法有两种:MapReduce常用方式和HBase提供的TableMapReduceUtil工具类

两种方式的设置效果是相同的,通过普通的方式进行设置的时候需要配置TableInputFormat/TableOutputFormat的相关属性,如上的

//设置读取的表
configuration.set(TableInputFormat.INPUT_TABLE, "client");

而是使用TableMapReduceUtil的initTableMapperJob/initTableReducerJob则是通过参数传递这些配置,下面给出具体的配置项

TableInputFormat

TableInputFormat

TableOutputFormat

TableOutputFormat

initTableMapperJob

initTableMapperJob

initTableReducerJob

initTableReducerJob

作者:@小黑

相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
&nbsp; 相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情:&nbsp;https://cn.aliyun.com/product/hbase &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
存储 API Apache
【zookeeper 第三篇章】客户端 API
本文介绍了Apache ZooKeeper客户端的一些常用命令及其用法。首先,`create`命令用于创建不同类型的节点并为其赋值,如持久化节点、有序节点及临时节点等。通过示例展示了如何创建这些节点,并演示了创建过程中的输出结果。其次,`ls`命令用于列出指定路径下的所有子节点。接着,`set`命令用于更新节点中的数据,可以指定版本号实现乐观锁机制。
38 0
|
3月前
|
负载均衡 API 数据安全/隐私保护
Zookeeper的客户端-原生的API
Zookeeper的客户端-原生的API
|
4月前
|
安全 API 网络安全
【Azure API 管理】APIM如何配置客户端证书的CRL检测策略
【Azure API 管理】APIM如何配置客户端证书的CRL检测策略
|
4月前
|
测试技术 编译器 Go
依赖注入与控制反转:优化Go语言REST API客户端
依赖注入与控制反转:优化Go语言REST API客户端
|
4月前
|
API C# 开发框架
WPF与Web服务集成大揭秘:手把手教你调用RESTful API,客户端与服务器端优劣对比全解析!
【8月更文挑战第31天】在现代软件开发中,WPF 和 Web 服务各具特色。WPF 以其出色的界面展示能力受到欢迎,而 Web 服务则凭借跨平台和易维护性在互联网应用中占有一席之地。本文探讨了 WPF 如何通过 HttpClient 类调用 RESTful API,并展示了基于 ASP.NET Core 的 Web 服务如何实现同样的功能。通过对比分析,揭示了两者各自的优缺点:WPF 客户端直接处理数据,减轻服务器负担,但需处理网络异常;Web 服务则能利用服务器端功能如缓存和权限验证,但可能增加服务器负载。希望本文能帮助开发者根据具体需求选择合适的技术方案。
203 0
|
4月前
|
API
【Azure 应用服务】在App Service中调用外部服务API时需要携带客户端证书,而多次调用的情况下会出现WindowsCryptographicException Keyset does not exist异常
【Azure 应用服务】在App Service中调用外部服务API时需要携带客户端证书,而多次调用的情况下会出现WindowsCryptographicException Keyset does not exist异常
|
4月前
|
存储 安全 API
【Azure API 管理】在APIM中使用客户端证书验证API的请求,但是一直提示错误"No client certificate received."
【Azure API 管理】在APIM中使用客户端证书验证API的请求,但是一直提示错误"No client certificate received."
|
3月前
|
分布式计算 Java Hadoop
java使用hbase、hadoop报错举例
java使用hbase、hadoop报错举例
120 4
|
2月前
|
分布式计算 Hadoop Shell
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
80 4
|
2月前
|
SQL 分布式计算 Hadoop
Hadoop-37 HBase集群 JavaAPI 操作3台云服务器 POM 实现增删改查调用操作 列族信息 扫描全表
Hadoop-37 HBase集群 JavaAPI 操作3台云服务器 POM 实现增删改查调用操作 列族信息 扫描全表
38 3