HBase的架构、数据结构和进阶原理(读写流程、flush、合并、拆分)详解

目录

一、HBase架构

1、Client

2、Zookeeper

3、HMaster(类似NameNode)

4、HregionServer(类似DataNode)

5、HDFS

6、HRegion

7、Store

8、HFile

9、MemStore

10、WAL(Write-Ahead logs)

11、HBase Meta表

二、HBase数据结构

1、RowKey(行键)

2、Column Family(列族)

3、Cell(单元)

4、TimeStamp(时间戳)

5、NameSpace(命名空间)

三、HBase进阶原理

1、写流程

2、读流程

3、MemStore Flush

4、StoreFile Compaction

5、Region Split


一、HBase架构

从图中可以看出,HBase是由Client、Zookeeper、HMaster、HRegionServer、HDFS等几个组件组成。

下面介绍一下几个组件的相关功能:

1、Client

Client包含了访问HBase的接口,另外Client还维护了对应的cache来加速HBase的访问,比如cache的.META元数据的信息。

2、Zookeeper

HBase通过Zookeeper来做master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等工作。具体工作如下:

  • 通过Zookeeper来保证集群中只有1个master在运行,如果master异常,会通过竞争机制产生新的master提供服务
  • 通过Zookeeper来监控RegionServer的状态,当RegionServer有异常的时候,通过回调的形式通知master、RegionServer上下线的信息
  • 通过Zookeeper存储元数据的统一入口地址

3、HMaster(类似NameNode)

master节点的主要职责如下:

  • 为RegionServer分配Region
  • 维护整个集群的负载均衡
  • 维护集群的元数据信息
  • 发现失效的Region,并将失效的Region分配到正常的RegionServer上
  • 当RegionServer失效的时候,协调对应Hlog的拆分

4、HregionServer(类似DataNode)

HregionServer直接对接用户的读写请求,是真正的“干活”的节点。它的功能概括如下:

  • 管理master为其分配的Region
  • 处理来自客户端的读写请求
  • 负责和底层HDFS的交互,存储数据到HDFS
  • 负责Region变大以后的拆分
  • 负责Storefile的合并工作

5、HDFS

HDFS为HBase提供最终的底层数据存储服务,同时为HBase提供高可用(Hlog存储在HDFS)的支持,具体功能概括如下:

  • 提供元数据和表数据的底层分布式存储服务
  • 数据多副本,保证的高可靠和高可用性

6、HRegion

HBase表的分片,HBase表会根据RowKey值被切分成不同的HRegion存储在RegionServer中,每个HRegion会分散在不同的RegionServer中,但一个HRegion是不会拆分到多个RegionServer上的。 HRegion是Hbase中分布式存储和负载均衡的最小单元。

这里写图片描述

7、Store

每个HRegion由多个Store构成,每个Store由一个MemStore和0或多个StoreFile组成,每个Store保存一个Columns Family。

这里写图片描述

8、HFile

这是在磁盘上保存原始数据的实际的物理文件,是实际的存储文件。HRegion虽然是分布式存储的最小单元,但并不是存储的最小单元。StoreFile是以HFile的形式存储在HDFS的。

HFile的格式参考如下:

Hbase系统架构及数据结构

HFile分为六个部分:

  • Data Block 段–保存表中的数据,这部分可以被压缩
  • Meta Block 段 (可选的)–保存用户自定义的kv对,可以被压缩。
  • File Info 段–Hfile的元信息,不被压缩,用户也可以在这一部分添加自己的元信息。
  • Data Block Index 段–Data Block的索引。每条索引的key是被索引的block的第一条记录的key。
  • Meta Block Index段 (可选的)–Meta Block的索引。
  • Trailer– 这一段是定长的。保存了每一段的偏移量,读取一个HFile时,会首先读取Trailer,Trailer保存了每个段的起始位置(段的Magic Number用来做安全check),然后,DataBlock Index会被读取到内存中,这样,当检索某个key时,不需要扫描整个HFile,而只需从内存中找到key所在的block,通过一次磁盘io将整个 block读取到内存中,再找到需要的key。DataBlock Index采用LRU机制淘汰。

HFile的Data Block,Meta Block通常采用压缩方式存储,压缩之后可以大大减少网络IO和磁盘IO,随之而来的开销当然是需要花费cpu进行压缩和解压缩。目标HFile的压缩支持两种方式:Gzip,Lzo。

9、MemStore

内存存储存当前的数据操作,所以当数据保存在WAL中之后,RegsionServer会在内存中存储键值对。

10、WAL(Write-Ahead logs)

当对HBase读写数据的时候,数据不是直接写进磁盘,它会在内存中保留一段时间(时间以及数据量阈值可以设定)。但把数据保存在内存中可能有更高的概率引起数据丢失,为了解决这个问题,数据会先写在一个叫做Write-Ahead logfile的文件中,然后再写入内存中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。

11、HBase Meta表

HBase有一个叫做Meta的特殊的目录表,用于保存集群中Regions的位置信息(Region列表)。ZooKeeper存储着Meta表的位置。

 

二、HBase数据结构

1、RowKey(行键)

与nosql数据库们一样,RowKey是用来检索记录的主键。访问HBASE table中的行,只有三种方式:

1)通过单个RowKey访问(get)

2)通过RowKey的range(正则)(like)

3)全表扫描(scan)

RowKey行键 (RowKey)可以是任意字符串(最大长度是64KB,实际应用中长度一般为 10-100bytes),在HBASE内部,RowKey保存为字节数组。存储时,数据按照RowKey的字典序(byte order)排序存储。设计RowKey时,要充分排序存储这个特性,将经常一起读取的行存储放到一起。(位置相关性)

2、Column Family(列族)

列族:HBASE表中的每个列,都归属于某个列族。列族是表的schema的一部 分(而列不是),必须在使用表之前定义。列名都以列族作为前缀。例如 courses:history,courses:math都属于courses 这个列族。

3、Cell(单元)

由{rowkey, column Family:columu, version} 唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存贮。

关键字:无类型、字节码

4、TimeStamp(时间戳)

HBASE 中通过rowkey和columns确定的为一个存贮单元称为cell。每个 cell都保存 着同一份数据的多个版本。版本通过时间戳来索引。时间戳的类型是 64位整型。时间戳可以由HBASE(在数据写入时自动 )赋值,此时时间戳是精确到毫秒 的当前系统时间。时间戳也可以由客户显式赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。每个 cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。

为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,HBASE提供 了两种数据版本回收方式。一是保存数据的最后n个版本,二是保存最近一段 时间内的版本(比如最近七天)。用户可以针对每个列族进行设置。

5、NameSpace(命名空间)

命名空间的结构:

 

1) Table:表,所有的表都是命名空间的成员,即表必属于某个命名空间,如果没有指定,则在default默认的命名空间中。

2) RegionServer group一个命名空间包含了默认的RegionServer Group。

3) Permission权限,命名空间能够让我们来定义访问控制列表ACL(Access Control List)。例如,创建表,读取表,删除,更新等等操作。

4) Quota限额,可以强制一个命名空间可包含的region的数量。

 

三、HBase进阶原理

1、写流程

1)Client先访问ZooKeeper,获取hbase:meta表位于哪个RegionServer;
2)访问对应的RegionServer,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个Region Server中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问;
3)与目标RegionServer进行通讯;
4)将数据顺序写入(追加)到WAL;
5)将数据写入对应的MemStore,数据会在MemStore进行排序;
6)向客户端发送ack;
7)等达到MemStore的刷写时机后,将数据刷写到HFile。

2、读流程

1)Client先访问ZooKeeper,获取hbase:meta表位于哪个RegionServer;
2)访问对应的RegionServer,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个Region Server中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问;
3)查询数据,如果Block Cache没有对应数据,同时读取内存(MemStore)和磁盘(StoreFile)中的数据(并将磁盘的数据缓存到Block Cache,LRU算法),比较时间戳返回对应的数据。
4)如果Block Cache有对应数据,直接比较和MemStore中数据的最大时间戳,返回该数据。

3、MemStore Flush

MemStore数据达到阈值,将数据刷到硬盘。将内存中的数据删除,同时删除HLog中的历史数据。

MemStore刷写时机:

1)当某个MemStore的大小达到了hbase.hregion.memstore.flush.size (默认值128M),其所在Region的所有MemStore都会刷写。
2)RegionServer中的MemStore大小超过hbase.regionserver.global.memstore.size(默认大小为堆大小的40%)
3)到达自动刷写的时间也会触发MemStore Flush,自动刷新的时间间隔由该属性进行配置hbase.regionserver.optionalcacheflushinterval (默认1小时)。

4、StoreFile Compaction

由于MemStore每次刷写都会生成一个新的HFile,且同一个字段的不同版本(timestamp)和不同类型(Put/Delete)有可能会分布在不同的HFile中,因此查询时需要遍历所有的HFile。为了减少HFile的个数,以及清理掉过期和删除的数据,会进行StoreFile Compaction。

Compaction分为两种,分别是Minor Compaction和Major Compaction。Minor Compaction会将临近的若干个较小的HFile合并成一个较大的HFile,但不会清理过期和删除的数据。Major Compaction会将一个Store下的所有的HFile合并成一个大HFile,并且会清理掉过期和删除的数据。

StoreFile Compaction触发时机:

当数据块达到 4 块,Hmaster触发合并操作,Region将数据块加载到本地,进行合并;当合并的数据超过 256M,进行拆分,将拆分后的Region分配给不同的HRegionServer管理(一个表中的Region就会被不同的HRegionServer管理,分布式存储,高可用容灾); 当 HRegionServer宕机后,将 HRegionServer上的HLog拆分,然后分配给不同的HRegionServer加载,修改.META.;

5、Region Split

默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的Region Server,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer

Hbase系统架构及数据结构

Region Split时机:

当1个Region中的某个Store下所有StoreFile的总大小超过hbase.hregion.max.filesize,该Region就会进行拆分(0.94 版本之前)。
当1个Region中的某个Store下所有StoreFile的总大小超过Min(R^2 * "hbase.hregion.memstore.flush.size",hbase.hregion.max.filesize"),该Region就会进行拆分,其中R为当前Region Server中属于该Table的个数(0.94 版本之后)。

猜你喜欢

转载自blog.csdn.net/weixin_43230682/article/details/107511310