首页 > 代码库 > 初识HBase
初识HBase
今天我们初步了解一些HBase相关的内容:包括HBase的简单介绍、以及HBase的逻辑模型和物理模型。
HBase简介
HBase是Google BigTable的开源实现。我们可以理解为它是山寨了Google的BigTable。Google的BigTable的思想,是用一个很大的表(很Big的Table)来记录所有的数据,就是说一个数据库中只有一个大表,我们要记录的任何数据都是这个大表中的一行记录。BigTable具体是如何实现的,我们不得而知,因为它不是开源的。不过Google曾经发布了一篇论文来描述BigTable的思想,受此启发才产生了HBase。HBase之外还有一个分布式数据库产品Cassandra,它也是参考了BigTable模型。此外,Google还有两篇非常重要的论文:Google FS、MapReduce。Hadoop生态圈的两大基石MapReduce和HDFS就是受这两篇论文的启发而完成的。这三篇论文合在一起被称作Google的三大论文,在大数据的发展中有非常重要的地位。大家可以从网上找到这三篇论文。原版是英文的,不过已经有人翻译成中文了。
HBase是一个分布式的、面向列的数据库。分布式的特性是说我们可以使用大量的机器搭建起大规模的存储集群。当现有集群性能不足的时候,可以简单地添加一些机器来扩充节点。一般来说HBase集群对节点机器的要求不是很高,一般普通的PC机就能满足需求。如果机器的性能非常好,还可以考虑在单机上安装Docker来创建HBase集群。至于面向列,是说HBase中的记录是按列来进行存储和维护的。HBase中也有行的概念,不过与其说是行,倒不如说是Key/Value对更恰当一些。关于面向列这一点我们稍后会仔细地说,现在先继续。
HBase主要适用于高速读写的场景。尤其是高速写(insert)的场景,HBase有很大的优势。我工作中的一个项目,高峰时每小时需要入库的数据量达到10个G左右。对于传统关系型数据库来说,这样的写入规模不是不能支撑下来,但是难免会需要多付出一些代价。使用HBase呢,我们只是用了3台配置一般的服务器组成的HBase集群就很轻松得完成了数据的写入。当然HBase也是有一些局限性的:一些在关系型数据库中很简单的操作,比如order、还有group by这样的操作,要在HBase中实现就是非常困难的事情。所以HBase还是比较适合一些简单的数据结构,以及简单的查询操作。
HBase逻辑模型
前面我们说过,HBase是山寨了Google的BigTable,Google的BigTable的思想是用一个大表来记录所有的数据。我们来看一个例子:
假设我们需要存储员工信息。表的结构是这样子的:员工信息(ID,姓名,性别,年龄)。在关系型数据库中这是一张非常简单的表了。
用BigTable的思想该怎么做呢——我们只需要一张表三个列就可以保存这些信息。该怎样用三个列来记录这些信息呢,大家可以想一下。
我们可以用这样的三个列来保存数据:
- 第一个列是数据的主键,在这里可以是员工ID;
- 第二列是属性的名称,比如姓名这个属性、性别这个属性;
- 第三列是属性的值。
实际上就是将原来关系型数据库中的一行记录转成了多行记录。根据这个思想,任何一张有主键的表都可以转成BigTable模型下的记录。不管是员工信息、部门信息、设备信息、资产信息还是考勤信息都可以放在一张表里面,用三个列来记录。
刚才我们说的是BigTable的思想,那么HBase中是如何做的呢?下面这张表是一份HBase存储的数据的示例,大家看一下:
虽然说HBase是山寨了BIgTable,但是HBase和BigTable还是有很多不同之处的,它只是学习了BigTable的一些思想。BigTable是用一张大表存储了所有的记录,在HBase中却是允许有很多张表的。每张表的结构也和BigTable有些相似,也是由行和列组成的二维表,大家看一下上面这张表:它的第一列是行键,就相当于表的主键;第二列是列名,这里的列名是比较奇怪的——中间有一个冒号分隔。HBase中列的结构就是这样子的:在冒号的前面是列族(columnFamily)名称,冒号后面是列限定符的名称,这两者合起来构成了HBase中的列。比如第一行记录,列族是basic、列限定符是name;第二行列族是basic,列限定符是age。第三列是一个时间戳,通常是采用这一行记录的创建时间,时间戳还有一个非常重要的作用就是标识这一行数据的版本。第四列就是列的值了。
HBase的逻辑结构就是这样子的:
- HBase以表的形式存储数据
- 表由行与列组成,列划分为若干列族,由行与列确定了HBase最基本的存储单元
- 每个存储单元可以存储一份数据的多个版本,由时间戳来标识
我们再来看一些HBase逻辑模型中的关键概念。
1. 行键(RowKey)
- 行键是一份数据的唯一标识。(既然行键是唯一索引,为什么我们前面的那个示例表中相同的行键会出现两次呢,这是因为出现了数据的更新。HBase是允许更新和删除数据的,但是它的更新比较奇怪,是再插入一条新的纪录,同时旧的记录也会保存。也就是说对一行记录进行一次更新以后,这行记录会在HBase中保存两个版本。这个版本用记录的时间戳来标识,我们默认取时间戳最新的版本。具体可以有多少个版本是在建表时进行设置的。当一行记录的版本超过设置的数量以后,最早的记录就会被删除掉。HBase中的删除也是比较奇怪的,它没办法立即删除一条记录,只是为这个版本的记录打上一个删除标记。因为HBase一直在不停地执行一个将小文件合并成大文件的操作,这个操作叫做compact,以后我们会详细说一下。在compact的时候遇到了打上了删除标记的记录,就会放弃将它合并到大文件,从而实现了真正的删除)
- 行键是字节数组,这意味着我们不仅可以使用字符串或数字来做为行键,还可以使用一些非可视化字符;
- 表中的行根据行键进行排序,数据按照Row key的字节序(byte order)排序存储;
- 所有对表的访问都要通过行键 (单个RowKey访问,或RowKey范围访问,或全表扫描)(我们可以认为行键是HBase表的默认的唯一索引,不过我们也可以通过冗余存储的方式实现二级索引)
说到了查询,不妨多聊一些。
2. 列族(ColumnFamily)
-- CF需要在表定义时给出(这里需要解释下,在表定义的时候,必需至少提供一个列族,表创建成功后还可以添加更多的列族,但是添加前需要先禁用表),且必须是可打印字符(这一点是HBase中非常特殊的一点)
-- 每个CF可以有一个或多个列成员(ColumnQualifier,这个可以是任意二进制数组),列成员不需要在表定义时给出,新的列族成员可以随后按需、动态加入
-- 数据按CF分开存储,HBase所谓的列式存储就是根据CF分开存储(每个CF对应一个Store),这种设计非常适合于数据分析的情形
3)时间戳(TimeStamp)
-- 每个Cell可能又多个版本,它们之间用时间戳区分
4)单元格(Cell)
-- Cell 由行键,列族:限定符,时间戳唯一决定
-- Cell中的数据是没有类型的,全部以字节码形式存贮
但是在HBase中允许创建多个表。虽然,但是HBase也有一些
参考文档
http://blog.csdn.net/zhouzhaoxiong1227/article/details/46778033
########################
初识HBase