提起HBase,必须要说的一点就是它的shell语言.
对于习惯了传统关系数据库sql语法的人,接触到它可能会很排斥
但是实际上HBase的shell语言是基于hbase的特性,而且具有很强大的功能的,
下面就来介绍一些最基础的常规操作之外的shell语句
诸如 : 创建表格, 删除表格, 添加数据, 获取数据, 扫描全表, 删除数据等操作,网上一搜一大把,就不在赘述…
直接进入主题,首先要对Hbase的shell有一个最基本的介绍 :
一. 什么是HBase Shell
Hbase Shell 是HBase集群的命令行接口.
用户可以通过Shell访问本地或者是远程服务器并与其进行交互,Shell同时提供了客户端和管理功能的操作.
Hbase Shell 是基于Jruby的,其是基于Ruby实现的java虚拟机.
它使用的是交互式的Ruby Shell,输入命令并迅速得到响应
二.HBase的Shell操作
以下的每一条都会附上相关的操作, 用来演示的表格统一以testtable1,… testtablen这种方式来命名
各项操作会给出详细的注释帮助大家进行理解!
1. Ruby散列属性
Ruby散列属性格式如下 :
{'key1' => 'value1', 'key2' => 'value2', ...}
// 键值对需要包含在花括号中, 键值对之间用逗号隔开,键/值之间用 => 分隔, 对于NAME,VERSIONS等属性,不需要使用引号
示例如下 :
a.创建表格
create 'testtable1', {NAME => 'columnfamily1', VERSIONS => 1,TTL => 1314520}
// 创建一个列名为columnfamily1, 仅保留一个版本号(默认是三个) ,TTL=>的更新超时时间:该列最后更新的时间,到超时时间的限制为1314520 ,默认的值是(2147483647)大约是69年... 几乎相当于永久有效
执行情况如下:
b. 创建表格的时候进行预分区
对于一些用于存储大量数据的表格 : 如果创建表格的时候不进行合理的预分区的话, 首先导致的就是插入数据的时候并行度降低(默认的分区数为1), 其次就是当数据量达到一定程度的情况下,由系统进行分区操作会严重的影响效率...
场景之一就是 :使用bulkload方法入库的时候 : 合理预分区和不分区的效率能差好几十倍!
create 'testtable2','columnfamily1',{SPLITS => [ '1','2','3', '4','5','6','7','8','9']}
// 建表的时候进行预分区 第一个分区的start Key --- end Key 1, 第二个分区的start Key 1, end Key 2, ... 最后一个分区的start Key 9, end Key ---
c.使用命名空间的方式建表
命名空间建表的方式 我接触到的场景的目的主要就是:
1. 方便管理,规范命名
2. 便于进行权限的控制(在租户状态下,不同的租户只具备对该租户指定的命名空间操作的权限)
如何操作呢?
create_namespace 'xmr_ns' //创建一个命名空间
create 'xmr_ns:testtable3','info' //在刚刚创建的命名空间下面建表,列簇名为 : info
命名空间的其它操作 :(不一一截图啦)
drop_namespace '命名空间名' //删除某个命名空间
list_namespace // 列出所有的命名空间
describe_namespace '命名空间名' //描述命名空间
list_namespace_tables '命名空间名' //列出某个命名空间下面的表
既然命名空间主要是为了权限控制所做的,那它的授权操作一定要叙述下了!
grant 'hmaster','W','@xmr_ns' //授予用户hmaster对于命名空间xmr_ns的写权限
// 其中权限包括:RWXCA
revoke 'hmaster', '@xmr_ns' //回收用户hmaster对于命名空间xmr_ns的全部权限
2. 直接写简单的java程序
HBase Shell可以直接调用HBase的类和功能函数哦~
也可以直接用简单的shell语句直接写出java程序呢,
怎么样,是不是很炫酷?
a. 将二进制数组转换成整型
org.apache.hadoop.hbase.util.Bytes.toInt("\x00\x01\x06[".to_java_bytes)
// shell将前三个不可见字符编码为16进制值,第四个字符"["作为一个字符打印
结果如下 :
b. 将日期类型转变为当前时间的豪秒数,然后转变成可读的日期
java.text.SimpleDateFormat.new("yyyy/MM/dd HH:mm:ss").parse(\
"2018/05/27 17:50:00").getTime()
// 通过SimpleDateFormat 获得格式形如"yyyy/MM/dd HH:mm:ss"这种形式的时间距离1970年1月1日00:00的毫秒值 ,其中\代表的是换行操作
java.util.Date.new(1527414600000).toString()
// 把刚刚拿到的时间毫秒值以我们看起来舒服的方式展现出来
结果如下 :
c.使用循环向表里面批量插入数据
还在为每次使用shell命令都要一条一条的put而苦恼么?
其实有更快捷的批量插入的方式的!
还记得刚刚创建的预分区的那个表格么?就用它来测试好了,顺便还能检验预分区的效果!
for i in '1'..'9' do for j in '1'..'9' do put 'testtable2',\"row-#{i}#{j}","columnfamily1:#{j}","#{j}" end end
// 使用for循环,向表格里面列名为columnfamily1的列里面插入数据
// 行键为 11--99, 值为1--9
界面显示结果如下:
查询表格 :
scan 'testtable2' //对指定的表格进行全表扫描
从输出的结果就可以知道命令行的作用啦!
d. 获得当前时间的值
Time.now.to_i // 获取当前的时间距离1970-01-01的秒数
3.针对于HBase的其它高阶操作
a.手动compact
在HBase中,每当memstore的数据flush到磁盘后,就形成一个storefile,当storefile的数量越来越大时,会严重影响HBase的读性能 ,所以必须将过多的storefile文件进行合并操作。
主要起到如下几个作用:
(1)合并文件
(2)清除删除、过期、多余版本的数据
(3)提高读写数据的效率
HBase中实现了两种compaction的方式:minor and major
这两种compaction方式的区别是:
<1> Minor操作只用来做部分文件的合并操作以及包括minVersion=0并且设置ttl的过期版本清理,不做任何删除数据、多版本数据的清理工作。
<2>Major操作是对Region下的HStore下的所有StoreFile执行合并操作,最终的结果是整理合并出一个文件。
在shell中的命令如下:
major_compact 'testtable2' //对表格testtable2进行major合并操作
**暂时在工作中接触到的稍微高级点的shell命令就是这些,后续接触到在持续更新 **