前言
HBase,是基于Google Bigtable实现的开源、分布式、可伸缩的列式存储数据库。
诞生于Hadoop,也是Hadoop生态的重要一环,如今作为一个Apache顶级项目,早已经不能将其仅仅看作Hadoop的一部分,基于Storm,Spark等框架的数据处理方案中,都有它的身影,可以说它已经成为大数据工具箱中非常重要的一种数据存储工具,也因此必然会被很纳入很多人学习计划。
对于任何一个新技术的介绍,我认为一种有效的学习方式是:对其有简要认知后,通过Quick Start式的使用,获得直观的感知,消除距离感,然后再带着使用过程中的疑问去了解其背后的真相,最后支撑我们将其应用到实际工程。
从关系型数据库模型来演变理解Hbase
在说Hase是个啥家伙之前,首先我们来看看两个概念,面向行存储和面向列存储。
面向行存储,我相信大伙儿应该都清楚,我们熟悉的RDBMS就是此种类型的,面向行存储的数据库主要适合于事务性要求严格场合,或者说面向行存储的存储系统适合OLTP,但是根据CAP理论,传统的RDBMS,为了实现强一致性,通过严格的ACID事务来进行同步,这就造成了系统的可用性和伸缩性方面大大折扣,而目前的很多NoSQL产品,包括Hbase,它们都是一种最终一致性的系统,它们为了高的可用性牺牲了一部分的一致性。好像,我上面说了面向列存储,那么到底什么是面向列存储呢?
相信各位对Mysql的概念比较熟,那我们从Mysql入手来介绍。
假如系统中有一个User表,如果按照传统的RDBMS的话,User表中的列是固定的,比如schema 定义了name,age,sex等属性。
这种关系型数据结构的存储相信已经是非常熟悉了。但在Hbse,或是说在Nosql里面,却不是这样了。
新技术的学习,避免不了又是学习很多的术语,在解释之前,我们先说说在Hbase里面的术语。
表(table):一张表中包含若干行。
行(row):一行包括一个行键(row key)和若干列族,一张表中的行按照行键排序,并用行键作为索引。图中展示了一个行键为1、2、3的行。
列族(column family):每个列族包含若干个列,列族需要在建表时预定义,运行期间可以动态加入新的列。图中的"private"、"public"就是row1行中的两个列族。
在物理层面,HBase的数据存储是在列族这一层级进行组织,每个列族单独存储。所以一般我们在开发中,指定列族名就用一个字母,并且不会超过两个。
列(column):每个列都归属于某个列族,以列族名作为前缀,通常使用列族名:修饰符的形式来标识一个列,可以将其中的修饰符部分看作列名。图中的"private:name"和"priavte:phone"即是列族private中的成员。
单元格(cell):存储的每一个值存放在一个单元格中,由[行,列,版本号]来唯一指向一个单元格。
版本(version):版本号默认是时间戳形式,同一列中可能包含若干单元格,这些单元格由版本号唯一区分,根据版本号降序排列,HBase查询时,如果不指定版本号,默认返回最新的值。版本是HBase多维特性的表现。
HBase 与Mysql关系型数据库非常不一样。HBase 是一个稀疏的、分布式、持久、多维、排序的映射,它以行键(row key),列键(column key)和时间戳(timestamp)为索引。你可能会听到人们称呼它为 key-value 存储的、面向列族的数据库,或者是存储不同版本的映射的映射的数据库。
理解Column Family和RegionServer
从关系型数据库模型来辅助理解,好像是一张表,被两个列族垂直纵向切割了。每一个切割的单元,我们就把它称之为一个列族。
如果纵向的切割,称之为列族,那横向的切割是什么?
对,没错,就是RegionServer,除了RegionServer,hbase里面还有其他的组件。
先从粗粒度对HBase的架构进行简单了解吧:
HMaster:主要负责监控集群、管理RegionServers的负责均衡等,可以用主-备形式部署多个Master。
HRegionServers:负责响应用户的I/O操作请求,客户端对HBase读写数据是与RegionServer交互。
Zookeeper:负责选举Master的主节点;服务注册;保存RegionServers的状态等。可以使用系统内建的zookeeper,也可以使用独立的zookeeper,只需要在配置文件中调整即可。
HDFS:真正的数据持久层,并非必须是HDFS文件系统,但搭配HDFS是最佳选择,也是目前应用最广泛的选择。
整体的理解Hbase架构
相关组件的介绍如下:
Client
包含访问HBase的接口并维护cache来加快对HBase的访问
Zookeeper
保证任何时候,集群中只有一个master
存贮所有Region的寻址入口。
实时监控Region server的上线和下线信息。并实时通知Master
存储HBase的schema和table元数据
Master
为Region server分配region
负责Region server的负载均衡
发现失效的Region server并重新分配其上的region
管理用户对table的增删改操作
RegionServer
Region server维护region,处理对这些region的IO请求
Region server负责切分在运行过程中变得过大的region
HLog(WAL log):
HLog文件就是一个普通的Hadoop Sequence File,Sequence File 的Key是HLogKey对象,HLogKey中记录了写入数据的归属信息,除了table和 region名字外,同时还包括sequence number和timestamp,timestamp是” 写入时间”,sequence number的起始值为0,或者是最近一次存入文件系 统中sequence number。
HLog SequeceFile的Value是HBase的KeyValue对象,即对应HFile中的 KeyValue
Region
HBase自动把表水平划分成多个区域(region),每个region会保存一个表里面某段连续的数据;每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,region就会等分会 两个新的region(裂变);
当table中的行不断增多,就会有越来越多的region。这样一张完整的表 被保存在多个Regionserver上。
Memstore 与 storefile
一个region由多个store组成,一个store对应一个CF(列族)
store包括位于内存中的memstore和位于磁盘的storefile写操作先写入memstore,当memstore中的数据达到某个阈值,hregionserver会启动flashcache进程写入storefile,每次写入形成单独的一个storefile
当storefile文件的数量增长到一定阈值后,系统会进行合并(minor、 major compaction),在合并过程中会进行版本合并和删除工作 (majar),形成更大的storefile。
当一个region所有storefile的大小和超过一定阈值后,会把当前的region分割为两个,并由hmaster分配到相应的regionserver服务器,实现负载均衡。
客户端检索数据,先在memstore找,找不到再找storefile
HRegion是HBase中分布式存储和负载均衡的最小单元。最小单元就表示不同的HRegion可以分布在不同的HRegion server上。
HRegion由一个或者多个Store组成,每个store保存一个columns family。
每个Strore又由一个memStore和0至多个StoreFile组成。
归纳总结如下图: