HBase是一个分布式,面向对象的开源数据库,该技术来源于Google论文“Bigtable:一个结构化数据的分布式存储系统”。
就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。
HBase是apache的Hadoop项目的子项目。
HBase不同于一般的关系型数据库,它是一个适合于非结构化数据存储的数据库,另一个不同的是HBase基于列的而不是基于行模式。
HBase存储的是松散型数据(稀疏型的数据,并不是每个列都有数据,保证查询的效率,比如学生表中有的只有学号,而没有年龄,有的没有成绩,存储时只需要存储学号,空值不需要存储)。
1、逻辑模型
以表的形式存放数据
表由行和列组成,每个列属于某个列族,由行和列确定的存储单元称为元素
每个元素保存了同一份数据的多个版本,由时间戳来标识区分
行键
时间戳
列族contens
列族anchor
列族mime
“com.cnn.www”
t9
anchor:cnnsi.com=”CNN”
t8
anchor:my.look.ca=”CNN.com”
t6
contens:html=””
mime:type=”text/html”
t5
contens:html=””
t3
contens:html=””
注释:
a) 之所以有多个时间戳,是因为HBase中数据无法update,只能插入新的时间戳版本的数据。
b)删除时,也是插入一行,然后加入一个删除的标记。
下面,我们来介绍一些概念:
1) 行键(Rowkey)
行键是数据行在表里面的唯一标识,并作为检索记录的主键
访问表里面的行只有三种方式:
a) 通过单个行键访问
b) 给定行键的范围访问
c) 全表扫描
行键可以是最大长度不超过64kb的任意字符串,并按照字典序存储
对于经常要一起读取的行,要对行键值精心设计,以便他们能够存放在一起存储。
总结:
–行键是字节数组, 任何字符串都可以作为行键;
– 表中的行根据行键进行排序,数据按照Row key的字节序(byteorder)排序存储;
– 所有对表的访问都要通过行键(单个RowKey访问,或RowKey范围访问,或全表扫描)
2) 列族( ColumnFamily )
列表示为<列族>:<限定符>
HBase在磁盘上按照列族存储数据,这种列式数据库的设计非常适合于数据分析的情形。
列族里的元素最好具有相同的读写方式(例如等长的字符串),以提高性能。
总结:
– CF(ColumnFamily列族)必须在表定义时给出
–每个CF可以有一个或多个列成员(ColumnQualifier),列成员不需要在表定义时给出,新的列族成员可以随后按需、动态加入
–数据按CF分开存储,HBase所谓的列式存储就是根据CF分开存储(每个CF对应一个Store),这种设计非常适合于数据分析的情形
3) 时间戳(TimeStamp)
对应每次数据操作的时间,可由系统自动生成,也可以由用户显式的赋值
HBase支持两种数据版本回收方式:
a) 每个数据单元,只能存储指定个数的最新版本
b) 保存指定时间长度的版本(例如7天)
常见的客户端时间查询:“某个时刻起的最新数据”或者“给我全部版本的数据”
总结:
–每个Cell可能又多个版本,它们之间用时间戳区分
4) 单元格(Cell)或称为元素
– Cell (元素)由行键,列族:限定符,时间戳唯一决定
– Cell(元素)中的数据是没有类型的,全部以字节码形式存贮
5) 区域(Region)
–HBase自动把表水平(按Row)划分成多个区域(region),每个region会保存一个表里面某段连续的数据;
– 每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阈值的时候,region就会等分会两个新的region;
– 当table中的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个Region上。
– HRegion是HBase中分布式存储和负载均衡的最小单元。最小单元表示不同的HRegion可以分布在不同的HRegionServer上。但一个HRegion不会拆分到多个server上。
2、HBase物理存储
所有的列族都在同一列。
Table中的所有行都按照row key的字典序排列。
Table 在行的方向上分割为多个HRegion,多个HRegion可以位于不同的HRegionServer上面。
region按大小分割的,每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,HRegion就会等分成两个新的HRegion。当table中的行不断增多,就会有越来越多的HRegion。
HRegion是Hbase中分布式存储和负载均衡的最小单元。最小单元就表示不同的HRegion可以分布在不同的HRegion server上。但一个HRegion是不会拆分到多个server上的。
HRegion虽然是分布式存储的最小单元,但并不是存储的最小单元。
事实上,HRegion由一个或者多个Store组成,每个Store保存一个columns family。
每个Strore又由一个memStore和0至多个StoreFile组成。StoreFile以HFile格式保存在HDFS上。
3、HBase物理模型
HMaster HBase = Master HBase
HRegionServer = HBase RegionServer
1) Region和Region服务器
表在行方向上,按照行键范围划分成若干的Region;
每个表最初只有一个region,当记录数增加到超过某个阀值时,开始分裂成两个region;
物理上所有数据存放在HDFS,由Region服务器提供region的管理;
一台物理节点只能跑一个HRegionServer;
一个HRegionServer可以管理很多的Region实例;
一个Region实例包括HLog日志和存放数据的Store(一个或多个),每个Store保存一个Columns Family(列族);
每个Store又由一个memStore和0至多个StoreFile组成;
StoreFile以HFile格式保存在HDFS上面。
HMaster作为总控节点;
Zookeeper负责调度。
2) HLog
用于灾难恢复;
预写式日志(WAL,Write-Ahead Logging),记录所有更新操作,操作先记录日志,数据才会写入数据文件。
每个Region Server服务器只维护一个HLog(而不是每个Region一个),来自不同表的Region日志是混合在一起的,这样做的目的是不断追加单个文件相对于同时写多个文件而言,可以减少磁盘寻址次数,因此可以提高对table的写性能。但是带来的问题是,如果一台RegionServer下线,为了恢复其上的Region,需要将Region Server的HLog进行拆分,然后分发到其他Region Server上进行恢复。
HLog文件就是一个普通的Hadoop Sequence File,Sequence File的Key是HLogKey对象,HLogKey中记录了写入数据的归属信息,除了table和region名字外,同时还包括 sequence number和timestamp,timestamp是”写入时间”,sequence number的起始值为0,或者是最近一次存入文件系统中sequencenumber。HLog Sequece File的Value是Hbase的KeyValue对象,即对应HFile中的KeyValue。
HLog会被定期回滚。
3) Store
每个Region由一个或多个HStore组成,每个HStore保存一个列族的所有数据;
每个HStore由一个memStore和0个或多个StoreFile组成;
StoreFile以Hfile的格式存储在HDFS上的,这些文件都是B树结构。
4) 客户端更新操作流程
先连接有关的HRegionServer,然后向Region提交变更,
提交的数据首先写入WAL(Write-Ahead Log)和MemStore;
当memstore中的数据量达到某个阀值,HRegionServer会启动flashcache进程写入StoreFile;
当StoreFile文件的数量增加到一定阀值后,系统会将多个StoreFile进行合并,在合并的过程中会进行版本合并和删除工作,形成更大的StoreFile
当单个StoreFile大小超过一定阀值后,会把当前的Region分隔成为两个Regions,并由HMaster分配到相应的Region服务器,实现负载均衡
客户端检索数据时,先在MemStore找,找不到再找StoreFile。
5) HMaster
HBase只有一个Hmaster,主服务器程序
HMaster将Region分配给Region Server服务器,协调Region Server服务器的负载并维护集群的状态
HMaster不会对外(Region Server服务器和客户端)提供数据服务,而是由RegionServer服务器负载所有Regions的读写请求和操作;
如果HRegion Server发生故障终止后,HMaster会通过ZooKeeper感知到,并处理相应的HLog文件,然后重新分配失效的Regions;
HMaster还负责管理表的schema和对元数据的操作;
HMaster失效仅会导致所有元数据无法被修改,但表的数据读写还是可以正常进行的。