hbase简单使用(一篇文章入门Hbase)(1)

1.HBase

HBase是hadoop Database的简称,是建立在Hadoop文件系统之上的分布式面向列的数据库,为横向发展类型数据库,提供快速随机访问海量结构化数据,它是Hadoop生态系统,提供对数据的随机实时读/写访问,是Hadoop文件系统的一部分,利用了Hadoop的文件系统(HDFS)提供的容错能力。

HBase是分布式、面向列族的开源数据库,HDFS为HBase提供可靠的底层数据存储服务,MapReduce为HBase提供高性能的计算能力,Zookeeper为HBase提供稳定服务和Failover机制,可以说,HBase是一个通过大量廉价的机器解决海量数据的高速存储和读取的分布式数据库解决方案。

人们可以直接或通过HBase的存储HDFS数据。使用HBase在HDFS读取消费/随机访问数据。HBase在Hadoop的文件系统之上,并提供了读写访问。

hbase简单使用(一篇文章入门Hbase)(2)

1.1 HBase和HDFS

HDFS适用于存储大容量文件的分布式文件系统,不支持快速单独记录查找,提供了高延迟批量处理,但是没有批处理的概念;提供的数据只能够顺序访问;

HBase是建立在HDFS之上的数据库,提供在较大的表快速查找,提供了数十亿记录低延迟访问单个行记录(随机存储),HBase内部使用哈希表和提供随机接入,并且其存储索引,可以将在HDFS文件中的数据进行快速查找。

1.2 HBase存储机制

HBase是一个面向列的数据库,在表中它由行排序。表模式定义只能列族,也就是键值对。一个表有多个列族以及每一个列族可以有任意数量的列。后续列的值连续地存储在磁盘上。表中的每个单元格值都具有时间戳。总之,在一个HBase: - 表是行的集合。 - 行是列族的集合。 - 列族是列的集合。 - 列是键值对的集合。

下面给出的表中是HBase模式的一个例子。

1.3 面向行和面向列

1.3.1 OLTP和OLAP

当今的数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing)、联机分析处理OLAP(On-Line Analytical Processing)。OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果.

1.3.1.1 OLTP

也称为面向交易的处理系统,其基本特征是顾客的原始数据可以立即传送到计算中心进行处理,并在很短的时间内给出处理结果。

这样做的最大优点是可以即时地处理输入的数据,及时地回答。也称为实时系统(Real time System)。衡量联机事务处理系统的一个重要性能指标是系统性能,具体体现为实时响应时间(Response Time),即用户在终端上送入数据之后,到计算机对这个请求给出答复所需要的时间。OLTP是由数据库引擎负责完成的。

OLTP 数据库旨在使事务应用程序仅写入所需的数据,以便尽快处理单个事务。

1.3.1.2 OLAP

随着数据库技术的发展和应用,数据库存储的数据量从20世纪80年代的兆(M)字节及千兆(G)字节过渡到现在的兆兆(T)字节和千兆兆(P)字节,同时,用户的查询需求也越来越复杂,涉及的已不仅是查询或操纵一张关系表中的一条或几条记录,而且要对多张表中千万条记录的数据进行数据分析和信息综合,关系数据库系统已不能全部满足这一要求。在国外,不少软件厂商采取了发展其前端产品来弥补关系数据库管理系统支持的不足,力图统一分散的公共应用逻辑,在短时间内响应非数据处理专业人员的复杂查询要求。

联机分析处理(OLAP)系统是数据仓库系统最主要的应用,专门设计用于支持复杂的分析操作,侧重对决策人员和高层管理人员的决策支持,可以根据分析人员的要求快速、灵活地进行大数据量的复杂查询处理,并且以一种直观而易懂的形式将查询结果提供给决策人员,以便他们准确掌握企业(公司)的经营状况,了解对象的需求,制定正确的方案。

1.3.2 面向行数据库和面向列数据库特点

面向行的数据库适用于联机事务处理(OLTP),这样的数据库被设计为小数目的行和列。

面向列的数据库适用于在线分析处理(OLAP),可以设计为巨大表。

下面显示了列族在面向列的数据库:

1.3.3 名词概念

1.3.3.1 Rowkey的概念

Rowkey的概念和mysql中的主键是完全一样的,Hbase使用Rowkey来唯一的区分某一行的数据。Hbase只支持3种查询方式: - 1、基于Rowkey的单行查询 - 2、基于Rowkey的范围扫描 - 3、全表扫描

因此,Rowkey对Hbase的性能影响非常大,Rowkey的设计就显得尤为的重要。设计的时候要兼顾基于Rowkey的单行查询也要键入Rowkey的范围扫描。

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

1.3.3.2 Column的概念

列,可理解成MySQL列。

1.3.3.3 ColumnFamily的概念

Hbase通过列族划分数据的存储,列族下面可以包含任意多的列,实现灵活的数据存取。列族是由一个一个的列组成(任意多)。

Hbase表的创建的时候就必须指定列族。就像关系型数据库创建的时候必须指定具体的列是一样的。

Hbase的列族不是越多越好,官方推荐的是列族最好小于或者等于3。我们使用的场景一般是1个列族。

1.3.3.4 TimeStamp的概念

TimeStamp对Hbase来说至关重要,因为它是实现Hbase多版本的关键。在Hbase中使用不同的timestame来标识相同rowkey行对应的不通版本的数据。

在写入数据的时候,如果用户没有指定相应的timestamp,HBase会自动添加一个timestamp,timestamp和服务器时间保持一致。

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

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

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

1.3.3.5 单元格(Cell)

由{rowkey, column( = ),version}唯一确定的单元。 Cell 中的数据是没有类型的,全部是字节码形式存贮。

1.3.3.6 Region

Region的概念和关系型数据库的分区或者分片差不多。

Hbase会将一个大表的数据基于Rowkey的不同范围分配到不通的Region中,每个Region负责一定范围的数据访问和存储。这样即使是一张巨大的表,由于被切割到不通的region,访问起来的时延也很低。

1.4 HBase特点

1.4.1 数据库要点

1)介于NoSQL和RDBMS之间,仅能通过主键(rowkey)和主键的range来检索数据;

2)HBase查询数据功能很简单,不支持join等复杂操作;

3)不支持复杂事务,只支持行级事务(可通过hive支持来实现多表join等复杂操作)

4)HBase中支持的数据类型:byte

5)主要用来存储结构化和半结构化的松散数据;

1.4.2 结构化、半结构化和非结构化

结构化:数据结构字段含义确定,清晰,典型的如数据库中的表结构

半结构化:具有一定结构,但语义不够确定,典型的如 HTML 网页,有些字段是确定的(title),有些不确定(table)

非结构化:杂乱无章的数据,很难按照一个概念去进行抽取,无规律性。

与 Hadoop 一样,HBase目标主要依靠横向扩展,通过不断增加廉价的商用服务器,来增加计算和存储能力。

1.4.3 HBase中的表特点

1、大:一个表可以有上十亿行,上百万列

2、面向列:面向列(族)的存储和权限控制,列(簇)独立检索。

3、稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。

4、无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列。

1.4.4 HBase特点

1.4.4.1 海量存储

Hbase适合存储PB级别的海量数据,在PB级别的数据以及采用廉价PC存储的情况下,能在几十到百毫秒内返回数据。这与Hbase的极易扩展性息息相关。正式因为Hbase良好的扩展性,才为海量数据的存储提供了便利。

1.4.4.2 列式存储

这里的列式存储其实说的是列族存储,Hbase是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定。

RDBMS:

hbase简单使用(一篇文章入门Hbase)(3)

Hbase的表:

hbase简单使用(一篇文章入门Hbase)(4)

RDBMS和HBase区别:

hbase简单使用(一篇文章入门Hbase)(5)

1.4.4.3 极易扩展

Hbase的扩展性主要体现在两个方面,一个是基于上层处理能力(RegionServer)的扩展,一个是基于存储的扩展(HDFS)。

通过横向添加RegionSever的机器,进行水平扩展,提升Hbase上层的处理能力,提升Hbsae服务更多Region的能力。

备注:RegionServer的作用是管理region、承接业务的访问。

通过横向添加Datanode的机器,进行存储层扩容,提升Hbase的数据存储能力和提升后端存储的读写能力。

1.4.4.4 高并发

由于目前大部分使用Hbase的架构,都是采用的廉价PC,因此单个IO的延迟其实并不小,一般在几十到上百ms之间。这里说的高并发,主要是在并发的情况下,Hbase的单个IO延迟下降并不多。能获得高并发、低延迟的服务。

1.4.4.5 稀疏

稀疏主要是针对Hbase列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间的。

1.5 使用场景

HBase适用于海量数据存储和准实时查询。HBase能够应用在上百亿行*上百万列,实现百毫秒的查询;

HBase只有当数据量非常大的时候,才能发挥其良好的性能,如果只是百万或者千万数据,完全可以使用MySQL的分库分表实现。但是关系型数据库的字段列数需要在30以内,否则就是表的设计有问题。

查询简单(基于rowkey或者rowkey查询范围)、不涉及复杂关联的环境,如:交通(红绿灯信息采集)、海量订单流水数据(长久保存)、交易记录、数据库历史数据。

2.HBase架构

在HBase中,表被分割成区域,并由区域服务器提供服务。区域被列族垂直分为“Stores”。Stores被保存在HDFS文件。下面显示的是HBase的结构。注意:术语“store”是用于区域来解释存储结构。 - 依赖于HDFS做底层的数据存储 - 依赖于MapReduce做数据计算 - 依赖于ZooKeeper做服务协调

HBase有三个主要组成部分:客户端库,主服务器和区域服务器。区域服务器可以按要求添加或删除。

2.1 主服务器

主服务器用于: - 分配区域给区域服务器并在Apache ZooKeeper的帮助下完成这个任务。 - 处理跨区域的服务器区域的负载均衡。它卸载繁忙的服务器和转移区域较少占用的服务器。 - 通过判定负载均衡以维护集群的状态。 - 负责模式变化和其他元数据操作,如创建表和列。

2.2 区域

区域只不过是表被拆分,并分布在区域服务器。

2.3 区域服务器

区域服务器拥有区域如下: - 与客户端进行通信并处理数据相关的操作。 - 句柄读写的所有地区的请求。 - 由以下的区域大小的阈值决定的区域的大小。

需要深入探讨区域服务器:包含区域和存储,如下图所示:

存储包含内存存储和HFiles。memstore就像一个高速缓存。在这里开始进入了HBase存储。数据被传送并保存在Hfiles作为块并且memstore刷新。

2.4 Zookeeper

3.常用命令

3.1 HBase Shell命令

3.1.1 通用命令

3.1.2 数据定义语言

这些是关于HBase在表中操作的命令。 - create: 创建一个表。 - list: 列出HBase的所有表。 - disable: 禁用表。 - is_disabled: 验证表是否被禁用。 - enable: 启用一个表。 - is_enabled: 验证表是否已启用。 - describe: 提供了一个表的描述。 - alter: 改变一个表。 - exists: 验证表是否存在。 - drop: 从HBase中删除表。 - drop_all: 丢弃在命令中给出匹配“regex”的表。

Java Admin API: 在此之前所有的上述命令,Java提供了一个通过API编程来管理实现DDL功能。在这个org.apache.hadoop.hbase.client包中有HBaseAdmin和HTableDescriptor这两个重要的类提供DDL功能。

3.1.3 数据操纵语言

Java client API: 在此之前所有上述命令,Java提供了一个客户端API来实现DML功能,CRUD(创建检索更新删除)操作更多的是通过编程,在org.apache.hadoop.hbase.client包下。 在此包HTable的Put和Get是重要的类。

3.1.3.1 进入HBase命令行

在你安装的随意台服务器节点上,执行命令:hbase shell,会进入到你的hbase shell客户端

[hadoop@hadoop1 ~]$ hbase shell ...... hbase(main):001:0>

其中:

HBase Shell; enter 'help<RETURN>' for list of supported commands. Type "exit<RETURN>" to leave the HBase Shell

讲述了怎么获得帮助,怎么退出客户端。

help获取帮助 - help:获取所有命令提示 - help "dml" :获取一组命令的提示 - help "put" :获取一个单独命令的提示帮助

exit:退出 hbase shell 客户端

3.1.3.2 HBase表的操作

关于表的操作包括(创建create,查看表列表list。查看表的详细信息desc,删除表drop,清空表truncate,修改表的定义alter)

3.1.3.2.1 创建create

可以输入以下命令进行查看帮助命令

hbase(main):001:0> help 'create' ...... hbase> create 't1', {NAME => 'f1'}, {NAME => 'f2'}, {NAME => 'f3'} ......

其中t1是表名,f1,f2,f3是列簇的名,如:

hbase(main):002:0> create 'myHbase',{NAME => 'myCard',VERSIONS => 5} 0 row(s) in 3.1270 seconds => Hbase::Table - myHbase hbase(main):003:0>

创建了一个名为myHbase的表,表里面有1个列簇,名为myCard,保留5个版本信息

3.1.3.2.2 查看表列表list

可以输入以下命令进行查看帮助命令

hbase(main):003:0> help 'list' List all tables in hbase. Optional regular expression parameter could be used to filter the output. Examples: hbase> list hbase> list 'abc.*' hbase> list 'ns:abc.*' hbase> list 'ns:.*' hbase(main):004:0>

直接输入list进行查看

hbase(main):004:0> list TABLE myHbase 1 row(s) in 0.0650 seconds => ["myHbase"] hbase(main):005:0>

只有一条结果,就是刚刚创建的表myHbase

3.1.3.2.3 查看表的详细信息desc

一个大括号,就相当于一个列簇。

hbase(main):006:0> desc 'myHbase' Table myHbase is ENABLED myHbase COLUMN FAMILIES DESCRIPTION {NAME => 'myCard', BLOOMFILTER => 'ROW', VERSIONS => '5', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', D ATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true' , BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'} 1 row(s) in 0.2160 seconds hbase(main):007:0>

3.1.3.2.4 修改表的定义alter

3.1.3.2.4.1 添加一个列簇

hbase(main):007:0> alter 'myHbase', NAME => 'myInfo' Updating all regions with the new schema... 1/1 regions updated. Done. row(s) in 2.0690 seconds hbase(main):008:0> desc 'myHbase' Table myHbase is ENABLED myHbase COLUMN FAMILIES DESCRIPTION {NAME => 'myCard', BLOOMFILTER => 'ROW', VERSIONS => '5', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', D ATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true' , BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'} {NAME => 'myInfo', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', D ATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true' , BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'} row(s) in 0.0420 seconds hbase(main):009:0>

3.1.3.2.4.2 删除一个列簇

hbase(main):009:0> alter 'myHbase', NAME => 'myCard', METHOD => 'delete' Updating all regions with the new schema... 1/1 regions updated. Done. row(s) in 2.1920 seconds hbase(main):010:0> desc 'myHbase' Table myHbase is ENABLED myHbase COLUMN FAMILIES DESCRIPTION {NAME => 'myInfo', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', D ATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true' , BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'} row(s) in 0.0290 seconds hbase(main):011:0>

删除一个列簇也可以执行以下命令

alter 'myHbase', 'delete' => 'myCard'

3.1.3.2.4.3 添加列簇hehe同时删除列簇myInfo

hbase(main):011:0> alter 'myHbase', {NAME => 'hehe'}, {NAME => 'myInfo', METHOD => 'delete'} Updating all regions with the new schema... 1/1 regions updated. Done. Updating all regions with the new schema... 1/1 regions updated. Done. 0 row(s) in 3.8260 seconds hbase(main):012:0> desc 'myHbase' Table myHbase is ENABLED myHbase COLUMN FAMILIES DESCRIPTION {NAME => 'hehe', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DAT A_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'} 1 row(s) in 0.0410 seconds hbase(main):013:0>

1.3.2.4.4 清空表truncate

hbase(main):013:0> truncate 'myHbase' Truncating 'myHbase' table (it may take a while): - Disabling table... - Truncating table... 0 row(s) in 3.6760 seconds hbase(main):014:0>

3.1.3.2.4.5 删除表drop

hbase(main):014:0> drop 'myHbase' ERROR: Table myHbase is enabled. Disable it first. Here is some help for this command: Drop the named table. Table must first be disabled: hbase> drop 't1' hbase> drop 'ns1:t1' hbase(main):015:0>

直接删除表会报错,根据提示需要先停用表

hbase(main):015:0> disable 'myHbase' 0 row(s) in 2.2620 seconds hbase(main):016:0> drop 'myHbase' 0 row(s) in 1.2970 seconds hbase(main):017:0> list TABLE 0 row(s) in 0.0110 seconds => [] hbase(main):018:0>

3.1.3.2.5 HBase表中数据的操作

关于数据的操作(增put,删delete,查get scan, 改==变相的增加)

创建 user 表,包含 info、data 两个列簇

hbase(main):018:0> create 'user_info',{NAME=>'base_info',VERSIONS=>3 },{NAME=>'extra_info',VERSIONS=>1 } 0 row(s) in 4.2670 seconds => Hbase::Table - user_info hbase(main):019:0>

3.1.3.2.5.1 增put

查看帮助,需要传入表名,rowkey,列簇名、值等

hbase(main):019:0> help 'put' Put a cell 'value' at specified table/row/column and optionally timestamp coordinates. To put a cell value into table 'ns1:t1' or 't1' at row 'r1' under column 'c1' marked with the time 'ts1', do: hbase> put 'ns1:t1', 'r1', 'c1', 'value' hbase> put 't1', 'r1', 'c1', 'value' hbase> put 't1', 'r1', 'c1', 'value', ts1 hbase> put 't1', 'r1', 'c1', 'value', {ATTRIBUTES=>{'mykey'=>'myvalue'}} hbase> put 't1', 'r1', 'c1', 'value', ts1, {ATTRIBUTES=>{'mykey'=>'myvalue'}} hbase> put 't1', 'r1', 'c1', 'value', ts1, {VISIBILITY=>'PRIVATE|SECRET'} The same commands also can be run on a table reference. Suppose you had a reference t to table 't1', the corresponding command would be: hbase> t.put 'r1', 'c1', 'value', ts1, {ATTRIBUTES=>{'mykey'=>'myvalue'}} hbase(main):020:0>

向 user 表中插入信息,row key 为 user0001,列簇 base_info 中添加 name 列标示符,值为 zhangsan1

hbase(main):020:0> put 'user_info', 'user0001', 'base_info:name', 'zhangsan1' 0 row(s) in 0.2900 seconds hbase(main):021:0>

3.1.3.2.5.2 查get scan

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

hbase(main):022:0> get 'user_info', 'user0001' COLUMN CELL base_info:name timestamp=1522320801670, value=zhangsan1 1 row(s) in 0.1310 seconds hbase(main):023:0>

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

hbase(main):025:0> get 'user_info', 'rk0001', 'base_info' COLUMN CELL base_info:name timestamp=1522321247732, value=zhangsan 1 row(s) in 0.0320 seconds hbase(main):026:0>

查询user_info表中的所有信息

hbase(main):026:0> scan 'user_info' ROW COLUMN CELL rk0001 column=base_info:name, timestamp=1522321247732, value=zhangsan user0001 column=base_info:name, timestamp=1522320801670, value=zhangsan1 2 row(s) in 0.0970 seconds hbase(main):027:0>

查询user_info表中列簇为base_info的信息

hbase(main):027:0> scan 'user_info', {COLUMNS => 'base_info'} ROW COLUMN CELL rk0001 column=base_info:name, timestamp=1522321247732, value=zhangsan user0001 column=base_info:name, timestamp=1522320801670, value=zhangsan1 2 row(s) in 0.0620 seconds hbase(main):028:0>

3.1.3.2.5.3 删delete

删除user_info表row key为rk0001,列标示符为base_info:name的数据

hbase(main):028:0> delete 'user_info', 'rk0001', 'base_info:name' 0 row(s) in 0.0780 seconds hbase(main):029:0> scan 'user_info', {COLUMNS => 'base_info'} ROW COLUMN CELL user0001 column=base_info:name, timestamp=1522320801670, value=zhangsan1 1 row(s) in 0.0530 seconds hbase(main):030:0>

3.2 常用命令

3.2.1 status

命令返回包括在系统上运行的服务器的细节和系统的状态。它的语法如下

hbase(main):009:0> status 3 servers, 0 dead, 1.3333 average load

3.2.2 version

该命令返回HBase系统使用的版本。它的语法如下

hbase(main):009:0> version 0.98.8-hadoop2, r6cfc8d064754251365e070a10a82eb169956d5fe, Fri Nov 14 18:26:29 PST 2014

3.2.3 table_help

此命令将引导如何使用表引用的命令。当使用此命令时,它显示帮助主题表相关的命令。下面给出是此命令的部分输出。

hbase(main):002:0> table_help Help for table-reference commands. You can either create a table via 'create' and then manipulate the table via commands like 'put', 'get', etc. See the standard help information for how to use each of these commands. However, as of 0.96, you can also get a reference to a table, on which you can invoke commands. For instance, you can get create a table and keep around a reference to it via: hbase> t = create 't', 'cf'…...

3.2.4 whoami

该命令返回HBase用户详细信息。如果执行这个命令,返回当前HBase用户

hbase(main):008:0> whoami hadoop (auth:SIMPLE) groups: hadoop

hbase简单使用(一篇文章入门Hbase)(6)

hbase简单使用(一篇文章入门Hbase)(7)

,