分布式数据库HBase
Hbase简介对比
HBase的概念
HBase-Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩、实时读写的分布式数据库。
在Hadoop生态圈中,它是其中一部分且利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理HBase中的海量数据,利用Zookeeper作为其分布式协同服务,主要用来存储非结构化和半结构化的松散数据(NoSQL非关系型数据库有redis、MongoDB等)。
而我们的HBase就是这样一个非关系型数据库。
简单来说,关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
关系型与非关系型数据库对比
关系型数据库
1、关系型数据库的3大优点
**容易理解:**二维表结构是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型来说更容易理解。
**使用方便:**通用的SQL语言使得操作关系型数据库非常方便。
**易于维护:**丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率。
2、关系型数据库的3大瓶颈
(1)高并发读写需求
网站的用户并发性非常高,往往达到每秒上万次读写请求,对于传统关系型数据库来说,硬盘I/O是一个很大的瓶颈,并且很难能做到数据的强一致性。
(2)海量数据的读写性能低:
网站每天产生的数据量是巨大的,对于关系型数据库来说,在一张包含海量数据的表中查询,效率是非常低的。
(3)扩展性和可用性差
在基于web的结构当中,数据库是最难(但是可以)进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移。
当然,对网站来说,关系型数据库的很多特性不再需要了,比如:事务一致性、读写实时性 。在关系型数据库中,导致性能欠佳的最主要原因是多表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询。为了保证数据库的ACID特性,我们必须尽量按照其要求的范式进行设计,关系型数据库中的表都是存储一个格式化的数据结构。
非关系型数据库
1、非关系型数据库的理念
非关系型数据库提出另一种理念,例如:以 key-value 键值对存储,且结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,这样就不会局限于固定的结构,可以减少一些时间和空间的开销。 使用这种方式,用户可以根据需要去添加自己需要的字段,这样,为了获取用户的不同信息,不需要像关系型数据库中,要对多表进行关联查询。仅需要根据 id 取出相应的 value 就可以完成查询。
2、非关系型数据库特点
(1)一般不支持ACID特性,无需经过SQL解析,读写性能高。
ACID,指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。一个支持事务(Transaction)的数据库,必须要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求。
(2)存储格式:key-value,文档,图片等等。
(3)数据没有耦合性,容易扩展。
但非关系型数据库由于很少的约束,他也不能够提供像SQL所提供的where这种对于字段属性值情况的查询。并且难以体现设计的完整性。他只适合存储一些较为简单的数据,对于需要进行较复杂查询的数据,SQL数据库显的更为合适。
(4)多样性且开源。
由于非关系型数据库本身天然的多样性,以及出现的时间较短,因此,不像关系型数据库,有几种数据库能够一统江山,非关系型数据库非常多,并且大部分都是开源的。
(5)特定的应用需求
这些数据库中,其实实现大部分都比较简单,除了一些共性外,很大一部分都是针对某些特定的应用需求出现的,因此,对于该类应用,具有极高的性能。
3、非关系型数据库的分类
(1)**面向高性能并发读写的key-value数据库:**Redis,Tokyo Cabinet,Flare。
(2)**面向海量数据访问的文档数据库:**MongoDB以及CouchDB,可以在海量的数据中快速的查询数据。
(3)**面向可扩展性的分布式数据库:**这类数据库想解决的问题就是传统数据库存在可扩展性上的缺陷,这类数据库可以适应数据量的增加以及数据结构的变化。
二者优缺点对比
HBase数据模型
我们先大概看一下传统数据库存储方式及非关系型数据库的存储方式。
非关系型数据库表
Row Key
1、决定一行数据,具有唯一性。
2、按照字典顺序排序。
3、Row Key最大只能存储64K的字节数据。
Column Family列族 & qualifier列
1、HBase表中的每个列都归属于某个列族,列族必须作为表模式(schema)定义的一部分预先给出。如 create ‘test’, ‘course’;
2、列名以列族作为前缀,每个“列族”都可以有多个列成员(column);如 course:math, course:english, 新的列可以随后按需、动态加入;权限控制、存储以及调优都是在列族层面进行的;
3、HBase把同一列族里面的数据存储在同一目录下,由几个文件保存。
Cell 单元格
1、由行和列的坐标交叉决定; 单元格是有版本的;
2、单元格的内容是未解析的字节数组;
3、由 {row key, column( = < family > + < qualifier >), version} 唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存贮。
Timestamp 时间戳
1、在HBase每个cell存储单元对同一份数据有多个版本,根据唯一的时间戳来区分每个版本之间的差异,不同版本的数据按照时间倒序排序,最新的数据版本排在最前面。
2、时间戳的类型是 64位整型。
3、时间戳可以由HBase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。 时间戳也可以由客户显式赋值,如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。
HLog(WAL log)
1、HLog文件就是一个普通的Hadoop SequenceFile,Sequence File的Key是HLogKey对象,HLogKey中记录了写入数据的归属信息,除了table和region名字外,同时还包括 sequence number和timestamp,timestamp是”写入时间”,sequence number的起始值为0,或者是最近一次存入文件系统中sequence number。
sequenceFile文件是Hadoop用来存储二进制形式的[Key,Value]对而设计的一种平面文件(Flat File),它提供key-value的存储,但与传统key-value存储(比如hash表,btree)不同的是,它是append only的,于是你不能对已存在的key进行写操作。
2、HLog SequeceFile的Value是HBase的KeyValue对象,即对应HFile中的KeyValue。存储Hbase表的操作记录,K-V数据信息。
HBase 体系架构
Client
包含访问HBase的接口并维护cache来加快对HBase的访问。
Zookeeper
1、保证任何时候,集群中只有一个master。
2、存贮所有Region的寻址入口。
3、实时监控Region server的上线和下线信息,并实时通知Master。
4、存储HBase的schema(数据库对象的集合)和table元数据。
方案(Schema)为数据库对象的集合,为了区分各个集合,我们需要给这个集合起个名字,这些名字就是我们在企业管理器的方案下看到的许多类似用户名的节点,这些类似用户名的节点其实就是一个schema,schema里面包含了各种对象如tables, views, sequences, stored procedures, synonyms, indexes, clusters, and database links。 一个用户一般对应一个schema,该用户的schema名等于用户名,并作为该用户缺省schema。这也就是我们在企业管理器的方案下看到schema名都为数据库用户名的原因。
Master
为 Region server 分配region.
1、负责Region server的负载均衡;
2、发现失效的Region server并重新分配其上的region;
3、管理用户对table的操作,对表的创建、删除、修改(DDL)。
RegionServer
1、维护region,处理对这些region的IO请求;
2、负责切分在运行过程中变得过大的region。
Region
1、HBase自动把表水平划分成多个区域(region),每个region会保存一个表里面某段连续的数据;每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,region就会等分成两个新的region(裂变);
2、当table中的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个Regionserver 上。
3、HRegion是HBase中分布式存储和负载均衡的最小单元,最小单元就表示不同的HRegion可以分布在不同的 HRegion server上。
MemStore与StoreFile
1、一个Region由多个Store组成,一个Store对应一个CF(列族)。
2、Store包括位于内存中的MemStore和位于磁盘的StoreFile。写操作先写入MemStore,当MemStore中的数据达到某个阈值,HRegionServer会启动flashcache进程溢写到磁盘中的Storefile,每次写入形成单独的一个StoreFile;
3、当StoreFile文件的数量增长到一定阈值后,系统会进行合并(minor、major compaction)。
先抽取一部分小的StoreFile文件进行小合并(minor compaction),小的StoreFile文件指的是刚溢写形成的最大64M,小合并速度比较快,IO开销比较小。然后当这些小合并的StoreFile越来越多,会进行大合并(major compaction),在合并过程中会进行版本合并和删除工作(major),形成更大的StoreFile。大合并速度比较慢,IO开销也比较大。
注意:合并只能是同一个store里的合并,也就是同一个列族里的合并。不然数据会包含多个列族,造成数据混乱。
4、当一个Region所有StoreFile已经合并且大小和数量超过一定阈值后,会把当前的Region分割为两个(裂变),并由HMaster分配到相应的HRegionServer服务器,实现负载均衡。
StoreFile文件的大小取决于内存大小,当它的数量达到峰值后根据相同的key进行合并(HBase的小合并)。
当MemStore中的数据溢写到磁盘后,系统会在内存中开辟一个新的MemStore去接收数据写入,老的MemStore在落地到磁盘后被释放掉。永远只有一个MemStore去接收服务。还有一种,当服务器宕机或者异常,尽管MemStore还未满,数据也会被落地到磁盘,也就是HDFS上,避免数据的丢失。
客户端检索数据,先在MemStore找,找不到再找StoreFile。(也就是先会到内存中找,找不到再去磁盘中找)
HRegion由一个或者多个Store组成,每个store保存一个columns family,每个Strore又由一个memStore和0至多个StoreFile组成。StoreFile以HFile格式保存在HDFS上。
HBase的安装部署
1、上传tar安装包并解压
官网下载地址:http://hbase.apache.org/downloads.html
在使用的时候注意版本的兼容问题,我这里使用的是1.2.1的版本。
2、修改hbase-env.sh配置JAVA_HOME
在 hbase的安装包下的conf目录下,打开hbase-env.sh,填入JAVA_HOME路径
注意:
不使用HBase的默认zookeeper配置:HBASE_MANAGES_ZK=false
3、配置hbase-site.xml,也是在conf目录下
配置参数:
<property> |
4、配置regionservers添加你配置的regionservers 的主机名
还是到conf目录下新建regionservers文件
5、vi并配置backup-masters 添加你配置的master备份的主机名
6、拷贝Hadoop的下配置文件hdfs-site.xml到当前conf下
cp -r /usr/soft/hadoop-2.6.5/etc/hadoop/hdfs-site.xml ./ |
7、将配置好的环境发送给其他的服务器节点
scp -r hbase-0.98.12.1-hadoop2 sean02:/usr/soft/ |
8、配置HBase的环境变量
配置局部的环境变量 ~/.bash_profile
然后不要忘记发送给其他节点
scp -r ~/.bash_profile sean02:/root/ |
最后记得刷新一下环境变量:source ~/.bash_profile
当我们在任意的节点上输入hbase,tab键一下,出现下图说明环境变量已配置成功。
9、启动:Zookeeper集群主机
zkServer.sh start |
10、启动hadoop
start-all.sh |
11、启动hbase :因为HBase依赖于Hadoop和zookeeper之上的所以要Hadoop集群启动正常和Zookeeper集群启动正常。因为用不到yarn,所以不需要启动。
start-hbase.sh |
12、启动后查看集群进程
13、查看Web端
默认端口:60010
注意:有时查看web端,我们找不到另外两个节点的服务。再次查看进程,发现节点sean02和sean03已经挂掉
这时需要做时间同步。停掉hbase的进程
stop-hbase.sh #停止hbase的进程 |
做完时间同步后再次启动hbase,再查看web端
结果如图上所示,说明启动正常,搭建成功!
HBase Shell & API
HBase Shell
1、进入shell命令行
通过 hbase shell 命令进入HBase 命令行接口
2、hbase shell中的操作参数
通过help可查看所有命令的支持以及帮助手册
名称 | Shell命令 |
---|---|
创建表 | create ‘表名’, ‘列族名1’[,…] |
添加记录 | put ‘表名’, ‘RowKey’, ‘列族名称:列名’, ‘值’ |
查看记录 | get ‘表名’, ‘RowKey’, ‘列族名称:列名’ |
查看表中的记录总数 | count ‘表名’ |
删除记录 | delete ‘表名’ , ‘RowKey’, ‘列族名称:列名’ |
删除一张表 | 先要屏蔽该表,才能对该表进行删除。第一步 disable ‘表名称’ 第二步 drop ‘表名称’ |
查看所有记录 | scan ‘表名’ |
设置表的过期时间 | alter ’表名‘ , {NAME => ‘f’, TTL => 7776000} |
注意:在hbase命令行中,常规的删除无法正常使用,需要按 ctrl+删除键 组合使用
这是因为Xshell的设置中默认的。在节点属性中的键盘设置中可以查看
3、具体操作
(1)建表:表名为t1,列族为cf1
create 't1','cf1' |
(2)查看当前表,使用命令 list
(3)添加表记录:
表名t1,rowkey为0001,列族cf1,列名name,Value为xiaoming |
(4)查看表所有记录
scan 't1' |
注意:因为scan是整个表的全盘扫描,如果表数据过大,慎用!
(5)查看某个表的指定条件的记录
get 't1','0001' #表示查看t1表中rowkey为0001的表记录 |
(6)设定表的保留版本(在创建表初期定义)
create 't2',{NAME =>'cf1',VERSIONS => 2} #表名t2,列族cf1,保留2个版本 |
put数据进去
put 't2','0001','cf1:name','lisi' |
然后命令scan查看表数据
然而我们创建表的时候明明保留了3个版本,为什么这里只显示一个最新的版本呢?是因为我们没有加版本号
scan 't2',{RAW => true,VERSIONS => 2} #取两个版本 |
那当我们取三个或者四个、五个版本呢
scan 't2',{RAW => true,VERSIONS => 3} #取三个版本 |
我们会惊奇的发现,本来我们创建的时候定义保留两个版本,但是这里却留下了我们所有的版本。这是为什么?
这里发现RAM这个字段设为true的时候,意思是未经处理的都显示出来,也就是说:当写入内存中的数据较少时,内存中的数据还没有达到阈值,所以并未溢写到磁盘,也就是未处理。
如果去掉字段RAW,就只显示我们保留的两个版本
scan 't2',{VERSIONS => 5} #取五个版本 |
这里我们可以验证一下:
① 在处理之前,我们到HDFS web端看到,hbase目录下有三个文件夹WALs、oldWALs和data,WALs中存着表的元数据信息,data中存放表的真实数据,oldWALs中存放之前已经经过处理的元数据信息。
打开data文件夹会发现是空的,根本没有数据,也就是说还没有落地到磁盘
② 我们知道如果服务器发生意外宕机(也可以使用flush命令),内存中的数据就自动会落地到磁盘中。所以我们关掉hbase的服务
stop-hbase.sh |
注:如果关闭hbase的过程中发生异常无法关闭,ctrl+c暂停,换另外一个HMaster去关,如果还是无法关闭,ctrl+c暂停,查看进程kill调其中的一个,kill尽量少用,会对服务器有损耗。
③ 重新开启hbase服务,查看HDFS数据
start-hbase.sh |
oldWALs目录
data目录
此时说明,t2表的数据已经落地到磁盘中
总结:客户端检索数据,先会到内存中找,找不到再去磁盘中找。
④ 进入hbase中查询表数据
此时发现由于数据已经落地到磁盘,所以无论怎么取都会保留在建表初期设定的保留两个版本
(7)删除表
drop 't2' |
删表前我们要先进行disable(屏蔽掉)这个表再删除
如图显示已删除成功!
Hbase 建表设置数据的有效期
create 't1', {NAME => 'f', TTL => 7776000,VERSIONS => 1} |
如果在已存在的表上加有效期,要先disable
disable 'tableName' |
HBase API
详细 API 请见我的 github 仓库:Hbase API
总结思考
1、HBase中写入数据什么情况会落地到磁盘
- 当MemStore中的数据达到某个阈值,HRegionServer会启动flashcache进程溢写到磁盘中的Storefile。
- 当前HRegionServer服务器异常宕机。
- 使用命令
flush
强制刷到磁盘中。