HBase可以认为是一种类似于数据库的存储层,并且HBase是一种列式的分布式数据库(由谷歌当年的BigTable论文而生),也就是说HBase适用于结构化的存储。注意HBase底层依然依赖HDFS来作为其物理存储,这与Hive类似 。
Hive和HBbase的区别
Hive的适用场景:
- Hive适用于对一段时间内的数据进行分析查询(适用于非实时的查询,它的结果需要很长时间才返回结果)
- Hive一般只要有Hadoop便可以动作,可以直接使用HQL(一种类SQL语言)。
- 默认情况下Hive的存储层是HDFS。
HBase的适用场景
-
HBase适合用来进行大数据的实时查询(eg Facebook用HBase进行消息和实时的分析)。
-
HBase本身只提供Java的API接口,并不直接支持SQL的语句查询,想要在HBase上使用SQL,有两种方案:
- 联合使用HBase和Apache Phonenix,不经过MapReduce,实用性优于Hive和HBase的存储层。
- 联合使用Hive和HBase,无法绕过MapReduce,实用性还是有一定的损失。
注意:Phoenix 在 HBase 之上提供了 OLTP 相关的功能,例如完全的 ACID支持、SQL、二级索引等,此外 Phoenix 还提供了标准的 JDBC 的 API。在 Phoenix 的帮助下,RDBMS的用户可以很容易的使用 HBase,并且迁移原有的业务到 HBase 之中。
-
默认情况下HBase的存储层是HDFS,但是HBase在一些特殊情况下可以直接使用本机的文件系统。
HBase与传统关系数据库的区别
表1 HBase和RDBMS的区别(传统的关系型数据库,全称Relational Database Management System)
HBase | RDBMS | |
---|---|---|
硬件架构 | 类似于Hadoop的分布式集群,硬件成本低廉 | 传统的多核系统,硬件成本昂贵 |
容错性 | 由软件架构实现,由于由多个节点组成,所有不必担心部分节点宕机 | 一般需要额外硬件设备实现HA机制 |
数据库大小 | PB | GB、TB |
数据库排布方式 | 稀疏的、分布的多维的Map | 以行和列组织 |
数据类型 | Bytes | 丰富的数据类型 |
事务支持 | ACID只支持单个Row级别 | 全面的ACID支持,对Row和表 |
查询语言 | 只支持Java API(除非与其他框架一起使用,如Phonenix、Hive) | SQL |
索引 | 只支持Row-Key(除非与其他技术一起应用,如Phonenix, Hive) | 支持 |
吞吐量 | 百万查询/每秒 | 数千查询/每秒 |
注意: HBase设计的目标不是替代RDBMS,而是对RDBMS的一个重要补充,尤其是对大数据的场景。
对比了上述不同点之后,让我们来看看数据如何在HBase和RDBMS中排布的。
表2 数据在RDBMS中的排布示例
ID | 姓 | 名 | 密码 | 时间戳 |
---|---|---|---|---|
1 | 张 | 三 | 111 | 20160719 |
2 | 李 | 四 | 222 | 20160720 |
表3 数据在HBase中的排布示例(逻辑上)
Row-Key | Value(CF、Qualifier、Version) |
---|---|
1 | info{‘姓’: ‘张’,‘名’:‘三’} pwd{‘密码’: ‘111’} |
2 | Info{‘姓’: ‘李’,‘名’:‘四’} pwd{‘密码’: ‘222’} |
如上述表格所示,HBase中首先会有Column Family的概念,简称为(CF)。CF一般用于将相关的列(Column)组合起来。在物理上HBase其实是按照CF存储的,只是按照Row-key将相关CF中的列关联起来。 物理上的数据排布大致如表4 所示
表4 数据在HBase中的排布
Row-Key | CF:Column-Key | 时间戳 | Cell Value |
---|---|---|---|
1 | info:fn | 123456789 | 三 |
1 | info:ln | 123456789 | 张 |
2 | info:fn | 123456789 | 四 |
2 | info:ln | 123456789 | 李 |
前面已经提到过HBase是按照CF来存储数据的。在表3 中,有info和pwd两个CF,其中info存储着姓名相关的列数,而pwd存储着密码相关的数据。上表是info这个CF存储在HBase中的数据排布(pwd的数据排布是类似的)。上表中的fn和ln称之为Column-key或者Qualifier。在HBase中,Row-key + CF + Quaifier + 时间戳 ** 能够定位到一个单元格** (HBase中每个单元格默认有3个时间戳的版本数据)。
图1 HBase中逻辑上数据的排布与物理上排布的关联
从上图可以看出
- Row1和Row5的数据分布在两个CF中,并且每个CF对应一个HFile。
- 逻辑上每一行中的一个单元格数据,对应于HFile中的一行,然后当用户按照Row-key查询数据的时候,HBase会遍历两个HFile,通过相同的Row-key标识,将相关的单元格组织成行返回,这是逻辑上的行数据 。
RDBMS一般都是以SQL作为主要的访问方式。而HBase是一种NoSQL 数据库。HBase是大型分布式NoSQL数据库。从技术上来说,HBase更像是数据存储而非数据库 (HBase和HDFS都属于大数据的存储层)。因此,HBase缺少很多RDBMS特性,如列类型,二级索引,触发器和高级查询语言等,然而,HBase也具有许多其他特征同时支持线性化和模块化扩充 (可通过增加Region Server的数量扩展HBase)。
HBase的模块组成
图2 HBase的模块组成
注意: HBase支持直接在本地文件系统上运行,但这样的HBase只能运行在一台机器上,是所谓的HBase的单机模式。在分布式的生成环境中,HBase需要运行在HDFS之上,以HDFS作为基础的设施 。
- Master
- 侦测各个Region Server的状态,并平衡Region Server之间的负载。
- 负责分配Region给Region Server。
- 可以基于zk实现HA,HBase允许多个Master节点共存,正在服务的Master宕机后,其他的Master会接管HBase集群。
- Region Server
- 对于一个Region Server而言,其包括了多个Region。其作用包括管理表格和实现读写操作。
- client直接连接Region Server,并通信获取HBase中的数据,Region是真实存放HBase数据的地方。
- Region是HBase可用性和分布式的基本单位 。如果当一个表格由多个CF组成时,那么表的数据将存放在多个Region之间,并且在每个Region中会关联多个存储的单元(Store)。
- Zookeeper
- Zookeeper是作为HBase Master的HA解决方案,Zookeeper保证至少有一个HBase Master处于运行状态(几乎所有的分布式大数据相关的开源框架都依赖于ZK实现HA)。
- Zookeeper负责Region和Region Server的注册。
图3 HBase的工作原理
当一个client需要访问HBase集群时,Client需要先和Zookeeper来通信,然后才会找到对应的Region Server。每一个Region Server管理多个Region,Region是HBase并行化的基本单元,数据存储在Region中 。注意,每一个Region只存储一个Column Family的数据,并且是该Column Family中的一段 。Region所存储的数据大小是有上限的,当达到该上限时(Threshold),Region会进行分裂,数据也会分裂到多个Region中,这样可以提高数据的并行化,以及提高数据的容量。
Region包含多个Store对象。每个Store包含一个MemStore和一个或多个HFile。MemStore是数据在内存中的实体,一般都是有序的。 当数据向Region写入的时候,会先写入MemStore。当MemStore中的数据需要向底层文件倾倒(dump)时(例如MemStore中的数据量达到MemStore配置的最大值),Store会创建StoreFile,StoreFile是对HFile一层封装。所以MemStore中的数据最终都会写入到HFile中,也就是磁盘IO 。由于HBase底层依靠HDFS,因此HFile都存储在HDFS之中。
在HBase的工作过程中,如何保证数据的可靠性?HBase中HLog机制是WAL的一种实现
答:每个Region Server中都会有一个HLog的实例,RegionServer会将更新操作(如Put,Delete)先记录到HLog的实例,然后将其写入Store的MemStore,最终MemStore会将数据写入到持久化的HFile中。这样就保证了HBase的写的可靠性。
WAL (WriteAheadLog):预写日志,将操作先写入持久化存储,然后再真正执行,保证断电能够恢复操作。
图4 HFile的结构
- HFile由很多个数据块(Block)组成,并且有一个固定的尾块。
- 数据块由一个Header和多个Key-Value的键值对组成。
- 尾块中包含数据相关的索引信息,系统也是通过尾块的索引信息找到HFile中的数据。
- HFile中的数据块的大小默认为64KB,调整该值可以提高HBase的性能。
- 如果访问HBase数据库的场景多为有序访问 ,则建议将该值设置的大一些。
- 如果访问HBase数据库的场景多为随机访问 ,则建议将该值设置的小一些。
图5 HBase的数据映射关系
总结,HBase其实就是一个有序的多维Map,其中每一个Row-key映射了许多数据,这些数据存储在Column Family中的Column。
笔者初次接触HBase,处于扫盲阶段,如任何不对之处,欢迎指出。