HBASE
第 1 章NoSQL简介
1.1 关系型数据库的查询瓶颈
当用户表的数据达到几千万甚至几亿级别的时候,对单条数据的检索将花费数秒甚至达到分钟级别。实际情况更复杂,查询的操作速度将会受到以下两个因素的影响:
①高并发的更新(插入、修改、删除)操作。大中型网站的并发操作一般能达到几十乃至几百并发,此时单条数据查询的延时将轻而易举地达到分钟级别。
②多表关联后的复杂查询,以及频繁的group by或者order by操作,此时,性能下降较为明显。
1.2 CAP定理
分摊读写压力的有效方式是将单个关系型数据库扩展为分布式数据库。但是,随之而来的问题则是很难保证原子性。没有了原子性,事务也无从谈起,关系型数据库也就没有了存在的意义。
为了保证原子性,则需要增加很多额外的必要操作,此时一次写操作的性能却面临大幅下降了。
20世纪90年代初期Berkerly大学有位Eric Brewer教授提出了一个CAP理论。全称是Consistency Availability and Partition tolerance。
- Consistency(强一致性):数据更新操作的一致性,所有数据变动都是同步的。
- Availability(高可用性):良好的响应性能。
- Partition tolerance(高分区容错性):可靠性。
Brewer教授给出的定理是:任何分布式系统只可同时满足二点,没法三者兼顾。
Brewer教授给出的忠告是:架构师不要将精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍。所以专家们始终没有办法构建出一个既有完美原子性又兼具高性能的分布式数据库。
1.3. NoSQL
有些数据库在实现性能的同时会牺牲一部分一致性,即数据在更新时,不会立刻同步,而是经过了一段时间才达到一致性。这个特性也称之为最终一致性!例如你发了一条朋友圈,你的一部分朋友立马看到了这条信息,而另一部分朋友可能要等到1分钟之后才能刷出这条消息。虽然有延时,但是对于这样一个社交的场景,这个延时是可以容忍的。而如果使用传统关系型数据库,可能这些即时通信软件就早已崩溃!
NoSQL数据库最初指不使用SQL标准的数据库,现在泛指非关系型数据库。NoSQL一词最早出现于1998年,是Carlo Strozzi开发的一个轻量、开源、不提供SQL功能的数据库。
现在NoSQL被普遍理解理解为“Not Only SQL”,意为不仅仅是SQL。NoSQL和传统的关系型数据库在很多场景下是相辅相成的,谁也不能完全替代谁。
第 2 章 HBase简介
2.1 Hbase的来源
2006年Google技术人员Fay Chang发布了一篇文章Bigtable: ADistributed Storage System for Structured Data。该文章向世人介绍了一种分布式的数据库,这种数据库可以在局部几台服务器崩溃的情况下继续提供高性能的服务。
2007年Powerset公司的工作人员基于此文研发了BigTable的Java开源版本,即HBase。刚开始它只是Hadoop的一部分。
2008年HBase成为了Apache的顶级项目。HBase几乎实现了BigTable的所有特性。它被称为一个开源的非关系型分布式数据库。
2010年HBase的开发速度打破了一直以来跟Hadoop版本一致的惯例,因为HBase的版本发布速度已经超越了Hadoop。它的版本号一下从0.20.x跳跃到了0.89.x。其Logo也进行了更换!
2.2 HBase定义
HBase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库。
Hbase面向列存储,构建于Hadoop之上,类似于Google的BigTable,提供对10亿级别表数据的快速随机实时读写!
2.3 Hbase的特点
2.3.1 HBase的特点
1)海量存储
HBase适合存储PB级别的海量数据,在PB级别的数据以及采用廉价PC存储的情况下,能在几十到百毫秒内返回数据。这与HBase的极易扩展性息息相关。正式因为HBase良好的扩展性,才为海量数据的存储提供了便利。
2)列式存储
这里的列式存储其实说的是列族存储,HBase是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定。
3)极易扩展
HBase的扩展性主要体现在两个方面,一个是基于上层处理能力(RegionServer)的扩展,一个是基于存储的扩展(HDFS)。
通过横向添加RegionSever的机器,进行水平扩展,提升HBase上层的处理能力,提升Hbsae服务更多Region的能力。
4)高并发
由于目前大部分使用HBase的架构,都是采用的廉价PC,因此单个IO的延迟其实并不小,一般在几十到上百ms之间。这里说的高并发,主要是在并发的情况下,HBase的单个IO延迟下降并不多。能获得高并发、低延迟的服务。
5)稀疏
稀疏主要是针对HBase列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间的。
2.3.2 Hbase的优点
①HDFS有高容错,高扩展的特点,而Hbase基于HDFS实现数据的存储,因此Hbase拥有与生俱来的超强的扩展性和吞吐量。
②HBase采用的是Key/Value的存储方式,这意味着,即便面临海量数据的增长,也几乎不会导致查询性能下降。
③HBase是一个列式数据库,相对于于传统的行式数据库而言。当你的单张表字段很多的时候,可以将相同的列(以regin为单位)存在到不同的服务实例上,分散负载压力。
2.3.3 Hbase的缺点
①架构设计复杂,且使用HDFS作为分布式存储,因此只是存储少量数据,它也不会很快。在大数据量时,它慢的不会很明显!
②Hbase不支持表的关联操作,因此数据分析是HBase的弱项。常见的 group by或order by只能通过编写MapReduce来实现!
③Hbase部分支持了ACID
2.3.4 Hbase的总结
适合场景:单表超千万,上亿,且高并发!
不适合场景:主要需求是数据分析,比如做报表。数据量规模不大,对实时性要求高!
2.4 HBase数据模型
逻辑上,HBase的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列。但从HBase的底层物理存储结构(K-V)来看,HBase更像是一个multi-dimensional map。
2.4.1 HBase逻辑结构
2.4.2 HBase物理存储结构
2.4.3 数据模型
1)Name Space
命名空间,类似于关系型数据库的database概念,每个命名空间下有多个表。HBase两个自带的命名空间,分别是hbase和default,hbase中存放的是HBase内置的表,default表是用户默认使用的命名空间。
一个表可以自由选择是否有命名空间,如果创建表的时候加上了命名空间后,这个表名字以<Namespace>:<Table>作为区分!
2)Table
类似于关系型数据库的表概念。不同的是,HBase定义表时只需要声明列族即可,数据属性,比如超时时间(TTL),压缩算法(COMPRESSION)等,都在列族的定义中定义,不需要声明具体的列。
这意味着,往HBase写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase能够轻松应对字段变更的场景。
3)Row
HBase表中的每行数据都由一个RowKey和多个Column(列)组成。一个行包含了多个列,这些列通过列族来分类,行中的数据所属列族只能从该表所定义的列族中选取,不能定义这个表中不存在的列族,否则报错NoSuchColumnFamilyException。
4) RowKey
Rowkey由用户指定的一串不重复的字符串定义,是一行的唯一标识!数据是按照RowKey的字典顺序存储的,并且查询数据时只能根据RowKey进行检索,所以RowKey的设计十分重要。
如果使用了之前已经定义的RowKey,那么会将之前的数据更新掉!
5)Column Family
列族是多个列的集合。一个列族可以动态地灵活定义多个列。表的相关属性大部分都定义在列族上,同一个表里的不同列族可以有完全不同的属性配置,但是同一个列族内的所有列都会有相同的属性。
列族存在的意义是HBase会把相同列族的列尽量放在同一台机器上,所以说,如果想让某几个列被放到一起,你就给他们定义相同的列族。
官方建议一张表的列族定义的越少越好,列族太多会极大程度地降低数据库性能,且目前版本Hbase的架构,容易出BUG。
6) Column Qualifier
Hbase中的列是可以随意定义的,一个行中的列不限名字、不限数量,只限定列族。因此列必须依赖于列族存在!列的名称前必须带着其所属的列族!例如info:name,info:age。
因为HBase中的列全部都是灵活的,可以随便定义的,因此创建表的时候并不需要指定列!列只有在你插入第一条数据的时候才会生成。其他行有没有当前行相同的列是不确定,只有在扫描数据的时候才能得知!
7)TimeStamp
用于标识数据的不同版本(version)。时间戳默认由系统指定,也可以由用户显式指定。
在读取单元格的数据时,版本号可以省略,如果不指定,Hbase默认会获取最后一个版本的数据返回!
8)Cell
一个列中可以存储多个版本的数据。而每个版本就称为一个单元格(Cell)。
Cell由{rowkey, column Family:column Qualifier, time Stamp}确定。
Cell中的数据是没有类型的,全部是字节码形式存贮。
9)Region
Region由一个表的若干行组成!在Region中行的排序按照行键(rowkey)字典排序。
Region不能跨RegionSever,且当数据量大的时候,HBase会拆分Region。
Region由RegionServer进程管理。HBase在进行负载均衡的时候,一个Region有可能会从当前RegionServer移动到其他RegionServer上。
Region是基于HDFS的,它的所有数据存取操作都是调用了HDFS的客户端接口来实现的。
2.5 HBase基本架构
架构角色:
1)Region Server
RegionServer是一个服务,负责多个Region的管理。其实现类为HRegionServer,主要作用如下:
对于数据的操作:get, put, delete;
对于Region的操作:splitRegion、compactRegion。
客户端从ZooKeeper获取RegionServer的地址,从而调用相应的服务,获取数据。
2)Master
Master是所有Region Server的管理者,其实现类为HMaster,主要作用如下:
对于表的操作:create, delete, alter,这些操作可能需要跨多个ReginServer,因此需要Master来进行协调!
对于RegionServer的操作:分配regions到每个RegionServer,监控每个RegionServer的状态,负载均衡和故障转移。
即使Master进程宕机,集群依然可以执行数据的读写,只是不能进行表的创建和修改等操作!当然Master也不能宕机太久,有很多必要的操作,比如创建表、修改列族配置,以及更重要的分割和合并都需要它的操作。
3)Zookeeper
RegionServer非常依赖ZooKeeper服务,ZooKeeper管理了HBase所有RegionServer的信息,包括具体的数据段存放在哪个RegionServer上。
客户端每次与HBase连接,其实都是先与ZooKeeper通信,查询出哪个RegionServer需要连接,然后再连接RegionServer。Zookeeper中记录了读取数据所需要的元数据表
hbase:meata,因此关闭Zookeeper后,客户端是无法实现读操作的!
HBase通过Zookeeper来做master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等工作。
4)HDFS
HDFS为Hbase提供最终的底层数据存储服务,同时为HBase提供高可用的支持。
第 3 章 Hbase安装
3.1 Hbase安装前
3.1.1 启动Zookeeper
首先保证Zookeeper集群的正常部署,并启动之:
[jack@hadoop102 zookeeper-3.4.10]$ bin/zkServer.sh start
[jack@hadoop103 zookeeper-3.4.10]$ bin/zkServer.sh start
[jack@hadoop104 zookeeper-3.4.10]$ bin/zkServer.sh start
3.1.2 启动Hadoop
Hadoop集群的正常部署并启动:
[jack@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh
[jack@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh
3.1.3 HBase的解压
解压HBase到指定目录:
[jack@hadoop102 soft]$ tar -zxvf HBase-1.3.1-bin.tar.gz -C /opt/module
3.2 HBase的安装
3.2.1 HBase的配置
修改HBase对应的配置文件。
1)HBase-env.sh修改内容:
export JAVA_HOME=/opt/module/jdk1.6.0_144
export HBASE_MANAGES_ZK=false
2)HBase-site.xml修改内容:
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://hadoop102:9000/HBase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<!-- 0.98后的新变动,之前版本没有.port,默认端口为60000 -->
<property>
<name>hbase.master.port</name>
<value>16000</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/opt/module/zookeeper-3.4.10/zkData</value>
</property>
</configuration>
3)regionservers:
hadoop102 hadoop103 hadoop104 |
4)软连接hadoop配置文件到HBase:
[jack@hadoop102 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/core-site.xml
/opt/module/HBase/conf/core-site.xml
[jack@hadoop102 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/hdfs-site.xml
/opt/module/HBase/conf/hdfs-site.xml
3.2.2 分发HBase到其他节点
[jack@hadoop102 module]$ xsync HBase/
3.3 HBase服务的启动
1.启动方式1
[jack@hadoop102 HBase]$ bin/HBase-daemon.sh start master
[jack@hadoop102 HBase]$ bin/HBase-daemon.sh start regionserver
提示:如果集群之间的节点时间不同步,会导致regionserver无法启动,抛出ClockOutOfSyncException异常。
修复提示:
a、同步时间服务
请参看帮助文档:《尚硅谷大数据技术之Hadoop入门》
b、属性:hbase.master.maxclockskew设置更大的值
<property> <name>hbase.master.maxclockskew</name> <value>180000</value> <description>Time difference of regionserver from master</description> </property> |
2.启动方式2
[jack@hadoop102 HBase]$ bin/start-HBase.sh
对应的停止服务:
[jack@hadoop102 HBase]$ bin/stop-HBase.sh
3.4 查看HBase页面
启动成功后,可以通过“host:port”的方式来访问HBase管理页面,例如:http://hadoop102:16010
第 4 章 HBase Shell操作
使用hbase shell可以进入一个shell命令行界面!
[jack@hadoop102 HBase]$ bin/HBase shell
4.1 其他操作
1.查看集群状态
使用status可以查看集群状态,默认为summary,可以选择‘simple’和‘detailed’来查看详情。
hbase(main):011:0> status
1 active master, 0 backup masters, 3 servers, 0 dead, 0.6667 average load
2.查看版本
hbase(main):002:0> version
1.3.1, r930b9a55528fe45d8edce7af42fef2d35e77677a, Thu Apr 6 19:36:54 PDT 2017
3.查看操作用户及组信息
hbase(main):003:0> whoami
jack (auth:SIMPLE)
groups: jack
4.查看表操作信息
hbase(main):004:0> table_help
Help for table-reference commands.
5.查看帮助信息
hbase(main):005:0> help
HBase Shell, version 1.3.1, r930b9a55528fe45d8edce7af42fef2d35e77677a, Thu Apr 6 19:36:54 PDT 2017
Type 'help "COMMAND"', (e.g. 'help "get"' -- the quotes are necessary) for help on a specific command.
Commands are grouped. Type 'help "COMMAND_GROUP"', (e.g. 'help "general"') for help on a command group.
6.查看具体命令的帮助
hbase(main):006:0> help 'get'
Get row or cell contents; pass table name, row, and optionally
a dictionary of column(s), timestamp, timerange and versions. Examples:
hbase> get 'ns1:t1', 'r1'
注意引号是必须的!
4.2 表的操作
4.2.1. list
hbase(main):008:0> list
TABLE
0 row(s) in 0.0410 seconds
list后可以使用*等通配符来进行表的过滤!
4.2.2 create
创建表时,需要指定表名和列族名,而且至少需要指定一个列族,没有列族的表是没有任何意义的。
创建表时,还可以指定表的属性,表的属性需要指定在列族上!
格式:
create '表名', { NAME => '列族名1', 属性名 => 属性值}, {NAME => '列族名2', 属性名 => 属性值}, …
如果你只需要创建列族,而不需要定义列族属性,那么可以采用以下快捷写法:
create'表名','列族名1' ,'列族名2', …
HBase(main):002:0> create 'student','info'
4.2.3 desc
hbase(main):003:0> describe 'person'
hbase(main):004:0> desc 'person'
4.2.4 disable
停用表后,可以防止在对表做一些维护时,客户端依然可以持续写入数据到表。一般在删除表前,必须停用表。
在对表中的列族进行修改时,也需要停用表。
hbase(main):005:0> disable 'person'
0 row(s) in 2.4250 seconds
disable_all ‘正则表达式’ 可以使用正则来匹配表名。
is_disabled 可以用来判断表是否被停用。
hbase(main):006:0> is_disabled 'person'
true
0 row(s) in 0.0160 seconds
4.2.5 enable
和停用表类似。enable ‘表名’用来启用表,is_enabled ‘表名’用来判断一个表是否被启用。
enable_all ‘正则表达式’可以通过正则来过滤表,启用复合条件的表。
4.2.6. exists
hbase(main):008:0> exists 'person'
Table person does exist