一、什么是HBase?
hbase是bigtable得开源java版本。是建立在hdfs之上,提供高可靠、高性能、列存储、可伸缩、实时读写nosql得数据库系统。
它介于nosql和RDBMS之间,仅能通过主键(row key)和主键得range来检索数据,仅支持单行事务,当然后面可以和hive做集合配合来实现多表join等复杂得操作。
HBase表的特点:
1.一个表可以有上十亿行,上百万列。
2.面向列:面向列族的存储和权限控制,列族独立检索。
3.稀疏性:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。
二、HBase与Hadoop的关系
HDFS:
1. 是一个分布式文件存储系统
2. 针对储存大尺寸的文件进行优化,不需要对hdfs上的文件进行随机读写
3 .直接使用文件
4 .数据模型不灵活
5. 优化一次写入,多次读取的方式
6 .使用文件系统和处理框架
HBase:
1. 提供表状的面向列的数据存储
2. 针对表状数据的随机读写进行优化
3. 使用key-value操作数据
4. 提供灵活的数据模型
5.使用表状存储,依赖hdfs,支持mapreduce
6. 优化了多次读写,以及多次写
三、RDBMS与HBase的对比
1.关系型数据库
结构:
* 数据库以表的形式存在
* 支持FAT、NTFS、EXT、文件系统
* 使用Commit log存储日志
* 参考系统是坐标系统
* 使用主键(PK)
* 支持分区
* 使用行、列、单元格
功能:
* 支持向上扩展
* 使用SQL查询
* 面向行,即每一行都是一个连续单元
* 数据总量依赖于服务器配置
* 具有ACID支持
* 适合结构化数据
* 传统关系型数据库一般都是中心化的
* 支持事务
* 支持Join
2.Hbase
结构:
* 数据库以region的形式存在
* 支持HDFS文件系统
* 使用WAL(Write-Ahead Logs)存储日志
* 参考系统是Zookeeper
* 使用行键(row key)
* 支持分片
* 使用行、列、列族和单元格
功能:
* 支持向外扩展
* 使用API和MapReduce来访问HBase表数据
* 面向列,即每一列都是一个连续的单元
* 数据总量不依赖具体某台机器,而取决于机器数量
* HBase不支持ACID(Atomicity、Consistency、Isolation、Durability)
* 适合结构化数据和非结构化数据
* 一般都是分布式的
* HBase不支持事务,支持的是单行数据的事务操作
* 不支持Join
四、Hbase系统架构及数据结构
1.1 Row Key (行键)
Row Key
是用来检索记录的主键。想要访问 HBase Table 中的数据,只有以下三种方式:
-
通过指定的
Row Key
进行访问; -
通过 Row Key 的 range 进行访问,即访问指定范围内的行;
-
进行全表扫描。
Row Key
可以是任意字符串,存储时数据按照 Row 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.2 Column Family(列族)
HBase 表中的每个列,都归属于某个列族。列族是表的 Schema 的一部分,所以列族需要在创建表时进行定义。列族的所有列都以列族名作为前缀,例如 courses:history
,courses:math
都属于 courses
这个列族。
1.3 Column Qualifier (列限定符)
列限定符,你可以理解为是具体的列名,例如 courses:history
,courses:math
都属于 courses
这个列族,它们的列限定符分别是 history
和 math
。需要注意的是列限定符不是表 Schema 的一部分,你可以在插入数据的过程中动态创建列。
1.4 Column(列)
HBase 中的列由列族和列限定符组成,它们由 :
(冒号) 进行分隔,即一个完整的列名应该表述为 列族名 :列限定符
。
1.5 Cell
Cell
是行,列族和列限定符的组合,并包含值和时间戳。你可以等价理解为关系型数据库中由指定行和指定列确定的一个单元格,但不同的是 HBase 中的一个单元格是由多个版本的数据组成的,每个版本的数据用时间戳进行区分。
1.6 Timestamp(时间戳)
HBase 中通过 row key
和 column
确定的为一个存储单元称为 Cell
。每个 Cell
都保存着同一份数据的多个版本。版本通过时间戳来索引,时间戳的类型是 64 位整型,时间戳可以由 HBase 在数据写入时自动赋值,也可以由客户显式指定。每个 Cell
中,不同版本的数据按照时间戳倒序排列,即最新的数据排在最前面。
二、存储结构
2.1 Regions
HBase Table 中的所有行按照 Row Key
的字典序排列。HBase Tables 通过行键的范围 (row key range) 被水平切分成多个 Region
, 一个 Region
包含了在 start key 和 end key 之间的所有行。
2.2 Region Server
Region Server
运行在 HDFS 的 DataNode 上。它具有以下组件:
- WAL(Write Ahead Log,预写日志):用于存储尚未进持久化存储的数据记录,以便在发生故障时进行恢复。
- BlockCache:读缓存。它将频繁读取的数据存储在内存中,如果存储不足,它将按照
最近最少使用原则
清除多余的数据。 - MemStore:写缓存。它存储尚未写入磁盘的新数据,并会在数据写入磁盘之前对其进行排序。每个 Region 上的每个列族都有一个 MemStore。
- HFile :将行数据按照 Key\Values 的形式存储在文件系统上。
五、HBase的读写请求
1、读请求过程:
HRegionServer保存着meta表以及表数据,要访问表数据,首先Client先去访问zookeeper,从zookeeper里面获取meta表所在的位置信息,即找到这个meta表在哪个HRegionServer上保存着。
接着Client通过刚才获取到的HRegionServer的IP来访问Meta表所在的HRegionServer,从而读取到Meta,进而获取到Meta表中存放的元数据。
Client通过元数据中存储的信息,访问对应的HRegionServer,然后扫描所在HRegionServer的Memstore和Storefile来查询数据。
最后HRegionServer把查询到的数据响应给Client。
2、写请求过程:
Client也是先访问zookeeper,找到Meta表,并获取Meta表元数据。
确定当前将要写入的数据所对应的HRegion和HRegionServer服务器。
Client向该HRegionServer服务器发起写入数据请求,然后HRegionServer收到请求并响应。
Client先把数据写入到HLog,以防止数据丢失。
然后将数据写入到Memstore。
如果HLog和Memstore均写入成功,则这条数据写入成功
如果Memstore达到阈值,会把Memstore中的数据flush到Storefile中。
当Storefile越来越多,会触发Compact合并操作,把过多的Storefile合并成一个大的HFile。
当HFile越来越大,Region也会越来越大,达到阈值后,会触发Split操作,将Region一分为二。
细节描述:
hbase使用MemStore和StoreFile存储对表的更新。
数据在更新时首先写入Log(WAL log)和内存(MemStore)中,MemStore中的数据是排序的,当MemStore累计到一定阈值时,就会创建一个新的MemStore,并 且将老的MemStore添加到flush队列,由单独的线程flush到磁盘上,成为一个StoreFile。于此同时,系统会在zookeeper中记录一个redo point,表示这个时刻之前的变更已经持久化了。
当系统出现意外时,可能导致内存(MemStore)中的数据丢失,此时使用Log(WAL log)来恢复checkpoint之后的数据。
HBase三个重要机制
1、flush机制
2、compact机制
3、split机制
注:HBase是面向列族的存储系统,列存储,而不是列式存储。