一起学HBase——简单介绍HBase各种组件

HBase是谷歌BigTble的开源实现。谷歌的三篇论文拉开了大数据江湖的序幕,铸就了现在以Hadoop为主的大数据技术生态圈。而HBase是开源的大数据数据库,和传统的行式数据库不同的是,HBase是列式数据库。列式数据的特点是开源横向扩展,将一张表的数据存储在hadoop集群的不同datanode中,一张表的存储量可以达到T级别。这是行式关系型数据库无法实现的。本文主要讲解HBase的基本概念,只有概念清楚了才能更好的在我们的系统中使用HBase。

核心组件介绍

Table:可理解为传统数据库中的一个表,但因为SchemaLess的设计,它较之传统数据库的表而言,在设计上更加灵活。

Region:将表横向切割为一个个子表,子表在HBase中被称之为Region。

RegionServer:数据服务进程,Region必须部署在某一个RegionServer上才可以提供读写服务。

HFile:HBase数据库在底层分布式文件系统中的文件组织形式。

Column Family:一些列的集合。不同的Column Family数据被存储在不同的路径中。

MemStore:用来在内存中缓存一定大小的数据,达到设定的阈值后批量写入到底层文件系统中。数据是有序的。

下图清晰的展示了Table,Region,RegionServer,HFile,MemStore,Column Family在HBase的逻辑关系。
HBase基础知识

下图显示了HBase集群中的关键进程
HBase基础知识
Zookeeper:HBase集群的调度器,可以用于将HBase RegionServer信息注册到zookeeper中,查询HBase RegionServer状态信息,HMaster启动时会将HBase系统表-ROOT-加载到zookeeper集群中,通过zookeeper集群可以获取当前系统表.META.的存储所对应的RegionServer信息 。
Master,通过jps命令显示的进程名称是HMaster,在负责表管理操作,Region到各个RegionServer的分配以及RegionServer Failover的处理等。

RegionServer进程提供数据读写服务。

NameNode,Hadoop进程,处理来自Master的请求,H管理DFS文件系统的命名空间NameSpace。

DataNode,Hadoop数据节点进程,HBase的所有数据都存在Hadoop的DataNode中。

KeyValue数据存储结构

HBase所存储的数据是以KeyValue形式存放的,KeyValue有特定的数据结构,如下图所示,一个KeyValue可以理解成HBase表中的一个列,当一行存在多个列时,将包含多个KeyValue,同一行的KeyValue有可能存储在不同的文件中,但在读取时,会按需合并在一起返回给客户端。
HBase基础知识

用户写数据时,需要定义用户数据的RowKey,指定每一列所存放的Column Family,并且为其定义相应的Qualifier(列名),Value部分存放用户数据。Hbase中每一行可拥有不同的KeyValues,这就是HBase Schema-less的特点。

HBase中支持数据的多版本,通过带有不同时间戳的多个KeyValue版本来实现的,如下图所示。
HBase基础知识

HBase所保存的版本数据是可配置的,默认存放3个版本。在普通的读取流程中,旧版本的数据时不可见的,但通过制定版本数或者版本号的读取,可以获取旧版本数据。下图是普通读取刘恒与多版本读取流程的对比。

灵活的列定义

用户数据存入到HBase表中时,需要进行Qualifier(KeyValue/列)设计。一个最简单的设计是保持HBase的列与用户数据的列一致,如下图1的设计。这种设计,基本上与关系型数据库的设计是一致的,但这种设计会带来较大的数据冗余(KeyValue结构开销)。但HBase基于KeyValue的接口,决定了这种设计可以是非常灵活的,例如,我们也可以考虑为HBase的每一行只设置两个列,其中,Name为一个列,其他内容合并到一个列中,如下图2所示。
HBase基础知识

尽管我们在使用HBase表存放数据的时候,需要预先做好列的设计。但这个设计仅仅由应用层感知,HBase并没有存放任何的Schema信息来描述这个设计。也就是说,应用层需要知道为每一个表/每一行设计了什么样的列(KeyValue),然后在地区的时候做相应的解析。既然HBase中并没有Schema信息,name,每一行中的列,也可以是任意添加的。如下图所示,绿色背景的KeyValue为后续增加的。
HBase基础知识

Column Family

假设为表设置了两个列族,而且,定义了每一个列簇中要存放的列,如下图所示:
{Name} -> Column Family - A, {City,Phone,Gender} -> Column Familly-B。不同列簇的数据会被存储在不同的路径中。即,设置多个列簇时一行数据可能存在于两个路径中。整行读取的时候,需要将两个路径中的数据合并在一起才可以获取完整的一行记录。但如果仅仅读取Name一列的话,只需要读取Column Family-A即可。 HBase基础知识



    用心写好每篇技术文章
-----------------------------------------------------------------

    关注本人的微信公众号获取更多关于大数据机器学习方面的技术文章。