
每日一句正能量
如果说幸福是一个悖论,那么,这个悖论的解决正存在于争取幸福的过程之中。其实有斗争,有苦恼,但是要希望尚存,就有幸福。
第五章 HBase分布式数据库
章节概要
Spark计算框架是如何在分布式环境下对数据处理后的结果进行随机的、实时的存储呢?HBase数据库正是为了解决这种问题而应用而生。HBase数据库不同于一般的数据库,如MySQL数据库和Oracle数据库是基于行进行数据的存储,而HBase则是基于列进行数据的存储,这样的话,HBase就可以随着存储数据的不断增加而实时动态的增加列,从而满足Spark计算框架可以实时的将处理好的数据存储到HBase数据库中的需求。本章将针对HBase分布式数据库的相关知识进行详细讲解。
5.3 HBase的基本操作
5.3.1 HBase的Shell操作
HBase Shell提供大量操作HBase的命令,通过Shell命令很方便地操作HBase数据库,如创建、删除及修改表、向表中添加数据、列出表中的相关信息等操作。当使用Shell命令行操作HBase时,需要进入HBase Shell交互界面,执行“bin/hbase shell”命令进入到目录/hbase-1.2.1的界面。如下图所示:
进入HBase Shell交互界面后,可以通过一系列Shell命令操作HBase, 接下来,通过一张表列举一些操作HBase表常见的Shell命令,具体如表所示。
表5-1 常见的Shell命令
命令名称 | 相关说明 |
---|---|
create | 创建表 |
put | 插入或更新数据 |
scan | 扫描表并返回表的所有数据 |
describe | 查看表的结构 |
get | 获取指定行或列的数据 |
count | 统计表中数据的行数 |
delete | 删除指定行或者列的数据 |
deleteall | 删除整个行或列的数据 |
truncate | 删除整个表中的数据,但是结构还在 |
drop | 删除整个表,数据和结构都删除(慎用) |
关于HBase中常见的Shell操作的讲解具体如下:
1.创建表
通过create
创建表,具体语法如下:
create 'table name', ' column family'
在上述语法中,“table name"为表名,创建表必须指定;“column family"为列族名,创建表也必须指定。
例如,创建一个名称为student、 列族名为info的HBase表,命令如下:
create 'student', 'info'
结果如下图所示:
执行"list
"命令,查看数据库中的数据表,命令如下:
list
结果如下图所示:
在上述代码中,出现了student数据表,说明创建表成功。
2.插入操作
通过使用put
插入或者更新表中的数据,具体语法如下:
put 'table name', 'row1', 'column family: column name', 'value'
在上述语法中,“row1 ”为行键(即Row Key) ;“column family: column name’为列族和列名的值。
例如,向student表中插入五条数据,命令如下:
hbase(main):009:0> put 'student','1001','info:sex','male'
0 row(s) in 0.5600 seconds
hbase(main):010:0> put 'student','1001','info:age','18'
0 row(s) in 0.0150 seconds
hbase(main):011:0> put 'student','1002','info:name','Janan'
0 row(s) in 0.0320 seconds
hbase(main):012:0> put 'student','1002','info:sex','female'
0 row(s) in 0.0360 seconds
hbase(main):013:0> put 'student','1002','info:age','20'
0 row(s) in 0.0240 seconds
结果如下图所示:
3.扫描操作
通过scan
扫描表中的数据,具体语法如下:
scan ‘table name’
例如,扫描student表的所有数据,命令如下:
scan 'student'
结果如下:
4.查看操作
通过describe
查看表结构,具体语法如下:
describe tabfe name
查看student表的表结构,命令如下:
describe 'student'
结果如下图所示:
上述代码中,通过describe输出了 student表的结构,表结构包含很多字段,具体介绍如下:
- NAME:表示列族名。
- BLOOMFILTER: 表示为列族级别的类型(读者只作了解即可)。
- VERIONS::表示版本数,默认值为1。
- IN_ MEMORY:设置是否存入内存。
- KEEP_ DELETED_ CELLS:设置被删除的数据,在基于时间的历史数据查询中是否依然可见。
- DATA_ .BLOCK_ ENCODING: 表示数据块的算法(读者只作了解即可)。
- TTL:表示版本存活的时间。
- COMPRESSION:表示设置压缩算法。
- MIN_ _VERSIONS:表示最小版本数。
- BLOCKCACHE: 表示是否设置读缓存。
- REPLICATION:表示设置备份。
5.更新操作
通过使用put
更新student表指定字段的数据,具体语法如下:
put 'table name',' row ' ,' column family :column name',' new value
在student表中,将行键为1001、列名name且值为18这一条数据中的值更新成100,命令如下:
put 'student', '1001', 'info:age', '100'
结果如下图所示:
6.获取指定字段的操作
通过使用get
获取指定行或指定列族:列的数据,具体语法如下:
//查看指定行的数据
get ' table name','row1 '
获取student表中行键为1001的数据,命令如下:
get 'student', '1001'
结果如下图所示:
查看指定行,指定列的数据, 获取行键为1001,的age列的数据,命令如下:
get 'student', '1001', 'info:age'
7.统计操作
通过使用count
统计表中数据的行数,具体语法如下:
count 'table name'
统计student表中数据的行数,命令如下:
count 'student'
结果如下图所示:
8.删除操作
通过使用delete
删除表中“指定字段”的数据,具体语法如下:
delete 'table name', ' row', ' column name', ' timestamp
删除student表中行键为1002、列名为info:sex的一条数据,命令如下:
delete 'student', '1002', 'info:sex'
结果如下图所示:
上述命令执行成功后,使用scan获取数据表中的数据,命令如下:
scan 'student'
结果如下图所示:
从上述代码可以看出,行键为1002、列名为info:sex的数据已经被删除。
如果要删除表中一-行所有的数据,可以使用deleteall
命令, 具体语法如下:
deleteall 'table mame', ' row'
例如,删除student表中行键为1001的所有数据,使用scan扫描数据表中的数据,扫描结果,命令如下:
deleteall 'student', '1001'
结果如下图所示:
从上述代码可以看出,行键为1001的所有数据已经被删除了。
9.清空表中的所有数据
通过使用truncate
清空表中的所有数据,具体语法如下:
truncate ' table name '
清空student表中的所有数据,命令如下:
truncate 'student'
结果如下图所示:
从上述代码可看出,表student中的所有数据都已经被清空。
10.drop删除表
通过使用drop
删除表,但是删除前要先禁用表,命令如下:
disable 'student'
然后再用drop删除表,具体语法如下:
drop ‘table name’
例如,删除表student,命令如下:
disable 'student'
drop 'student'
list
结果如下图所示:
上述的代码中,首先使用”disable“让student表变为禁用状态,然后进行删除操作。若表不是禁用状态,则无法删除。”[ ]“表示数据库已经为空,说明student表已经被删除。
5.3.2 HBase的Java API操作
HBase是由Java语言开发的,它对外提供了Java API的接口。下面,通过一个表来列举HBase常见的Java API。
类或接口名称 | 相关说明 |
---|---|
Admin | 是一个类,用于建立客户端和HBase 数据库的连接 |
HBaseConfiguration | 是一个类,用于将HBase配置添加到配置文件中 |
HTableDescriptor | 是一个接口,用于描述表的信息 |
HColumnDescriptor | 是一个类,用于描述列族的信息 |
Table | 是一个接口,用于实现HBase表的通信 |
Put | 是一个类,用于插入数据操作 |
Get | 是一个类,用于查询单条记录 |
Delete | 是一个类,用于删除数据 |
Scan | 是一个类,用于查询所有记录 |
Result | 是一个类,用于查询返回的单条记录结果 |
1.创建工程并导入依赖
创建一个名称为"spark_chapter05"的Maven项目。然后在项目spark_chapterO5中配置pom.xml文件,也就是引入HBase相关的依赖和单元测试的依赖,步骤如下图所示:
pom.xml文件添加的内容具体如下所示:
文件5-1 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itcast</groupId>
<artifactId>spark_chapter05</artifactId>
<version>1.0-SNAPSHOT</version>
<!--单元测试依赖-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--hbase 客户端依赖-->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.2.1</version>
</dependency>
<!--hbase 核心依赖-->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-common</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
</project>
结果如下图所示:
2.创建Java类,连接集群
在项目spark_chapterO5目录/src/main/java下创建一个名为com.itcast.hbase包,并在该包下创建HBaseTest.java文件,该文件用于编写Java测试类,构建Configuration和Connection对象。初始化客户端对象的具体操作步骤,如下图所示:
文件5-2 HBaseTest.java
public class HBaseTest {
//初始化Configuration对象
private Configuration conf = null;
//初始化连接
private Connection conn = null;
@Before
public void init() throws Exception {
//获取Configuration对象
conf = HBaseConfiguration.create();
//对于hbase的客户端来说,只需要知道hbase所经过的Zookeeper集群地址即可
//因为hbase的客户端找hbase读写数据完全不用经过HMaster
conf.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181,hadoop03:2181");
//获取连接
conn = ConnectionFactory.createConnection(conf);
}
}
3.创建数据表
在HBaseTest.Java文件中,定义一个方法createTable(),主要用于演示创建数据表操作。具体代码如下:
@Test
public void createTable() throws Exception {
//获取表管理器对象
Admin admin = conn.getAdmin();
//创建表的描述对象,并指定表名
HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf("t_user_info".getBytes()));
//构造第一个列族描述对象,并指定列族名
HColumnDescriptor hcd1 = new HColumnDescriptor("base_info");
//构造第二个列族描述对象,并指定列族名
HColumnDescriptor hcd2 = new HColumnDescriptor("extra_info");
//为该列族设定一个版本数量,最小为1,最大为3
hcd2.setVersions(1, 3);
//将列族描述对象添加到表描述对象中
tableDescriptor.addFamily(hcd1).addFamily(hcd2);
//利用表管理器来创建表
admin.createTable(tableDescriptor);
//关闭
admin.close();
conn.close();
}
在上述代码中,数据库中有一个名称为t_user_info的数据表,说明数据表创建成功。执行后和在hbase shell 中用"list
" 验证结果,如下:
4 插入数据
在HBaseTest.Java文件中,定义一个testPut()方法,主要用于演示在t_user_info表中插入数据的操作。具体代码如下:
@Test
public void testPut() throws Exception {
//创建table对象,通过table对象来添加数据
Table table = conn.getTable(TableName.valueOf("t_user_info"));
//创建一个集合,用于存放Put对象
ArrayList<Put> puts = new ArrayList<Put>();
//构建put对象(kv形式),并指定其行键
Put put01 = new Put(Bytes.toBytes("user001"));
put01.addColumn(Bytes.toBytes("base_info"),
Bytes.toBytes("username"), Bytes.toBytes("zhangsan"));
put01.addColumn(Bytes.toBytes("base_info"),
Bytes.toBytes("password"), Bytes.toBytes("123456"));
Put put02 = new Put("user002".getBytes());
put02.addColumn(Bytes.toBytes("base_info"),
Bytes.toBytes("username"), Bytes.toBytes("lisi"));
put02.addColumn(Bytes.toBytes("extra_info"),
Bytes.toBytes("married"), Bytes.toBytes("false"));
//把所有的put对象添加到一个集合中
puts.add(put01);
puts.add(put02);
//提交所有的插入数据的记录
table.put(puts);
//关闭
table.close();
conn.close();
}
执行后和在hbase shell 中用scan
验证结果,如下:
5.查看指定字段的数据
在HBaseTest.Jaga文件中,定义一个testGet()方法用于演示查看行键为usero01的数据。具体代码如下:
@Test
public void testGet() throws IOException {
Table table = conn.getTable(TableName.valueOf("t_user_info"));
//得到用于扫描region的对象
// Scan scan = new Scan();
Get get = new Get("user001".getBytes());
//使用HTable得到resultcanner实现类的对象
Result result1 = table.get(get);
List<Cell> cells = result1.listCells();
for (Cell cell : cells) {
//得到rowkey
System.out.println("行键:" + Bytes.toString(CellUtil.cloneRow(cell)));
//得到列族
System.out.println("列族:" + Bytes.toString(CellUtil.cloneFamily(cell)));
System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));
System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
执行结果如下:
6 扫描数据
在HBaseTestJava文件中,定义一个testScan()方法用于演示扫描t_user_info表中的所有数据。具体代码如下:
@Test
public void testScan() throws Exception {
//获取table对象
Table table = conn.getTable(TableName.valueOf("t_user_info"));
//获取scan对象
Scan scan = new Scan();
//获取查询的数据
ResultScanner scanner = table.getScanner(scan);
//获取ResultScanner所有数据,返回迭代器
Iterator<Result> iter = scanner.iterator();
//遍历迭代器
while (iter.hasNext()) {
//获取当前每一行结果数据
Result result = iter.next();
//获取当前每一行中所有的cell对象
List<Cell> cells = result.listCells();
//迭代所有的cell
for(Cell c:cells){
//获取行键
byte[] rowArray = c.getRowArray();
//获取列族
byte[] familyArray = c.getFamilyArray();
//获取列族下的列名称
byte[] qualifierArray = c.getQualifierArray();
//列字段的值
byte[] valueArray = c.getValueArray();
//打印rowArray、familyArray、qualifierArray、valueArray
System.out.println("行键:"+new String(rowArray, c.getRowOffset(),
c.getRowLength()));
System.out.print("列族:"+new String(familyArray,c.getFamilyOffset(),
c.getFamilyLength()));
System.out.print(" "+"列:"+ new String(qualifierArray,
c.getQualifierOffset(), c.getQualifierLength()));
System.out.println(" "+"值:"+ new String(valueArray,
c.getValueOffset(), c.getValueLength()));
}
System.out.println("-----------------------");
}
//关闭
table.close();
conn.close();
}
运行后效果如下:
7 删除指定列的数据
在HBaseTest.Java文件中,定义一个testDel()方法用于演示删除t_user_info表中行键为useroO1的数据。具体代码如下:
@Test
public void testDel() throws Exception {
//获取table对象
Table table = conn.getTable(TableName.valueOf("t_user_info"));
//获取delete对象,需要一个rowkey
Delete delete = new Delete("user001".getBytes());
//在delete对象中指定要删除的列族-列名称
delete.addColumn("base_info".getBytes(), "password".getBytes());
//执行删除操作
table.delete(delete);
//关闭
table.close();
conn.close();
}
运行testDel()方法进行测试,然后在HBase Shell交互式页面执行"scan
"命令,查看数据表t_user_info中的数据,检验结果如下:
8.删除表
在HbaseTest.Java文件中,定义一个testDrop0方法用于演示删除t_ user_ info表。 具体代码如下:
@Test
public void testDrop() throws Exception {
//获取一个表的管理器
Admin admin = conn.getAdmin();
//删除表时先需要disable,将表置为不可用,然后在delete
admin.disableTable(TableName.valueOf("t_user_info"));
admin.deleteTable(TableName.valueOf("t_user_info"));
//关闭
admin.close();
conn.close();
}
执行后在hbase shell用"list
"检验结果如下:
转载自:https://blog.csdn.net/u014727709/article/details/148438896
欢迎 👍点赞✍评论⭐收藏,欢迎指正