本文介绍HBase在shell终端的常见操作以及如何利用java api操作HBase,操作系统:Ubuntu24.04
参考:
https://blog.51cto.com/u_16099228/8016429
https://blog.csdn.net/m0_37739193/article/details/73618899
https://cloud.tencent.com/developer/article/1936188
启动HBase
Hbase操作主要包括两种模式:通过Shell输入命令或者通过编程语言(Java、Python等)调用API
首先启动Hbase,顺序为:
启动Hadoop → 启动Zookeeper → 启动HBase
zkp start
HBase Shell模式
进入HBase Shell模式,在hadoop101:
hbase shell #进入HBase shell 命令行模式

如果需要退出HBase Shell模式,在hadoop101上执行:
exit
如果在运行过程中出现了超时的日志,可以忽略,打回车即可
1. 在HBase中创建表(Shell模式)
假设这里要创建一个表student,该表包含Sname、Ssex、Sage、Sdept、course等字段。需要注意的是,在关系型数据库(比如MySQL)中,需要首先创建数据库,然后再创建表,但是,在HBase数据库中,不需要创建数据库,只要直接创建表就可以。按照PPT教程,在HBase中创建student表的Shell命令如下:
create 'student','Sname','Ssex','Sage','Sdept','course'

这里的各个字符表示的是列族,一个HBase表最多可以有32个列族。超过这个限制会导致表的创建或修改失败,但通常情况下不需要那么多的列族。列族多的话,会给HBase带来很多问题(这个是一个常见的考点!)。
另外,仔细体会一下,HBase建表时,仅仅建立了列族,没有建立列。列是在put数据的时候才出现的。
2. 在HBase中查看表信息(Shell模式)
创建完"student"表后,可通过describe命令查看"student"表的基本信息。
describe 'student'

可以使用list命令查看当前HBase数据库中已经创建了哪些表,命令如下:
list

3. 在HBase中添加数据(Shell模式)
可以用Shell命令手工插入数据,命令如下:
put 'student','95001','Sname','LiYing'

HBase 使用 put 命令可以向数据表中插入一行新的数据,或者覆盖指定行的数据。put 命令一次只能插入一个单元格的数据:
put 'namespace:table','RowKey','CF:CQ','value', timestamp
- 第一个参数 namespace:table 为指定命名空间下的表名。
- 第二个参数RowKey为行键的名称,字符串类型。
- 第三个参数CF:CQ为列族和列的名称。列族名必须是已经创建的,否则 HBase 会报错;列名是临时定义的,因此列族里的列是可以随意扩展的。
- 第四个参数value为单元格的值。在 HBase 里,所有数据都是字符串的形式。
- 最后一个参数timestamp为时间戳,如果不设置时间戳,则系统会自动插入当前的时间作为时间戳。
继续添加4个单元格的数据,用来记录LiYing同学的相关信息,命令如下:
put 'student','95001','Ssex','male'
put 'student','95001','Sage','22'
put 'student','95001','Sdept','CS'
put 'student','95001','course:math','80'

解释:这里的course:math表示在course列族下面新建了一个math列,成绩为80分
4. 删除表(Shell模式)
删除表需要分两步操作,第一步先让该表不可用,第二步删除表。比如,要删除student表,可以使用如下命令:
disable 'student'
drop 'student'

7. 查询历史数据(Shell模式)
为了查询历史数据,这里创建一个teacher表,首先,在创建表的时候,需要指定保存的版本数(假设指定为5),命令如下:
create 'teacher',{NAME=>'username',VERSIONS=>5}
创建表的完整语法:
create <table>, {NAME => <family>,VERSIONS => <VERSIONS>}

然后,插入数据,并更新数据,使其产生历史版本数据,需要注意的是,这里插入数据和更新数据都是使用put命令,具体如下:
put 'teacher','91001','username','Mary'
put 'teacher','91001','username','Mary1'
put 'teacher','91001','username','Mary2'
put 'teacher','91001','username','Mary3'
put 'teacher','91001','username','Mary4'
put 'teacher','91001','username','Mary5'
查询时,默认情况下回显示当前最新版本的数据,如果要查询历史数据,需要指定查询的历史版本数,由于上面设置了保存版本数为5,所以,在查询时制定的历史版本数的有效取值为1到5,具体命令如下:
get 'teacher','91001',{COLUMN=>'username',VERSIONS=>5}
get 'teacher','91001',{COLUMN=>'username',VERSIONS=>3}

HBase Java API
1. 导入maven依赖
首先,找到hbase的jar包
输入HBase后,找到很多包

通过https://blog.51cto.com/u_16213369/9390696这篇文章和PPT中的源代码,感觉我们是需要HBase Client包,点击Apache HBase Client,

我安装的HBase是2.5.8版本,hadoop是3.3.6,应该就是2.5.8-hadoop3这个配置吧

在pom.xml里添加
<!-- https://mvnrepository.com/artifact/org.apache.hbase/hbase-client -->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.5.8-hadoop3</version>
</dependency>
随后刷新

2. 与HBase建立连接(Java模式)
参考:
https://www.cnblogs.com/yxym2016/p/14698745.html
HBase学习四之JAVA编程_tabledescriptorbuilder-CSDN博客
在网上找了一个模板,简化了一下,并且按照我的配置设置了参数。代码如下:
java
package HBase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
// import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
public class TestHBase {
public static void main(String[] args) {
try {
// 获取配置文件信息
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "hadoop101,hadoop102,hadoop103"); // 我的三台zookeeper服务器是master、node1和node2
// 建立连接,获取connection对象
Connection connection = ConnectionFactory.createConnection(conf);
// 获取admin对象,用于建表、删表等
Admin admin = connection.getAdmin();
/*
在中间编写代码即可
*/
// 关闭资源
admin.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 在HBase建立表和增加数据(Java模式)
代码如下:
java
package HBase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
public class Database {
public static void main(String[] args) {
try {
// 获取配置文件信息
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", " hadoop101,hadoop102,hadoop103"); // 我的三台zookeeper服务器是master、node1和node2
// 建立连接,获取connection对象
Connection connection = ConnectionFactory.createConnection(conf);
// 获取admin对象
Admin admin = connection.getAdmin();
// 准备创建一张student表,有两个列族info和course
// 构建表描述构建器,一张表只需要一个
TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(TableName.valueOf("student"));
// 构建列族描述构建器,每个列族需要一个
ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder1 = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("info"));
ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder2 = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("course"));
// 构建列族描述,每个列族描述构建器可以构建一个
ColumnFamilyDescriptor columnFamilyDescriptor1 = columnFamilyDescriptorBuilder1.build();
ColumnFamilyDescriptor columnFamilyDescriptor2 = columnFamilyDescriptorBuilder2.build();
// 添加列族,由于有多个列族,所以需要先构造一个Connection对象,然后使用tableDescriptorBuilder.setColumnFamilies()方法
Collection<ColumnFamilyDescriptor> families = Arrays.asList(columnFamilyDescriptor1, columnFamilyDescriptor2);
tableDescriptorBuilder.setColumnFamilies(families);
// 如果只有一个列族,就用下面这个方法
// tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);
// 构建表描述
TableDescriptor tableDescriptor = tableDescriptorBuilder.build();
// 创建表
admin.createTable(tableDescriptor);
// 获得表student的table对象
TableName tableName = TableName.valueOf("student");
Table table = connection.getTable(tableName);
// 定义第一个row key
String rowKey1 = "0001";
// 构建Put对象,对应put命令
Put put = new Put(Bytes.toBytes(rowKey1));
// 添加列,第一个参数是列族名,第二个参数是列名,第三个参数是值
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("tom"));
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("gender"), Bytes.toBytes("male"));
put.addColumn(Bytes.toBytes("course"), Bytes.toBytes("math"), Bytes.toBytes("80"));
// 将数据插入数据库
table.put(put);
// 关闭表
table.close();
// 关闭资源
admin.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用下列shell命令查看数据,发现数据成功写入HBase中的student表
get 'student','0001'

4. 在HBase查询数据(Java模式)
代码如下:
java
package HBase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.List;
public class Query {
public static void main(String[] args) {
try {
// 获取配置文件信息
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "hadoop101,hadoop102,hadoop103"); // 我的三台zookeeper服务器是master、node1和node2
// 建立连接,获取connection对象
Connection connection = ConnectionFactory.createConnection(conf);
// 获取admin对象,用于建表、删表等
Admin admin = connection.getAdmin();
// 获得表student的table对象
TableName tableName = TableName.valueOf("student");
Table table = connection.getTable(tableName);
// 获得rowkey为0001的get对象
Get get = new Get(Bytes.toBytes("0001"));
// 得到查询结果
Result result = table.get(get);
// 得到单元格列表
List<Cell> cells = result.listCells();
// 输出rowkey
System.out.println("rowKey= " + Bytes.toString(result.getRow()));
// 遍历所有的cell
for (Cell cell : cells) {
// 输出列名
System.out.print(Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()) + ":");
// 输出单元格的值
System.out.println(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
}
// 关闭表格
table.close();
// 关闭资源
admin.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
执行完成后,在IDEA的控制台可以看到下面的信息,成功输出rowkey为0001的记录。
