HBase基础知识

目录

1、HBase数据库介绍

1.1、产生背景

1.2、简介

1.3、表结构逻辑视图

1.3.1、行键(RowKey)

1.3.2、列簇(Column Family)

1.3.3、时间戳(TimeStamp)

1.3.4、单元格(Cell)

1.4、HBase应用场景

2、HBase集群结构

3、HBase和Hive的比较

3.1、相同点

3.2、不同点

4、HBase集群搭建

4.1、安装步骤

5、HBase命令行演示

5.1、HBase命令使用初准备

5.2、HBase命令使用实战

6、HBase Java API 代码开发

6.1、基本增删改查实现

6.2、过滤器查询


1、HBase数据库介绍

1.1、产生背景

自 1970 年以来,关系数据库用于数据存储和维护有关问题的解决方案。大数据的出现后,好多公司实现处理大数据并从中受益,并开始选择像 Hadoop 的解决方案。Hadoop 使用分布式文件系统,用于存储大数据,并使用 MapReduce 来处理。Hadoop 擅长于存储各种格式的庞大的数据,任意的格式甚至非结构化的处理。

Hadoop 的限制
Hadoop 只能执行批量处理,并且只以顺序方式访问数据。这意味着必须搜索整个数据集,即使是最简单的搜索工作。当处理结果在另一个庞大的数据集,也是按顺序处理一个巨大的数据集。在这一点上,一个新的解决方案,需要访问数据中的任何点(随机访问)单元。

Hadoop 随机存取数据库
应用程序,如 HBase,Cassandra,CouchDB,Dynamo 和 MongoDB 都是一些存储大量数据和以随机方式访问数据的数据库。

Hadoop 的特点:
对于任意格式的庞大数据集,Hadoop 可以做到安全存储但是对于需要在庞大数据集做针对于单条记录的增删改查是做不到的。

Hive 的特点:
对于存储在 HDFS 上的结构化的数据,如果增加一些描述这些数据的元数据信息,那么我们可以把存储在 HDFS 上的数据抽象成一张二维表格,使用 Hive 进行各种 Insert/Select 操作。但是 Hive 还是天生不支持对于单条记录的增删改查,也不是设计用来做单条记录的增删改查的。

总结:
1)海量数据量存储成为瓶颈,单台机器无法负载大量数据
2)单台机器 IO 读写请求成为海量数据存储时候高并发大规模请求的瓶颈
3)随着数据规模越来越大,大量业务场景开始考虑数据存储横向水平扩展,使得存储服务可以增加/删除,而目前的关系型数据库更专注于一台机器。

重要问题探讨:如何设计一个能存储庞大数据集,同时也能做到实时增删改查的数据库系统?相当于设计一个 MySQL 的分布式版本。
先解决这个问题,再来学习别人的成果,这是一种较好的学习方式。而不是一上来便学习别人的成功。须知:已掌握的知识会限制我们的思维方式。

类似问题:
1、如何设计一个分布式文件系统?
2、如何设计一个分布式计算框架?
3、如何设计一个分布式数据库?
他们的难点是什么?

思路引爆点:
1、怎样快速判断一个元素在不在一个数据集中?布隆过滤器
2、是否能找到一种合适的数据结构和搜索算法能快速从一个数据集中找出一个元素?二分查找
3、如何设计分布式系统?网络编程模型(NIO RPC Netty)
4、是否可以提前过滤不参与查询的数据,提高查询效率?列裁剪

1.2、简介

官网:http://hbase.apache.org/

HBase 是 BigTable 的开源(源码使用 Java 编写)版本。是 Apache Hadoop 的数据库,是建立在 HDFS 之上,被设计用来提供高可靠性、高性能、列存储、可伸缩、多版本的 NoSQL的分布式数据存储系统,实现对大型数据的实时、随机的读写访问。

HBase 依赖于 HDFS 做底层的数据存储,BigTable 依赖 Google GFS 做数据存储
HBase 依赖于 MapReduce 做数据计算,BigTable 依赖 Google MapReduce 做数据计算
HBase 依赖于 ZooKeeper 做服务协调,BigTable 依赖 Google Chubby 做服务协调

与 Hadoop 一样,HBase 目标主要依靠横向扩展,通过不断增加廉价的商用服务器,来增加计算和存储能力。所以,HBase 是一个通过大量廉价机器解决海量数据的高速存储和读取的分布式数据库解决方案

NoSQL = NO SQL
NoSQL = Not Only SQL:会有一些把 NoSQL 数据的原生查询语句封装成 SQL,比如 HBase 就有 Phoenix 工具

关系型数据库 和 非关系型数据库的典型代表:
NoSQL:HBase, Redis, MongoDB
RDBMS:MySQL, Oracle, SQL Server, DB2

以下5点是HBase这个NoSQL数据库的要点

① 高并发,可扩展,解决海量数据集的随机实时增删改查
② HBase 本质依然是 Key-Value 数据库,查询数据功能很简单,不支持 join 等复杂操作(可通过 Hive 支持来实现多表 join 等复杂操作)
③ 不支持复杂的事务,只支持行级事务
④ HBase 中支持的数据类型:byte[](底层所有数据的存储都是字节数组)
⑤ 主要用来存储结构化和半结构化的松散数据。

结构化:数据结构字段含义确定,清晰,典型的如数据库中的表结构
半结构化:具有一定结构,但语义不够确定,典型的如 HTML 网页,有些字段是确定的(title),有些不确定(table)
非结构化:杂乱无章的数据,很难按照一个概念去进行抽取,无规律性

HBase 中的表特点

1、:一个表可以有上十亿行,上百万列
2、面向列:列可以灵活指定,面向列(族)的存储和权限控制,列(簇)独立检索。
3、稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。
4、无严格模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列

关于存储系统的模式介绍:

读模式:在读取数据的时候做模式校验,比如数据仓库 Hive
写模式:在写入数据进入存储系统的时候做模式校验,比如 RDBMS

1.3、表结构逻辑视图

1、RDBMS 完全可以抽象成是一张二维表格,表由行和列组成。由行和列确定一个唯一的值
2、HBase 本质是 key-value 数据库,key 是行健 rowkey,value 是所有真实 key-value 的集合
3、HBase 可以抽象成为一张四维表格,四维分别由行健RowKey,列簇Column Family,列Column和时间戳Timestamp 组成。
4、其中,一张 HBase 的所有列划分为若干个列簇 (Column Family)

HBase基础知识_第1张图片

1.3.1、行键(RowKey)

与 NoSQL 数据库们一样,RowKey 是用来检索记录的主键。访问 HBase Table 中的行,只有三种方式:
1、通过单个 row key 访问
2、通过 row key 的 range
3、全表扫描

RowKey 行键可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),最好是 16。在 HBase 内部,RowKey 保存为字节数组。HBase 会对表中的数据按照 rowkey 排序(字典顺序)

存储时,数据按照 RowKey 的字典序(byte order)排序存储。设计 Key 时,要充分排序存储这个特性,将经常一起读取的行存储放到一起。(位置相关性)

注意:
字典序对 int 排序的结果是
1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,…,9,91,92,93,94,95,96,97,98,99。
要保持整形的自然序,行键必须用 0 作左填充。
行的一次读写是原子操作(不论一次读写多少列)。这个设计决策能够使用户很容易的理解程序在对同一个行进行并发更新操作时的行为。
 

1.3.2、列簇(Column Family)

HBase 表中的每个列,都归属与某个列簇。列簇是表的 Schema 的一部分(而列不是),必须在创建表的时候指定。指定好了列簇就不能更改。列簇可以增加或者删除,删除的时候会删除这个列簇中的所有数据。

列名都以列簇作为前缀。例如 courses:history,courses:math 都属于 courses 这个列簇。访问控制、磁盘和内存的使用统计等都是在列簇层面进行的。

列簇越多,在取一行数据时所要参与 IO、搜寻的文件就越多,所以,如果没有必要,不要设置太多的列簇,官网推荐是小于等于 3(最好就一个列簇)。

1.3.3、时间戳(TimeStamp)

HBase 中通过 RowKey 和 Column 确定的为一个存储单元称为 Cell。每个 Cell 都保存着同一份数据的多个版本。版本通过时间戳来索引。时间戳的类型是 64 位整型。时间戳可以由 HBase (在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也可以由客户显式赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。每个Cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。HBase 在查询的时候,默认返回最新版本/最近的数据。如果需要读取旧版本的数据,可以指定时间戳。

为了避免数据存在过多版本造成的的管理(包括存储和索引)负担,HBase 提供了两种数据版本回收方式:
保存数据的最后 n 个版本
保存最近一段时间内的版本(设置数据的生命周期 TTL)。

用户可以针对每个列簇进行设置。

1.3.4、单元格(Cell)

由{RowKey, Column( = + ), Version} 唯一确定的单元。Cell 中的数据是没有类型的,全部是字节码形式存储。

1.4、HBase应用场景

1、半结构化或非结构化数据
对于数据结构字段不够确定或杂乱无章很难按一个概念去进行抽取的数据适合用 HBase。而且 HBase 是面向列的,HBase 支持动态增加字段

2、记录非常稀疏
RDBMS 的行有多少列是固定的,为 null 的列浪费了存储空间。而 HBase 为 null 的 Column是不会被存储的,这样既节省了空间又提高了读性能。

3、多版本数据
对于需要存储变动历史记录的数据,使用 HBase 就再合适不过了。HBase 根据 Row key 和Column key 定位到的 Value 可以有任意数量的版本值。

4、超大数据量的随机、实时读写
当数据量越来越大,RDBMS 数据库撑不住了,就出现了读写分离策略,通过一个 Master 专门负责写操作,多个 Slave 负责读操作,服务器成本倍增。随着压力增加,Master 撑不住了,这时就要分库了,把关联不大的数据分开部署,一些 join 查询不能用了,需要借助中间层。随着数据量的进一步增加,一个表的记录越来越大,查询就变得很慢,于是又得搞分表,比如按 ID 取模分成多个表以减少单个表的记录数。经历过这些事的人都知道过程是多么的折腾。采用 HBase 就简单了,只需要加机器即可,HBase 会自动水平切分扩展,跟 Hadoop 的无缝集成保障了其数据可靠性(HDFS)和海量数据分析的高性(MapReduce)。

5、查询简单
不涉及到复杂的 Join 查询,基于 RowKey 或者 RowKey 的范围查询

2、HBase集群结构

HBase基础知识_第2张图片

HBase基础知识_第3张图片

Region:是 HBase 将一个表中的所有数据按照 RowKey 的不同范围进行切割的逻辑单元,每个 Region 负责一定范围数据的读写访问。Region 由 RegionServer 负责管理。HBase 中的 Region的概念就和 HDFS 中的数据块的概念差不多,Region 是 HBase 表切分出来的一个分片。数据块是 HDFS 中的一个大文件切分出来的一个分片。

HMaster:HBase 的主节点,负责整个集群的状态感知、负载分配、负责用户表的元数据(schema)管理(可以配置多个用来实现 HA),HMaster 负载压力相对于 HDFS 的 NameNode会小很多。HBase 的 HMaster 其实就算是宕机一段时间也可以正常对外提供服务的(要搞清楚为什么)。

RegionServer:HBase 中真正负责管理 Region 的服务器,也就是负责为客户端进行表数据读写的服务器。每一台 RegionServer 会管理很多的 Region,一个 RegionServer 上面管理的所有的region不属于同一张表。负责Region的拆分,负责和底层的HDFS的存储交互,负责StoreFile的合并。

ZooKeeper:整个 HBase 中的主从节点协调,元数据的入口,主节点之间的选举,集群节点之间的上下线感知……都是通过 ZooKeeper 来实现

HDFS:用来存储 HBase 的系统文件,或者表的 Region 文件

Client:Client 包含了访问 HBase 的接口,另外 Client 还维护了对应的 Cache 来加速 HBase 的访问,比如 Cache 的.META.元数据的信息。

3、HBase和Hive的比较

3.1、相同点

1、HBase 和 Hive 都是架构在 Hadoop 之上,用 HDFS 做底层的数据存储,用 MapReduce 做数据计算

3.2、不同点

1、Hive 是建立在 Hadoop 之上为了降低 MapReduce 编程复杂度的 ETL 工具。
 HBase 是为了弥补 Hadoop 对实时操作的缺陷

2、Hive 表是纯逻辑表,因为 Hive 的本身并不能做数据存储和计算,而是完全依赖 Hadoop
 HBase 是物理表,提供了一张超大的内存 Hash 表来存储索引,方便查询

3、Hive 是数据仓库工具,需要全表扫描,就用 Hive,因为 Hive 是文件存储
 HBase 是数据库,需要索引访问,则用 HBase,因为 HBase 是面向列的 NoSQL 数据库

4、Hive 表中存入数据(文件)时不做校验,属于读模式存储系统
 HBase 表插入数据时,会和 RDBMS 一样做 Schema 校验,所以属于写模式存储系统

5、Hive 不支持单行记录操作,数据处理依靠 MapReduce,操作延时高
 HBase 支持单行记录的 CRUD,并且是实时处理,效率比 Hive 高得多

4、HBase集群搭建

4.1、安装步骤

1、 安装 zookeeper 集群,此处略

2、 找到官网下载 hbase 安装包 hbase-1.2.6-bin.tar.gz,这里给大家提供一个下载地址:
http://mirrors.hust.edu.cn/apache/hbase/
对应版本的官方文档:http://hbase.apache.org/1.2/book.html

3、 上传安装包到服务器,并解压到对应的安装目录
[hadoop@hadoop02 apps]# tar -zxvf hbase-1.2.6-bin.tar.gz -C /home/hadoop/apps/

4、 修改配置文件

1、修改运行环境配置环境
[hadoop@hadoop02 conf]# vi hbase-env.sh
修改两个两地方:
export JAVA_HOME=/usr/local/java/jdk1.8.0_73,表示修改为自己的 jdk 目录
export HBASE_MANAGES_ZK=false,表示不引用 hbase 自带的 zookeeper,用我们自己
安装的
保存退出

 

2、修改集群配置文件:hbase-site.xml
增加以下配置:

 

 hbase.rootdir
 hdfs://myha01/hbase
 

 

 hbase.cluster.distributed
 true
 

 

 hbase.zookeeper.quorum
 hadoop03:2181,hadoop04:2181,hadoop05:2181
 


保存退出

 

3、修改 regionservers
vi regionservers

hadoop02
hadoop03
hadoop04
hadoop05

4、修改 backup-masters(自行创建),指定备用的主节点
该文件是不存在的,先自行创建:vi backup-masters

hadoop05

5、拷贝 hadoop 的核心配置文件过来
最重要一步,要把 hadoop 的 hdfs-site.xml 和 core-site.xml 放到 hbase-1.2.6/conf 下
cp ~/apps/hadoop-2.7.5/etc/hadoop/core-site.xml ~/apps/hbase-1.2.6/conf/
cp ~/apps/hadoop-2.7.5/etc/hadoop/hdfs-site.xml ~/apps/hbase-1.2.6/conf/

5、 分发安装到各节点
scp -r hbase-1.2.6 hadoop03:/home/hadoop/apps/
scp -r hbase-1.2.6 hadoop04:/home/hadoop/apps/
scp -r hbase-1.2.6 hadoop05:/home/hadoop/apps/

6、 别忘了同步时间!!!!!!!!
HBase 集群对于时间的同步要求的比 HDFS 严格,所以,集群启动之前千万记住要进行时间同步,要求相差不要超过 30s 

7、 配置环境变量
vi ~/.bashrc
添加两行:
export HBASE_HOME=/home/hadoop/apps/hbase-1.2.6
export PATH=$PATH:$HBASE_HOME/bin

保存退出!!!别忘了执行 source ~/.bashrc,使配置生效

8、 启动(顺序别搞错了)

1、 先启动 zookeeper 集群
zkServer.sh start

 

2、 启动 hdfs 集群
start-dfs.sh

 

3、 启动 hbase
保证 ZooKeeper 集群和 HDFS 集群启动正常的情况下启动 HBase 集群
启动命令:start-hbase.sh

 

HBase基础知识_第4张图片

 

观看启动日志可以看到:
1、首先在命令执行节点启动 master
2、然后分别在 hadoop02,hadoop03,hadoop04,hadoop05 启动 regionserver
3、然后在 backup-masters 文件中配置的备节点上再启动了一个 master 主进程

9、 查看启动是否正常,是否成功

1、 检查各进程是否启动正常
主节点和备用节点都启动 hmaster 进程
各从节点都启动 hregionserver 进程

HBase基础知识_第5张图片

按照对应的配置信息各个节点应该要启动的进程如上图所示

 

2、 通过访问浏览器页面,格式为”主节点:16010”
http://hadoop02:16010/

10、如果有节点相应的进程没有启动,那么可以手动启动
hbase-daemon.sh start master
hbase-daemon.sh start regionserver 

5、HBase命令行演示

5.1、HBase命令使用初准备

概述:大数据生态里的各种软件,基本都会给出 shell 命令行操作。所以在拿到新上手的软件的时候先找到怎么进入命令行,然后相应要想到 help 命令,查看命令帮助。别着急一股脑儿扎进去敲各种命令,这就是思路,思路很重要。

下面按照我的思路来进行练习:

1、先进入 hbase shell 命令行
在你安装的随意台服务器节点上,执行命令:hbase shell,会进入到你的 hbase shell 客户端
[root@hadoop01 ~]# hbase shell

HBase基础知识_第6张图片

2、进入之后先别着急,先看一下提示。其实是不是有一句很重要的话:
HBase Shell; enter 'help' for list of supported commands.
Type "exit" to leave the HBase Shell
意在告诉怎么获得帮助,怎么退出客户端
help 获取帮助
help 获取所有命令提示
help "dml" 获取一组命令的提示
help "put" 获取一个单独命令的提示帮助
exit 退出 hbase shell 客户端

重点关注类操作:DDL, DML

3、语法规则

名称 命令表达式
创建表 create '表名称','列名称1','列名称2','列名称N'
添加记录 put '表名称','行名称','列名称:','值'
查看记录 get '表名称','行名称'
查看表中的记录总数 count '表名称'
删除记录 delete '表名','行名称','列名称'
删除一张表 先要屏蔽该表,才能对表进行删除操作,第一步disable '表名称' 第二步 drop '表名称'
查看所有记录 scan '表名称'
查看某个表某个列中所有数据 scan '表名称',['列名称:']
更新记录 就是重写一遍进行覆盖

5.2、HBase命令使用实战

1、显示 hbase 中的表列表:list

2、创建表

创建一张 hbase 表,表名叫做 user,该表有 info 和 data 两个列簇,注意,创建表的时候不 用指定列的信息,插入数据的时候才需要指定 key-value 的信息,这个 key 就是列

create 'user', 'info', 'data'

也可以这样写:

create 'user',{NAME=>'info'},{NAME=>'data'}

创建一张表叫做 user_info,包含两个列簇 base_info 和 extra_info,并且分别指定这两个列簇 的数据的版本数为 3 和 1

create 'user_info',{NAME=>'base_info',VERSIONS=>3 },{NAME=>'extra_info',VERSIONS=>1}

create 'user',{NAME=>'info',VERSIONS=>3 },{NAME=>'data',VERSIONS=>2}

3、查看表的详细信息:desc 和 describe

desc "user_info" 或者 describe "user_info"

4、往表中插入数据:put

向 user 表中插入信息,row key 为 rk0001,列簇 info 中添加 name 列标示符,值为 zhangsan

put 'user', 'rk0001', 'info:name', 'zhangsan'

 

向 user 表中插入信息,row key 为 rk0001,列簇 info 中添加 gender 列标示符,值为 female

put 'user', 'rk0001', 'info:gender', 'female'

 

向 user 表中插入信息,row key 为 rk0001,列簇 info 中添加 age 列标示符,值为 20

put 'user', 'rk0001', 'info:age', 20

 

向 user 表中插入信息,row key 为 rk0001,列簇 data 中添加 pic 列标示符,值为 picture

put 'user', 'rk0001', 'data:pic', 'picture'

 

再插入几条其他数据:

put 'user', 'rk0002', 'info:name', 'fanbingbing'

put 'user', 'rk0002', 'info:gender', 'female'

put 'user', 'rk0002', 'info:nationality', '中国'

 

插入一堆示例数据,以便后面测试:

put 'user_info', 'user0000', 'base_info:name', 'luoyufeng'

put 'user_info', 'user0000', 'base_info:age', '18'
put 'user_info', 'user0000', 'base_info:gender', 'female'

put 'user_info', 'user0000', 'extra_info:size', '34'

put 'user_info', 'user0001', 'base_info:name', 'zhangsan'

put 'user_info', 'user0001', 'base_info:name', 'luoyufeng'

put 'user_info', 'user0001', 'base_info:name', 'zhangsan'

 

put 'user_info', 'zhangsan_20150701_0001', 'base_info:name', 'zhangsan1'

put 'user_info', 'zhangsan_20150701_0002', 'base_info:name', 'zhangsan2'

put 'user_info', 'zhangsan_20150701_0003', 'base_info:name', 'zhangsan3'

put 'user_info', 'zhangsan_20150701_0004', 'base_info:name', 'zhangsan4'

put 'user_info', 'zhangsan_20150701_0005', 'base_info:name', 'zhangsan5'

put 'user_info', 'zhangsan_20150701_0006', 'base_info:name', 'zhangsan6'

put 'user_info', 'zhangsan_20150701_0007', 'base_info:name', 'zhangsan7'

put 'user_info', 'zhangsan_20150701_0008', 'base_info:name', 'zhangsan8'

 

put 'user_info', 'zhangsan_20150701_0001', 'base_info:age', '21'

put 'user_info', 'zhangsan_20150701_0002', 'base_info:age', '22'

put 'user_info', 'zhangsan_20150701_0003', 'base_info:age', '23'

put 'user_info', 'zhangsan_20150701_0004', 'base_info:age', '24'

put 'user_info', 'zhangsan_20150701_0005', 'base_info:age', '25'

put 'user_info', 'zhangsan_20150701_0006', 'base_info:age', '26'

put 'user_info', 'zhangsan_20150701_0007', 'base_info:age', '27'

put 'user_info', 'zhangsan_20150701_0008', 'base_info:age', '28'

 

put 'user_info', 'zhangsan_20150701_0001', 'extra_info:Hobbies', 'music'

put 'user_info', 'zhangsan_20150701_0002', 'extra_info:Hobbies', 'sport'

put 'user_info', 'zhangsan_20150701_0003', 'extra_info:Hobbies', 'music'

put 'user_info', 'zhangsan_20150701_0004', 'extra_info:Hobbies', 'sport'

put 'user_info', 'zhangsan_20150701_0005', 'extra_info:Hobbies', 'music'

put 'user_info', 'zhangsan_20150701_0006', 'extra_info:Hobbies', 'sport'

put 'user_info', 'zhangsan_20150701_0007', 'extra_info:Hobbies', 'music'

 

put 'user_info', 'baiyc_20150716_0001', 'base_info:name', 'baiyc1'

put 'user_info', 'baiyc_20150716_0002', 'base_info:name', 'baiyc2'

put 'user_info', 'baiyc_20150716_0003', 'base_info:name', 'baiyc3'

put 'user_info', 'baiyc_20150716_0004', 'base_info:name', 'baiyc4'

put 'user_info', 'baiyc_20150716_0005', 'base_info:name', 'baiyc5'

put 'user_info', 'baiyc_20150716_0006', 'base_info:name', 'baiyc6'

put 'user_info', 'baiyc_20150716_0007', 'base_info:name', 'baiyc7'

put 'user_info', 'baiyc_20150716_0008', 'base_info:name', 'baiyc8'

 

put 'user_info', 'baiyc_20150716_0001', 'base_info:age', '21'

put 'user_info', 'baiyc_20150716_0002', 'base_info:age', '22'

put 'user_info', 'baiyc_20150716_0003', 'base_info:age', '23'

put 'user_info', 'baiyc_20150716_0004', 'base_info:age', '24'

put 'user_info', 'baiyc_20150716_0005', 'base_info:age', '25'

put 'user_info', 'baiyc_20150716_0006', 'base_info:age', '26'

put 'user_info', 'baiyc_20150716_0007', 'base_info:age', '27'

put 'user_info', 'baiyc_20150716_0008', 'base_info:age', '28'

 

put 'user_info', 'baiyc_20150716_0001', 'extra_info:Hobbies', 'music'

put 'user_info', 'baiyc_20150716_0002', 'extra_info:Hobbies', 'sport'

put 'user_info', 'baiyc_20150716_0003', 'extra_info:Hobbies', 'music'

put 'user_info', 'baiyc_20150716_0004', 'extra_info:Hobbies', 'sport'

put 'user_info', 'baiyc_20150716_0005', 'extra_info:Hobbies', 'music'

put 'user_info', 'baiyc_20150716_0006', 'extra_info:Hobbies', 'sport'

put 'user_info', 'baiyc_20150716_0007', 'extra_info:Hobbies', 'music'

put 'user_info', 'baiyc_20150716_0008', 'extra_info:Hobbies', 'sport'

4、查询数据:get

获取 user 表中 row key 为 rk0001 的所有信息

get 'user', 'rk0001'

 

获取 user 表中 row key 为 rk0001,info 列簇的所有信息

get 'user', 'rk0001', 'info'

 

获取 user 表中 row key 为 rk0001,info 列簇的 name、age 列标示符的信息

get 'user', 'rk0001', 'info:name', 'info:age'

 

获取 user 表中 row key 为 rk0001,info 和 data 列簇的信息

get 'user', 'rk0001', 'info', 'data'
get 'user', 'rk0001', {COLUMN => ['info', 'data']}
get 'user', 'rk0001', {COLUMN => ['info:name', 'data:pic']}

 

获取 user 表中 row key 为 rk0001,列簇为 info,版本号最新 5 个的信息
get 'user', 'rk0001', {COLUMN => 'info', VERSIONS => 2}
get 'user', 'rk0001', {COLUMN => 'info:name', VERSIONS => 5}
get 'user', 'rk0001', {COLUMN => 'info:name', VERSIONS => 5, TIMERANGE => [1392368783980, 1392380169184]}

get 'user_info', 'user0001', {COLUMN => 'base_info:name', VERSIONS => 3}

 

获取 user 表中 row key 为 rk0001,cell 的值为 zhangsan 的信息

get 'user', 'rk0001', {FILTER => "ValueFilter(=, 'binary:图片')"}

 

获取 user 表中 row key 为 rk0001,列标示符中含有 a 的信息

get 'user', 'rk0001', {FILTER => "(QualifierFilter(=,'substring:a'))"}

5、查询数据:scan

查询 user_info 表中的所有信息

scan 'user_info'

 

查询 user_info 表中的指定列簇的所有信息
scan 'user_info', {COLUMNS => 'base_info'}
scan 'user_info', {COLUMNS => 'base_info:name'}
scan 'user_info', {COLUMNS => ['base_info', 'extra_info']}

 

查询 user_info 表中的指定列簇为 base_info 的所有版本信息
scan 'user_info', {COLUMNS => 'base_info'} #只查询最新值

scan 'user_info', {COLUMNS => 'base_info', VERSIONS => 5}

 

查询 user 表中列簇为 info 和 data 的信息
scan 'user', {COLUMNS => ['info', 'data']}
scan 'user', {COLUMNS => 'info:name'}
scan 'user', {COLUMNS => ['info:name', 'data:pic']}

 

查询 user_info 表中列簇为 base_info、列标示符为 name 的信息,并且版本最新的 5 个

scan 'user_info', {COLUMNS => 'base_info:name', VERSIONS => 5}

 

查询 user 表中列簇为 info 和 data 且列标示符中含有 a 字符的信息
scan 'user', {COLUMNS => ['info', 'data']}
scan 'user', {COLUMNS => ['info', 'data'], FILTER => "(QualifierFilter(=,'substring:a'))"}

 

查询表名为 user_info 表中列簇为 base_info,rowkey 的起始偏移范围是[baiyc_20150716_0003, baiyc_20150716_0006)的数据
scan 'user_info', {COLUMNS => 'base_info', STARTROW => 'baiyc_20150716_0003', ENDROW => 'baiyc_20150716_0006'}

 

查询 user 表中 rowkey 以 rk 字符开头的

scan 'user', {FILTER=>"PrefixFilter('rk')"}

 

查询 user_info 表中指定时间戳范围的数据
scan 'user_info', {TIMERANGE => [1540882871681,1540882888540]}

6、删除数据:delete

删除记录
delete 'user', 'rk0001' #不能一口气删除一个 rowkey 所对应的所有 key-value

 

删除字段

delete 'user', 'rk0001', 'info:name'

 

删除 user_info 表 rowkey 为 user0000,列标示符为 info:name 的数据
get 'user_info', 'user0000', 'base_info:name'
delete 'user_info', 'user0000', 'base_info:name' #实现删除,其他两句为辅助测试语句

put 'user_info', 'user0000', 'base_info:name', 'luoyufeng'

 

删除 user 表 rowkey 为 rk0001,列标示符为 info:name,timestamp 为 1392383705316 的数据

delete 'user', 'rk0001', 'info:name', 1392383705316

7、修改表结构:alter

添加两个列簇 f2 和 f3
alter 'user_info', NAME => 'f2'

alter 'user_info', NAME => 'f3'

 

删除一个列簇 f2:
alter 'user_info', NAME => 'f2', METHOD => 'delete'


alter 'user_info', 'delete' => 'f2'

 

添加列簇 f1 同时删除列簇 f3
alter 'user_info', {NAME => 'f1'}, {NAME => 'f3', METHOD => 'delete'}

 

将 user_info 表的 base_info 列簇版本号改为 5
alter 'user_info', NAME => 'base_info', VERSIONS => 5

8、修改数据

严格来说,HBase 没有修改数据的显示操作,重复插入就相当于是修改操作

9、清空表:truncate

truncate 'user' #清空 user 表中的数据

10、停用表/启用表:disable 和 enable

disable 'user' #首先停用 user 表

enable 'user' #启用表

11、删除表

disable 'user'  #删除前,先停用表

drop 'user' #停用表之后才能删除

12、过滤器操作

过滤器
get 'user', 'rk0001', {FILTER => "ValueFilter(=, 'binary:中国')"}

get 'user', 'rk0001', {FILTER => "(QualifierFilter(=,'substring:a'))"}

 

scan 'user', {COLUMNS => 'info:name'}

scan 'user', {COLUMNS => ['info', 'data'], FILTER => "(QualifierFilter(=,'substring:a'))"}
scan 'user', {COLUMNS => 'info', STARTROW => 'rk0001', ENDROW => 'rk0003'}
scan 'user', {COLUMNS => 'info', STARTROW => '20140201', ENDROW => '20140301'}
scan 'user', {COLUMNS => 'info:name', TIMERANGE => [1395978233636, 1395987769587]}

6、HBase Java API 代码开发

几个主要HBase API类和数据模型之间的对应关系:

java类 HBase数据模型
HBaseAdmin 数据库(DataBase)
HBaseConfiguration
HTable 表(Table)
HTableDescriptor 列簇(Column Family)
HColumnDescriptor
Put 列修饰符(Column Qualifier)
Get
Delete
Result
Scan
ResultScanner

1、HBaseAdmin

关系:org.apache.hadoop.hbase.client.HBaseAdmin
作用:提供了一个接口来管理 HBase 数据库的表信息。它提供的方法包括:创建表,删除表, 列出表项,使表有效或无效,以及添加或删除表列簇成员等。

void addColumn(String tableName, HColumnDescriptor column) #向一个已经存在的表添加列

 

void checkHBaseAvailable(HBaseConfiguratio n conf) #静态函数,查看 HBase是否处于运行状态

 

void createTable(HTableDescriptor desc) #创建一个表,同步操作

 

void deleteTable(byte[] tableName) #删除一个已经存在的表

 

void enableTable(byte[] tableName) #使表处于有效状态

 

void disableTable(byte[] tableName) #使表处于无效状态

 

HTableDescriptor[] listTables() #列出所有用户空间表项

 

void modifyTable(byte[] tableName, HTableDescriptor htd) #修改表的模式,是异步的 操作,可能需要花费一定 的时间

 

boolean tableExists(String tableName) #检查表是否存在

 

用法示例:

HBaseAdmin admin = new HBaseAdmin(config);

admin.disableTable("tablename")

2、HBaseConfiguration

关系:org.apache.hadoop.hbase.HBaseConfiguration

作用:对 HBase 进行配置

void addResource(Path file) #通过给定的路径所指的文件来添加资源

 

void clear() #清空所有已设置的属性

 

String get(String name) #获取属性名对应的值 

 

String getBoolean(String name, boolean defaultValue) #获取为 boolean 类型的属性值,如果其属 性值类型部位 boolean,则返回默认属性值

 

void set(String name, String value) #通过属性名来设置值

 

void setBoolean(String name, boolean value) #设置 boolean 类型的属性值

 

用法示例:

HBaseConfiguration hconfig = new HBaseConfiguration();

hconfig.set("hbase.zookeeper.property.clientPort","2181");

该 方 法 设 置 了 "hbase.zookeeper.property.clientPort" 的 端 口 号 为 2181 。 一 般 情 况 下 ,HBaseConfiguration 会使用构造函数进行初始化,然后在使用其他方法。

3、HTableDescriptor

关系:org.apache.hadoop.hbase.HTableDescriptor

作用:包含了表的名字极其对应表的列簇

void addFamily(HColumnDescriptor) #添加一个列簇

 

HColumnDescriptor removeFamily(byte[] column) #移除一个列簇

 

byte[] getName() #获取表的名字

 

byte[] getValue(byte[] key) #获取属性的值

 

void setValue(String key, String value) #设置属性的值

 

用法示例:

HTableDescriptor htd = new HTableDescriptor(table);

htd.addFamily(new HcolumnDescriptor("family"));

在上述例子中,通过一个 HColumnDescriptor 实例,为 HTableDescriptor 添加了一个列簇:family

4、HColumnDescriptor

关系:org.apache.hadoop.hbase.HColumnDescriptor

作用:维护着关于列簇的信息,例如版本号,压缩设置等。它通常在创建表或者为表添加列簇的时候使用。列簇被创建后不能直接修改,只能通过删除然后重新创建的方式。列簇被删除的时候,列簇里面的数据也会同时被删除。

byte[] getName() #获取列簇的名字

 

byte[] getValue(byte[] key) #获取对应的属性的值

 

void setValue(String key, String value) #设置对应属性的值

 

用法示例:

HTableDescriptor htd = new HTableDescriptor(tablename);

HColumnDescriptor col = new HColumnDescriptor("content:");

htd.addFamily(col);

此例添加了一个 content 的列簇

5、HTable

关系:org.apache.hadoop.hbase.client.HTable
作用:可以用来和 HBase 表直接通信。此方法对于更新操作来说是非线程安全的。

void checkAdnPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put) #自动的检查row/family/qualifier 是否与给定的值匹配

 

void close() #释放所有的资源或挂起内部缓冲区中的更新

 

Boolean exists(Get get) #检查 Get 实例所指定的值是否存在于 HTable 的列中

 

Result get(Get get) #获取指定行的某些单元格所对 应的值

 

byte[][] getEndKeys() #获取当前一打开的表每个区域的结束键值

 

ResultScanner getScanner(byte[] family) #获取当前给定列簇的 scanner实例

 

HTableDescriptor getTableDescriptor() #获取当前表的HTableDescriptor 实例

 

byte[] getTableName() #获取表名

 

static boolean isTableEnabled(HBaseConfiguration conf, String tableName) #检查表是否有效

 

void put(Put put) #向表中添加值

 

用法示例:

HTable table = new HTable(conf, Bytes.toBytes(tablename));

ResultScanner scanner = table.getScanner(family);

6、Put

关系:org.apache.hadoop.hbase.client.Put

作用:用来对单个行执行添加操作

Put add(byte[] family, byte[] qualifier, byte[] value) #将指定的列和对应的值添加到Put 实例中

 

Put add(byte[] family, byte[] qualifier, long ts, byte[] value) #将指定的列和对应的值及时间 戳添加到 Put 实例中

 

byte[] getRow() #获取 Put 实例的行

 

RowLock getRowLock() #获取 Put 实例的行锁

 

long getTimeStamp() #获取 Put 实例的时间戳

 

boolean isEmpty() #检查 familyMap 是否为空

 

Put setTimeStamp(long timeStamp) #设置 Put 实例的时间戳

 

用法示例:

HTable table = new HTable(conf,Bytes.toBytes(tablename));

Put p = new Put(brow);//为指定行创建一个 Put 操作

p.add(family,qualifier,value);
table.put(p);

7、Get

关系:org.apache.hadoop.hbase.client.Get

作用:用来获取单个行的相关信息

Get addColumn(byte[] family, byte[] qualifier) #获取指定列簇和列修饰符对应的列

 

Get addFamily(byte[] family) #通过指定的列簇获取其对应的所有列

 

Get setTimeRange(long minStamp,long maxStamp) #获取指定取件的列的版本号

 

Get setFilter(Filter filter) #当执行 Get 操作时设置服务器端的过滤器

 

用法示例:

HTable table = new HTable(conf, Bytes.toBytes(tablename));

Get g = new Get(Bytes.toBytes(row));

8、Delete

关系:org.apache.hadoop.hbase.client.Delete

作用:用来封装一个要删除的信息

9、Scan

关系:org.apache.hadoop.hbase.client.Scan

作用:用来封装一个作为查询条件的信息

10、Result

关系:org.apache.hadoop.hbase.client.Result
作用:存储 Get 或者 Scan 操作后获取表的单行值。使用此类提供的方法可以直接获取值或者各种 Map 结构(key-value 对)

boolean containsColumn(byte[] family, byte[] qualifier) #检查指定的列是否存在

 

NavigableMap getFamilyMap(byte[] family) #获取对应列簇所包含的修 饰符与值的键值对

 

byte[] getValue(byte[] family, byte[] qualifier) #获取对应列的最新值

11、ResultScanner

关系:org.apache.hadoop.hbase.client.ResultScanner

作用:存储 Scan 操作后获取表的单行值

6.1、基本增删改查实现

查看hbase-01中的资料!操作要认真写一遍。

6.2、过滤器查询

过滤器的类型很多,但是可以分为两大类——比较过滤器,专用过滤器。过滤器的作用是在服务端判断数据是否满足条件,然后只将满足条件的数据返回给客户端;

hbase 过滤器的比较运算符:

LESS <

LESS_OR_EQUAL <=

EQUAL =
NOT_EQUAL <>

GREATER_OR_EQUAL >=

GREATER >
NO_OP 排除所有

HBase 过滤器的比较器(指定比较机制):

BinaryComparator 按字节索引顺序比较指定字节数组,采用 Bytes.compareTo(byte[])

BinaryPrefixComparator 跟前面相同,只是比较左端的数据是否相同
NullComparator 判断给定的是否为空
BitComparator 按位比较

RegexStringComparator 提供一个正则的比较器,仅支持 EQUAL 和非 EQUAL

SubstringComparator 判断提供的子串是否出现在 value 中。

比较过滤器:

行键过滤器 RowFilter

Filter filter1 = new RowFilter(CompareOp.LESS_OR_EQUAL, new BinaryComparator(Bytes.toBytes("user0000")));
scan.setFilter(filter1);

 

列簇过滤器 FamilyFilter

Filter filter1 = new FamilyFilter(CompareOp.LESS, new BinaryComparator(Bytes.toBytes("base_info")));
scan.setFilter(filter1);

 

列过滤器 QualifierFilter

Filter filter = new QualifierFilter(CompareOp.LESS_OR_EQUAL, new BinaryComparator(Bytes.toBytes("name")));
scan.setFilter(filter1);

 

值过滤器 ValueFilter

Filter filter = new ValueFilter(CompareOp.EQUAL, new SubstringComparator("zhangsan") );

scan.setFilter(filter1);

 

时间戳过滤器 TimestampsFilter

List tss = new ArrayList();

tss.add(1495398833002l);
Filter filter1 = new TimestampsFilter(tss);

scan.setFilter(filter1);

专用过滤器:

单列值过滤器 SingleColumnValueFilter----会返回满足条件的整行

SingleColumnValueFilter filter = new SingleColumnValueFilter( Bytes.toBytes("colfam1"),Bytes.toBytes("col-5"), CompareFilter.CompareOp.NOT_EQUAL, new SubstringComparator("val-5"));

filter.setFilterIfMissing(true); //如果不设置为 true,则那些不包含指定 column 的行也会返回

scan.setFilter(filter1);

 

单列值排除器 SingleColumnValueExcludeFilter -----返回排除了该列的结果与上面的结果相反

 

前缀过滤器 PrefixFilter----针对行键

Filter filter = new PrefixFilter(Bytes.toBytes("row1"));

scan.setFilter(filter1);

 

列前缀过滤器 ColumnPrefixFilter

Filter filter = new ColumnPrefixFilter(Bytes.toBytes("qual2"));

scan.setFilter(filter1);

 

分页过滤器 PageFilter

查看hbase-01中的资料!操作要认真写一遍。

你可能感兴趣的:(HBase)