图文详解深入理解 Hbase 架构 Deep Into HBase Architecture

Posted 禅与计算机程序设计艺术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图文详解深入理解 Hbase 架构 Deep Into HBase Architecture相关的知识,希望对你有一定的参考价值。

这是一篇讲 HBase 架构的文章,简洁明了,图文并茂。

HBase数据模型和特征

HBase 数据模型(The HBase data model)

HBase 中的数据存储是面向列的,采用多层次键值映射的形式。HBase 数据模型非常灵活,它的美妙之处在于动态添加或删除列数据,而不会影响性能。HBase 可用于处理半结构化数据。它没有任何特定的数据类型,因为数据以字节存储。

数据模型逻辑组件

HBase 数据模型有一些逻辑组件,如下所示:

HBase表模型如下图所示:

HBase特点——

1、适合大数据场景:一个表可以有上十亿行,上百万列;
2、面向列:面向列(族)的存储和权限控制,列(族)独立检索;
3、稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。

HBase 的优势—— 

  1. 可以存储大型数据集 

  2. 数据库可以共享 

  3. 从千兆字节到千兆字节的经济高效 

  4. 通过故障转移和复制实现高可用性 

HBase 的缺点—— 

  1. 不支持SQL结构 

  2. 无交易支持 

  3. 仅按键排序 

  4. 集群内存问题 

HBase 和HDFS的比较 

  • HBase 提供低延迟访问,而 HDFS 提供高延迟操作。 

  • HBase 支持随机读写,而 HDFS 支持 Write once Read Many times。 

  • HBase 通过 shell 命令、Java API、REST、Avro 或 Thrift API 访问,而 HDFS 通过 MapReduce 作业访问。 

注意 – HBase 广泛用于在线分析操作,例如在银行应用程序(例如 ATM 机中的实时数据更新)中,可以使用 HBase。

HBase 架构组件

HBase 架构有 3 个主要组件:HMaster、Region Server、Zookeeper。  

HBase 3 个组件如下所述: 
 

  1. HMaster 

    负责 Region 的分配,DDL(创建,删除 table)等操作。HBase 中 Master Server 的实现是 HMaster。这是一个将区域分配给区域服务器以及 DDL(创建、删除表)操作的过程。它监控集群中存在的所有 Region Server 实例。在分布式环境中,Master 运行多个后台线程。HMaster 具有许多功能,例如控制负载平衡、故障转移等。 
     

  2. Region Server 
    负责处理数据的读写请求,客户端请求数据时直接和 Region Server 交互。HBase 表按行键范围水平划分为区域。区域是 HBase 集群的基本构建元素,由表的分布和列族组成。Region Server 在 Hadoop 集群中的 HDFS DataNode 上运行。Region Server 的区域负责几件事,例如处理、管理、执行以及在该区域集上读取和写入 HBase 操作。区域的默认大小为 256 MB。 

  3. Zookeeper 
    作为 HDFS 的一部分,负责维护集群状态。它就像 HBase 中的协调器。它提供维护配置信息、命名、提供分布式同步、服务器故障通知等服务。客户端通过zookeeper与区域服务器通信。 
     

Zookeeper 用来协调分布式系统中集群状态信息的共享。Region Servers 和 在线 HMaster(active HMaster)和 Zookeeper 保持会话(session)。Zookeeper 通过心跳检测来维护所有临时节点(ephemeral nodes)。

每个 Region Server 都会创建一个 ephemeral 节点。HMaster 会监控这些节点来发现可用的 Region Servers,同样它也会监控这些节点是否出现故障。

HMaster 们会竞争创建 ephemeral 节点,而 Zookeeper 决定谁是第一个作为在线 HMaster,保证线上只有一个 HMaster。在线 HMaster(active HMaster) 会给 Zookeeper 发送心跳,不在线的待机 HMaster (inactive HMaster) 会监听 active HMaster 可能出现的故障并随时准备上位。

如果有一个 Region Server 或者 HMaster 出现故障或各种原因导致发送心跳失败,它们与 Zookeeper 的 session 就会过期,这个 ephemeral 节点就会被删除下线,监听者们就会收到这个消息。Active HMaster 监听的是 region servers 下线的消息,然后会恢复故障的 region server 以及它所负责的 region 数据。而 Inactive HMaster 关心的则是 active HMaster 下线的消息,然后竞争上线变成 active HMaster。

(点评:这一段非常重要,涉及到分布式系统设计中的一些核心概念,包括集群状态、一致性等。可以看到 Zookeeper 是沟通一切的桥梁,所有的参与者都和 Zookeeper 保持心跳会话,并从 Zookeeper 获取它们需要的集群状态信息,来管理其它节点,转换角色,这也是分布式系统设计中很重要的思想,由专门的服务来维护分布式集群状态信息。)

HBase 底层的数据存储都是基于 Hadoop HDFS 的:

  • Hadoop DataNode 负责存储 Region Server 所管理的数据。所有的 HBase 数据都存储在 HDFS 文件中。Region Server 和 HDFS DataNode 往往是分布在一起的,这样 Region Server 就能够实现数据本地化(data locality,即将数据放在离需要者尽可能近的地方)。HBase 的数据在写的时候是本地的,但是当 region 被迁移的时候,数据就可能不再满足本地性了,直到完成 compaction,才能又恢复到本地。

  • Hadoop NameNode 维护了所有 HDFS 物理 data block 的元信息。

Regions

HBase 表(Table)根据 rowkey 的范围被水平拆分成若干个 Region。每个 region 都包含了这个region 的 start key 和 end key 之间的所有行(row)。

Regions 被分配给集群中的某些节点来管理,即 Region Server,由它们来负责处理数据的读写请求。每个 Region Server 大约可以管理 1000 个 regions。

第一次读和写操作

有一个特殊的 HBase Catalog 表叫 Meta table(它其实是一张特殊的 HBase 表),包含了集群中所有 regions 的位置信息。Zookeeper 保存了这个 Meta table 的位置。

客户端读写数据,分两步:

第一步是定位,从 Meta table 获取 rowkey 属于哪个 Region Server 管理;

第二步再去相应的 Region Server 读写数据。这里涉及到了两个 Region Server,要理解它们各自的角色功能。关于 Meta table 下面会详细介绍。

HBase Meta Table

Meta table 是一个特殊的 HBase table,它保存了系统中所有的 region 列表。这张 table 类似一个 b-tree,结构大致如下:

  • Key:table, region start key, region id

  • Value:region server

Region Server 组成

Region Server 运行在 HDFS DataNode 上,由以下组件组成:

  • WAL:Write Ahead Log 是分布式文件系统上的一个文件,用于存储新的还未被持久化存储的数据,它被用来做故障恢复。

  • BlockCache:这是读缓存,在内存中存储了最常访问的数据,是 LRU(Least Recently Used)缓存。

  • MemStore:这是写缓存,在内存中存储了新的还未被持久化到硬盘的数据。当被写入硬盘时,数据会首先被排序。注意每个 Region 的每个 Column Family 都会有一个 MemStore。

  • HFile 在硬盘上(HDFS)存储 HBase 数据,以有序 KeyValue 的形式。

HBase 写数据步骤

当客户端发起一个写数据请求(Put 操作),第一步首先是将数据写入到 WAL 中:

  • 新数据会被追加到 WAL 文件尾部。

  • WAL 用来在故障恢复时恢复还未被持久化的数据。

数据被写入 WAL 后,会被加入到 MemStore 即写缓存。然后服务端就可以向客户端返回 ack 表示写数据完成。

(点评:注意数据写入时 WAL 和 MemStore 更新的顺序,不能调换,必须先 WAL 再 MemStore。如果反过来,先更新完 MemStore,此时 Region Server 发生 crash,内存中的更新就丢失了,而此时数据还未被持久化到 WAL,就无法恢复了。理论上 WAL 就是 MemStore 中数据的一个镜像,应该保持一致,除非发生系统 crash。另外注意更新 WAL 是在文件尾部追加的方式,这种磁盘操作性能很高,不会太影响请求的整体响应时间。)

HBase MemStore

MemStore 在内存中缓存 HBase 的数据更新,以有序 KeyValues 的形式,这和 HFile 中的存储形式一样。每个 Column Family 都有一个 MemStore,所有的更新都以 Column Family 为单位进行排序。

HBase Region Flush

MemStore 中累积了足够多的的数据后,整个有序数据集就会被写入一个新的 HFile 文件到 HDFS 上。HBase 为每个 Column Family 都创建一个 HFile,里面存储了具体的 Cell,也即 KeyValue 数据。随着时间推移,HFile 会不断产生,因为 KeyValue 会不断地从 MemStore 中被刷写到硬盘上。

注意这也是为什么 HBase 要限制 Column Family 数量的一个原因。每个 Column Family 都有一个 MemStore;如果一个 MemStore 满了,所有的 MemStore 都会被刷写到硬盘。同时它也会记录最后写入的数据的最大序列号(sequence number),这样系统就能知道目前为止哪些数据已经被持久化了。

最大序列号是一个 meta 信息,被存储在每个 HFile 中,来表示持久化进行到哪条数据了,应该从哪里继续。当 region 启动时,这些序列号会被读取,取其中最大的一个,作为基础序列号,后面的新的数据更新就会在该值的基础上递增产生新的序列号。

(点评:这里有个序列号的概念,每次 HBase 数据更新都会绑定一个新的自增序列号。而每个 HFile 则会存储它所保存的数据的最大序列号,这个元信息非常重要,它相当于一个 commit point,告诉我们在这个序列号之前的数据已经被持久化到硬盘了。它不仅在 region 启动时会被用到,在故障恢复时,也能告诉我们应该从 WAL 的什么位置开始回放数据的历史更新记录。)

HBase HFile

数据存储在 HFile 中,以 Key/Value 形式。当 MemStore 累积了足够多的数据后,整个有序数据集就会被写入一个新的 HFile 文件到 HDFS 上。整个过程是一个顺序写的操作,速度非常快,因为它不需要移动磁盘头。(注意 HDFS 不支持随机修改文件操作,但支持 append 操作。)

HBase HFile 文件结构

HFile 使用多层索引来查询数据而不必读取整个文件,这种多层索引类似于一个 B+ tree

  • KeyValues 有序存储。

  • rowkey 指向 index,而 index 则指向了具体的 data block,以 64 KB 为单位。

  • 每个 block 都有它的叶索引。

  • 每个 block 的最后一个 key 都被存储在中间层索引。

  • 索引根节点指向中间层索引。

trailer 指向原信息数据块,它是在数据持久化为 HFile 时被写在 HFile 文件尾部。trailer 还包含例如布隆过滤器和时间范围等信息。布隆过滤器用来跳过那些不包含指定 rowkey 的文件,时间范围信息则是根据时间来过滤,跳过那些不在请求的时间范围之内的文件。

HFile 索引

刚才讨论的索引,在 HFile 被打开时会被载入内存,这样数据查询只要一次硬盘查询。

HBase Read 合并

我们已经发现,每行(row)的 KeyValue cells 可能位于不同的地方,这些 cell 可能被写入了 HFile,可能是最近刚更新的,还在 MemStore 中,也可能最近刚读过,缓存在 Block Cache 中。所以,当你读一行 row 时,系统怎么将对应的 cells 返回呢?一次 read 操作会将 Block Cache,MemStore 和 HFile 中的 cell 进行合并:

  • 首先 scanner 从 Block Cache 读取 cells。最近读取的 KeyValue 都被缓存在这里,这是 一个 LRU 缓存。

  • 然后 scanner 读取 MemStore,即写缓存,包含了最近更新的数据。

  • 如果 scanner 没有在 BlockCache 和 MemStore 都没找到对应的 cells,则 HBase 会使用 Block Cache 中的索引和布隆过滤器来加载对应的 HFile 到内存,查找到请求的 row cells。

之前讨论过,每个 MemStore 可能会有多个 HFile,所以一次 read 请求可能需要多读个文件,这可能会影响性能,这被称为读放大(read amplification)。

(点评:从时间轴上看,一个个的 HFile 也是有序的,本质上它们保存了每个 region 的每个 column family 的数据历史更新。所以对于同一个 rowkey 的同一个 cell,它可能也有多个版本的数据分布在不同的 HFile 中,所以可能需要读取多个 HFiles,这样性能开销会比较大,尤其是当不满足 data locality 时这种 read amplification 情况会更加严重。这也是后面会讲到的 compaction 必要的原因)

HBase Minor Compaction

HBase 会自动合并一些小的 HFile,重写成少量更大的 HFiles。这个过程被称为 minor compaction。它使用归并排序算法,将小文件合并成大文件,有效减少 HFile 的数量。

HBase Major Compaction

Major Compaction 合并重写每个 Column Family 下的所有的 HFiles,成为一个单独的大 HFile,在这个过程中,被删除的和过期的 cell 会被真正从物理上删除,这能提高读的性能。但是因为 major compaction 会重写所有的 HFile,会产生大量的硬盘 I/O 和网络开销。这被称为写放大(Write Amplification)。

Major compaction 可以被设定为自动调度。因为存在 write amplification 的问题,major compaction 一般都安排在周末和半夜。MapR 数据库对此做出了改进,并不需要做 compaction。Major compaction 还能将因为服务器 crash 或者负载均衡导致的数据迁移重新移回到离 Region Server 的地方,这样就能恢复 data locality。

Region = Contiguous Keys

我们再来回顾一下 region 的概念:

  • HBase Table 被水平切分成一个或数个 regions。每个 region 包含了连续的,有序的一段 rows,以 start key 和 end key 为边界。

  • 每个 region 的默认大小为 1GB。

  • region 里的数据由 Region Server 负责读写,和 client 交互。

  • 每个 Region Server 可以管理约 1000 个 regions(它们可能来自一张表或者多张表)。

Region 分裂

一开始每个 table 默认只有一个 region。

当一个 region 逐渐变得很大时,它会分裂(split)成两个子 region,每个子 region 都包含了原来 region 一半的数据,这两个子 region 并行地在原来这个 region server 上创建,这个分裂动作会被报告给 HMaster。处于负载均衡的目的,HMaster 可能会将新的 region 迁移给其它 region server。

Read 负载均衡

Splitting 一开始是发生在同一台 region server 上的,但是出于负载均衡的原因,HMaster 可能会将新的 regions 迁移给其它 region server,这会导致那些 region server 需要访问离它比较远的 HDFS 数据,直到 major compaction 的到来,它会将那些远方的数据重新移回到离 region server 节点附近的地方。

(点评:注意这里的迁移的概念,只是逻辑上的迁移,即将某个 region 交给另一个 region server 管理。)

HDFS 数据备份

所有的读写都发生在 HDFS 的主 DataNode 节点上。HDFS 会自动备份 WAL 和 HFile 的文件 blocks。HBase 依赖于 HDFS 来保证数据完整安全。当数据被写入 HDFS 时,一份会写入本地节点,另外两个备份会被写入其它节点。

WAL 和 HFiles 都会持久化到硬盘并备份。那么 HBase 是怎么恢复 MemStore 中还未被持久化到 HFile 的数据呢?下面的章节会讨论这个问题。

HBase 故障恢复

当某个 Region Server 发生 crash 时,它所管理的 region 就无法被访问了,直到 crash 被检测到,然后故障恢复完成,这些 region 才能恢复访问。Zookeeper 依靠心跳检测发现节点故障,然后 HMaster 会收到 region server 故障的通知。

当 HMaster 发现某个 region server 故障,HMaster 会将这个 region server 所管理的 regions 分配给其它健康的 region servers。为了恢复故障的 region server 的 MemStore 中还未被持久化到 HFile 的数据,HMaster 会将 WAL 分割成几个文件,将它们保存在新的 region server 上。每个 region server 然后回放各自拿到的 WAL 碎片中的数据,来为它所分配到的新 region 建立 MemStore。

WAL 包含了一系列的修改操作,每个修改都表示一个 put 或者 delete 操作。这些修改按照时间顺序依次写入,持久化时它们被依次写入 WAL 文件的尾部。

当数据仍然在 MemStore 还未被持久化到 HFile 怎么办呢?WAL 文件会被回放。操作的方法是读取 WAL 文件,排序并添加所有的修改记录到 MemStore,最后 MemStore 会被刷写到 HFile。

(点评:故障恢复是 HBase 可靠性保障的一个重要特性。WAL 在这里扮演了关键角色,在分割 WAL 时,数据会根据 region 分配到对应的新的 region server 上,然后 region server 负责回放这一部分数据到 MemStore 中。)

Apache HBase 架构的优点

  • 强一致性:

    - 当 write 返回时,所有的 reader 都会读到同样的值。
  • 自动扩展性

    - 数据变大时 region 会分裂。
    - 使用 HDFS 存储备份数据。
  • 内置恢复功能

    - 使用 Write Ahead Log (类似于文件系统中的日志)
  • 与 Hadoop 结合:

    - 使用 MapReduce 处理 HBase 数据会非常直观。

Apache HBase 也有问题

  • 业务持续可靠性:

  • - WAL 回放很慢。
    - 故障恢复很慢。
    - Major Compaction 时候 I/O 会飙升。

HBase 架构:HBase 数据模型 & HBase 读/写机制

https://bbs.huaweicloud.com/blogs/301024

【摘要】 众所周知,HBase 是一个面向列的 NoSQL 数据库。虽然它看起来类似于包含行和列的关系数据库,但它不是关系数据库。关系数据库是面向行的,而 HBase 是面向列的。那么,让我们首先了解面向列和面向行的数据库之间的区别:

HBase 架构

在我之前关于HBase 教程的博客中,我解释了什么是 HBase 及其特性。我还提到了 Facebook Messenger 的案例研究,以帮助您更好地联系。现在继续,我将解释 HBase 和 HBase 架构的数据模型。在继续之前,您还应该知道 HBase 是一个重要的概念,它构成了大数据 Hadoop 认证课程的一个组成部分。

我将在此 HBase 架构博客中向您介绍的重要主题是:

  • HBase 数据模型

  • HBase 架构及其组件

  • HBase 写机制

  • HBase 读机制

  • HBase 性能优化机制

我们先来了解一下HBase的数据模型。它有助于 HBase 更快地读/写和搜索。

HBase 架构:HBase 数据模型

众所周知,HBase 是一个面向列的 NoSQL 数据库。虽然它看起来类似于包含行和列的关系数据库,但它不是关系数据库。关系数据库是面向行的,而 HBase 是面向列的。那么,让我们首先了解面向列和面向行的数据库之间的区别:

面向行与面向列的数据库:

  • 面向行的数据库以行的顺序存储表记录。而面向列的数据库 将表记录存储在一系列列中,即列中的条目存储在磁盘上的连续位置。

为了更好地理解它,让我们举个例子并考虑下表。

如果此表存储在面向行的数据库中。它将存储如下所示的记录:

1 ,保罗沃克,美国, 231 ,加拉多, 

2,  Vin Diesel ,巴西, 520 , Mustang

如上所示,在面向行的数据库中,数据是基于行或元组存储的。

虽然面向列的数据库将此数据存储为:

1 , 2 ,  Paul Walker , Vin Diesel , 美国,巴西,  231 , 520 ,  Gallardo , Mustang

在面向列的数据库中,所有列值都存储在一起,就像第一列值将存储在一起,然后第二列值将一起存储,其他列中的数据以类似方式存储。

  • 当数据量非常大时,比如 PB 级或 EB 级,我们使用面向列的方法,因为单列的数据存储在一起,可以更快地访问。

  • 虽然面向行的方法相对有效地处理较少数量的行和列,但面向行的数据库存储数据是一种结构化格式。

  • 当我们需要处理和分析大量半结构化或非结构化数据时,我们使用面向列的方法。例如处理在线分析处理的应用程序,如数据挖掘、数据仓库、包括分析在内的应用程序等。

  • 在线事务处理(例如处理结构化数据并需要事务属性(ACID 属性)的银行和金融领域)使用面向行的方法。

HBase 表具有以下组件,如下图所示:

  • 表格:数据以表格格式存储在 HBase 中。但这里的表格是面向列的格式。

  •  :行键用于搜索记录,使搜索速度更快。你会很想知道怎么做吗?我将在本博客的架构部分进行解释。 

  •  :各种列组合在一个列族中。这些列族存储在一起,这使得搜索过程更快,因为可以在一次查找中一起访问属于同一列族的数据。

  •  限定符:每列的名称称为其列限定符。

  • 单元格:数据存储在单元格中。数据被转储到由行键和列限定符专门标识的单元格中。

  • 时间戳:时间戳是日期和时间的组合。无论何时存储数据,它都会与其时间戳一起存储。这使得搜索特定版本的数据变得容易。

用更简单易懂的方式,我们可以说 HBase 包括:

  • 一组表

  • 每个表都有列族和行

  • 行键在 HBase 中充当主键。

  • 对 HBase 表的任何访问都使用此主键

  • HBase 中存在的每个列限定符表示与驻留在单元格中的对象相对应的属性。

现在您了解了 HBase 数据模型,让我们看看这个数据模型如何符合 HBase 架构并使其适用于大存储和更快的处理。

HBase 架构:HBase 架构的组件

HBase 具有三个主要组件,即HMaster ServerHBase Region Server、RegionsZookeeper

下图解释了 HBase 架构的层次结构。我们将单独讨论它们中的每一个。

现在在进入 HMaster 之前,我们将了解 Region,因为所有这些 Server(HMaster、Region Server、Zookeeper)都是用来协调和管理 Region 并在 Region 内部执行各种操作的。因此,您很想知道什么是区域以及它们为何如此重要? 

HBase 架构:区域(Region)

一个区域包含分配给该区域的开始键和结束键之间的所有行。HBase 表可以划分为多个区域,将一个列族的所有列存储在一个区域中。每个区域都包含按排序顺序的行。

许多区域被分配给一个Region Server,它负责处理、管理、执行对该组区域的读取和写入操作。

所以,以更简单的方式结束:

  • 一个表可以分为多个区域。区域是存储在开始键和结束键之间的数据的有序行范围。

  • 一个 Region 的默认大小为 256MB,可以根据需要进行配置。

  • 区域服务器为客户端提供一组区域。

  • 一个区域服务器可以为客户端提供大约 1000 个区域。

现在从层次结构的顶部开始,我首先想向您解释 HMaster Server,它的作用类似于HDFS 中的 NameNode 。然后,在层次结构中向下移动,我将带您了解 ZooKeeper 和 Region Server。

HBase 架构:HMaster 

如下图所示,您可以看到 HMaster 处理驻留在 DataNode 上的 Region Server 集合。让我们了解 HMaster 是如何做到这一点的。

  • HBase HMaster 执行 DDL 操作(创建和删除表)并将区域分配给区域服务器(Region Server),如上图所示。

  • 它协调和管理 Region Server(类似于 NameNode 在 HDFS 中管理 DataNode)。

  • 它在启动时将区域分配给区域服务器(Region Server),并在恢复和负载平衡期间将区域重新分配给区域服务器(Region Server)。

  • 它监视集群中所有 Region Server 的实例(在 Zookeeper 的帮助下),并在任何 Region Server 关闭时执行恢复活动。

  • 它提供了一个用于创建、删除和更新表的接口。

HBase 有一个庞大的分布式环境,仅靠 HMaster 不足以管理所有内容。那么,你会想知道是什么帮助 HMaster 管理这个巨大的环境?这就是 ZooKeeper 出现的地方。在了解了 HMaster 如何管理 HBase 环境后,我们将了解 Zookeeper 如何帮助 HMaster 管理环境。 

HBase 架构:ZooKeeper – 协调器 

下图解释了 ZooKeeper 的协调机制。

  • Zookeeper 就像 HBase 分布式环境中的协调器。它有助于通过会话进行通信来维护集群内的服务器状态。

  • 每个 Region Server 和 HMaster Server 都会定期向 Zookeeper 发送连续的心跳,并检查哪个服务器是活动的和可用的,如上图所示。它还提供服务器故障通知,以便可以执行恢复措施。

  • 从上图可以看出,有一个不活动的服务器,它作为活动服务器的备份。如果活动服务器出现故障,它就会派上用场。

  • 活动的 HMaster 向 Zookeeper 发送心跳,而非活动的 HMaster 侦听活动 HMaster 发送的通知。如果活动 HMaster 未能发送心跳,则会话将被删除,非活动 HMaster 变为活动状态。

  • 而如果 Region Server 无法发送心跳,则会话将过期并通知所有侦听器。然后 HMaster 执行适当的恢复操作,我们将在本博客稍后讨论。

  • Zookeeper 还维护 .META Server 的路径,这有助于任何客户端搜索任何区域。Client首先必须与.META Server核对某个区域所属的Region Server,并获取该Region Server的路径。 

说到.META Server,我先给大家解释一下什么是.META Server?因此,您可以轻松地将 ZooKeeper 和 .META Server 的工作联系在一起。稍后,当我在此博客中向您解释 HBase 搜索机制时,我将解释这两者如何协同工作。 

HBase 架构: 元表

  • META 表是一个特殊的 HBase 目录表。它维护了 HBase 存储系统中所有区域服务器(Region Server)的列表(简单理解:地址簿),如上图所示。

  • 从图中可以看到,.META文件以键和值的形式维护表。Key 代表区域的起始键和它的 id,而值包含区域服务器的路径。

正如我在向您解释 Region 时已经讨论过的 Region Server 及其功能,因此现在我们正在向下移动层次结构,我将专注于 Region Server 的组件及其功能。稍后我将讨论搜索、读、写的机制,并了解所有这些组件如何协同工作。

HBase 架构: Region Server 的组件

下图显示了区域服务器的组件。现在,我将分别讨论它们。

区域服务器维护在HDFS顶部运行的各种区域。区域服务器的组件是:

  • WAL: 从上图中可以得出结论,Write Ahead Log (WAL) 是附加到分布式环境中每个 Region Server 的文件。WAL 存储尚未持久化或提交到永久存储的新数据。它用于恢复数据集失败的情况。

  • Block Cache:从上图可以清楚的看到Block Cache位于Region Server的顶部。它将经常读取的数据存储在内存中。如果 BlockCache 中的数据最近最少使用,则该数据将从 BlockCache 中删除。

  • MemStore:是写缓存。在将所有传入数据提交到磁盘或永久内存之前,它会存储所有传入数据。一个区域中的每个列族都有一个 MemStore。正如您在图像中看到的,一个区域有多个 MemStore,因为每个区域包含多个列族。数据在提交到磁盘之前按字典顺序排序。 

  • HFile:从上图可以看出HFile是存储在HDFS上的。因此,它将实际单元存储在磁盘上。当 MemStore 的大小超过时,MemStore 将数据提交到 HFile。

现在我们知道了 HBase 架构的主要和次要组件,我将在此解释机制和他们的协作努力。不管是读还是写,首先我们要搜索从哪里读或者从哪里写一个文件。所以,让我们了解这个搜索过程,因为这是使 HBase 非常流行的机制之一。 

HBase 架构: 搜索如何在 HBase 中初始化?

如您所知,Zookeeper 存储 META 表位置。每当客户端向 HBase 发出读取或写入请求时,就会发生以下操作:

  1. 客户端从 ZooKeeper 检索 META 表的位置。

  2. 客户端然后从 META 表中请求相应行键的 Region Server 的位置来访问它。客户端将此信息与 META 表的位置一起缓存。

  3. 然后它将通过从相应的 Region Server 请求来获取行位置。

对于将来的引用,客户端使用其缓存来检索 META 表的位置和先前读取的行键的区域服务器。然后客户端将不会引用 META 表,直到并且除非由于区域移动或移动而导致未命中。然后它将再次请求 META 服务器并更新缓存。

与每次一样,客户端不会浪费时间从 META 服务器检索 Region Server 的位置,因此,这节省了时间并使搜索过程更快。现在,让我告诉您如何在 HBase 中进行写入。其中涉及哪些组件以及它们如何参与?

HBase 架构: HBase 写机制

下图解释了 HBase 中的写入机制。

写入机制依次经过以下过程(参考上图): 

步骤1:每当客户端有写请求时,客户端将数据写入WAL(Write Ahead Log)。 

  • 然后将编辑附加到 WAL 文件的末尾。

  • 该 WAL 文件保存在每个 Region Server 中,Region Server 使用它来恢复未提交到磁盘的数据。

第 2 步:将数据写入 WAL 后,将其复制到 MemStore。

第 3 步:一旦数据放入 MemStore,客户端就会收到确认。

第 4 步:当 MemStore 达到阈值时,它将数据转储或提交到 HFile。

现在让我们深入了解一下 MemStore 在写作过程中的贡献以及它的功能是什么?

HBase 写机制-  MemStore

  • MemStore 总是按照字典顺序(按字典方式)将存储在其中的数据更新为已排序的 KeyValue。每个列族有一个 MemStore,因此每个列族的更新以排序的方式存储。 

  • 当 MemStore 达到阈值时,它会以排序的方式将所有数据转储到一个新的 HFile 中。此 HFile 存储在 HDFS 中。HBase 为每个列族包含多个 HFile。

  • 随着时间的推移,HFile 的数量随着 MemStore 转储数据而增长。

  • MemStore 还保存了最后写入的序列号,因此 Master Server 和 MemStore 都知道到目前为止提交了什么以及从哪里开始。当区域启动时,读取最后一个序列号,并从该编号开始新的编辑。

正如我多次讨论过的,HFile 是 HBase 架构中的主要持久存储。最后,所有的数据都提交到 HFile 中,HFile 是 HBase 的永久存储。因此,让我们看看 HFile 的属性,它可以在读写时更快地进行搜索。

HBase 架构: HBase 写入机制-  HFile

  • 写入按顺序放置在磁盘上。因此,磁盘读写头的运动非常少。这使得写入和搜索机制非常快。

  • 每当打开 HFile 时,HFile 索引就会加载到内存中。这有助于在单次查找中查找记录。 

  • 预告片是一个指向 HFile 的元块的指针。它写在提交文件的末尾。它包含有关时间戳和布隆过滤器的信息。

  • 布隆过滤器有助于搜索键值对,它会跳过不包含所需行键的文件。时间戳还有助于搜索文件的版本,它有助于跳过数据。

在了解写入机制和各种组件在使写入和搜索更快方面的作用之后。我将向您解释读取机制在 HBase 架构中是如何工作的?然后我们将转向提高 HBase 性能的机制,如压缩、区域拆分和恢复。

HBase 架构: 读取机制

正如我们在搜索机制中所讨论的,如果客户端的缓存中没有它,客户端首先从 .META 服务器中检索区域服务器的位置。然后它按顺序执行以下步骤: 

  • 为了读取数据,扫描器首先在块缓存中查找行单元。这里存储了所有最近读取的键值对。

  • 如果 Scanner 未能找到所需的结果,它会移动到 MemStore,因为我们知道这是写缓存内存。在那里,它搜索最近写入的文件,这些文件尚未转储到 HFile 中。

  • 最后,它将使用布隆过滤器和块缓存从 HFile 加载数据。

到目前为止,我已经讨论了 HBase 的搜索、读写机制。现在我们来看看 HBase 机制,它使 HBase 中的搜索、读取和写入变得快速。首先,我们将了解Compaction,这是其中一种机制。

HBase 架构: 压缩

HBase 结合 HFiles 以减少存储并减少读取所需的磁盘寻道次数。这个过程称为压缩。Compaction 从一个区域中选择一些 HFile 并将它们组合起来。如上图所示,有两种类型的压缩。

  1. 次要压缩:HBase 自动选择较小的 HFile 并将它们重新提交到较大的 HFile,如上图所示。这称为轻微压实。它执行合并排序以将较小的 HFile 提交到较大的 HFile。这有助于优化存储空间。 

  2. Major Compaction 如上图所示,在Major compaction中,HBase将一个区域的较小的HFiles合并并重新提交到一个新的HFile。在这个过程中,相同的列族被放置在新的 HFile 中。它会在此过程中删除已删除和过期的单元格。它提高了读取性能。

但在此过程中,输入输出磁盘和网络流量可能会变得拥挤。这称为写放大。因此,它通常安排在低峰值负载时间。

现在我将讨论的另一个性能优化过程是 Region Split。这对于负载平衡非常重要。

HBase 架构: 区域拆分

下图说明了 Region Split 机制。

每当一个区域变大时,它就会被分成两个子区域,如上图所示。每个区域正好代表父区域的一半。然后将此拆分报告给 HMaster。这由同一个 Region Server 处理,直到 HMaster 将它们分配给新的 Region Server 以进行负载平衡。

接下来,最后但并非最不重要的一点是,我将向您解释 HBase 如何在发生故障后恢复数据。我们知道故障恢复是 HBase 的一个非常重要的特性,因此让我们了解 HBase 如何在故障后恢复数据。

HBase 架构:HBase 崩溃和数据恢复 

  • 每当 Region Server 出现故障时,ZooKeeper 都会通知 HMaster 故障。

  • 然后 HMaster 将崩溃的 Region Server 的区域分发并分配给许多活动的 Region Server。为了恢复出现故障的 Region Server 的 MemStore 的数据,HMaster 将 WAL 分发给所有 Region Server。

  • 每个 Region Server 重新执行 WAL 来为那个失败的 region 的列族构建 MemStore。

  • 数据按时间顺序(按时间顺序)写入 WAL。因此,重新执行该 WAL 意味着进行所有在 MemStore 文件中所做和存储的更改。

  • 所以,在所有的 Region Servers 执行完 WAL 之后,所有列族的 MemStore 数据都被恢复了。


详解HBase架构原理

本文简单介绍了HBase设计模型,物理存储模型以及存储架构

一、什么是HBase

HBase是一个高可靠、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价的PC Server上搭建大规模结构化存储集群。

HBase是Google BigTable的开源实现,与Google BigTable利用GFS作为其文件存储系统类似,HBase利用Hadoop HDFS作为其文件存储系统;

Google运行MapReduce来处理BigTable中的海量数据,HBase同样利用Hadoop MapReduce来处理HBase中的海量数据;

Google BigTable利用Chubby作为协同服务,HBase利用Zookeeper作为协同服务。

二、HBase设计模型

HBase中的每一张表就是所谓的BigTable。BigTable会存储一系列的行记录,行记录有三个基本类型的定义:

1.RowKey

是行在BigTable中的唯一标识。

2.TimeStamp:

是每一次数据操作对应关联的时间戳,可以看作SVN的版本。

3.Column:

定义为<family>:<label>,通过这两部分可以指定唯一的数据的存储列,family的定义和修改需要对HBase进行类似于DB的DDL操作,

而label,不需要定义直接可以使用,这也为动态定制列提供了一种手段。family另一个作用体现在物理存储优化读写操作上,同family

的数据物理上保存的会比较接近,因此在业务设计的过程中可以利用这个特性。

1. 逻辑存储模型

HBase以表的形式存储数据,表由行和列组成。列划分为若干个列簇,如下图所示:

下面是对表中元素的详细解析:

RowKey

与NoSQL数据库一样,rowkey是用来检索记录的主键。访问HBase Table中的行,只有三种方式:

1.通过单个rowkey访问

2.通过rowkey的range

3.全表扫描

rowkey行键可以任意字符串(最大长度64KB,实际应用中长度一般为10-100bytes),在HBase内部RowKey保存为字节数组。

存储时,数据按照RowKey的字典序(byte order)排序存储,设计key时,要充分了解这个特性,将经常一起读取的行存放在一起。

需要注意的是:行的一次读写是原子操作(不论一次读写多少列)

列簇

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

courses:history, courses:math 都属于 courses 这个列簇。

访问控制,磁盘和内存的使用统计都是在列簇层面进行的。

实际应用中,列簇上的控制权限能帮助我们管理不同类型的应用:我们允许一些应用可以添加新的基本数据、

一些应用可以读取基本数据并创建继承的列簇、一些应用则只允许浏览数据(设置可能因为隐私的原因不能浏览所有数据)。

时间戳

HBase中通过row和columns确定的为一个存储单元称为cell。每个cell都保存着同一份数据的多个版本。版本通过时间戳来索引。

时间戳的类型是64位整型。时间戳可以由HBase在写入时自动赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也可以由客户显示赋值。

如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。每个cell中在不同版本的数据按照时间倒序排序,即最新的数据排在最前面。

为了避免数据存在过多的版本造成的管理负担,HBase提供了两种数据版本回收方式。一是保存数据的最后n个版本,二是保存最近一段时间内的版本

(比如最近七天)。用户可以针对每个列簇进行设置。

Cell

由row key, column(=+), version 唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存储。

2. 物理存储模型

Table在行的方向上分割为多个HRegion,每个HRegion分散在不同的RegionServer中。

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

StoreFile以HFile格式存储在HDFS中。

三、HBase存储架构

从HBase的架构图上可以看出,HBase中的存储包括HMaster、HRegionSever、HRegion、HLog、Store、MemStore、StoreFile、HFile等,以下是HBase存储架构图:

HBase中的每张表都通过键按照一定的范围被分割成多个子表(HRegion),默认一个HRegion超过256M就要被分割成两个,这个过程由HRegionServer管理,

而HRegion的分配由HMaster管理。

HMaster的作用:

1.为HRegionServer分配HRegion

2.负责HRegionServer的负载均衡

3.发现失效的HRegionServer并重新分配

4.HDFS上的垃圾文件回收

5.处理Schema更新请求

HRegionServer的作用:

1.维护HMaster分配给它的HRegion,处理对这些HRegion的IO请求

2.负责切分正在运行过程中变得过大的HRegion

可以看到,Client访问HBase上的数据并不需要HMaster参与,寻址访问ZooKeeper和HRegionServer,数据读写访问HRegionServer,

HMaster仅仅维护Table和Region的元数据信息,Table的元数据信息保存在ZooKeeper上,负载很低。HRegionServer存取一个子表时,

会创建一个HRegion对象,然后对表的每个列簇创建一个Store对象,每个Store都会有一个MemStore和0或多个StoreFile与之对应,

每个StoreFile都会对应一个HFile,HFile就是实际的存储文件。因此,一个HRegion有多少列簇就有多少个Store。

一个HRegionServer会有多个HRegion和一个HLog。

HRegion

Table在行的方向上分割为多个HRegion,HRegion是HBase中分布式存储和负载均衡的最小单元,即不同的HRegion可以分别在不同的HRegionServer上,

但同一个HRegion是不会拆分到多个HRegionServer上的。HRegion按大小分割,每个表一般只有一个HRegion,随着数据不断插入表,HRegion不断增大,

当HRegion的某个列簇达到一个阀值(默认256M)时就会分成两个新的HRegion。

1、<表名,StartRowKey, 创建时间>

2、由目录表(-ROOT-和.META.)记录该Region的EndRowKey

HRegion定位:HRegion被分配给哪个HRegionServer是完全动态的,所以需要机制来定位HRegion具体在哪个HRegionServer,HBase使用三层结构来定位HRegion:

1、通过zk里的文件/hbase/rs得到-ROOT-表的位置。-ROOT-表只有一个region。

2、通过-ROOT-表查找.META.表的第一个表中相应的HRegion位置。其实-ROOT-表是.META.表的第一个region;

.META.表中的每一个Region在-ROOT-表中都是一行记录。

3、通过.META.表找到所要的用户表HRegion的位置。用户表的每个HRegion在.META.表中都是一行记录。

-ROOT-表永远不会被分隔为多个HRegion,保证了最多需要三次跳转,就能定位到任意的region。Client会将查询的位置信息保存缓存起来,缓存不会主动失效,

因此如果Client上的缓存全部失效,则需要进行6次网络来回,才能定位到正确的HRegion,其中三次用来发现缓存失效,另外三次用来获取位置信息。

Store

每一个HRegion由一个或多个Store组成,至少是一个Store,HBase会把一起访问的数据放在一个Store里面,即为每个ColumnFamily建一个Store,

如果有几个ColumnFamily,也就有几个Store。一个Store由一个MemStore和0或者多个StoreFile组成。HBase以Store的大小来判断是否需要切分HRegion。

MemStore

MemStore 是放在内存里的,保存修改的数据即keyValues。当MemStore的大小达到一个阀值(默认64MB)时,MemStore会被Flush到文件,

即生成一个快照。目前HBase会有一个线程来负责MemStore的Flush操作。

StoreFile

MemStore内存中的数据写到文件后就是StoreFile,StoreFile底层是以HFile的格式保存。

HFile

HBase中KeyValue数据的存储格式,是Hadoop的二进制格式文件。首先HFile文件是不定长的,长度固定的只有其中的两块:Trailer和FileInfo。

Trailer中有指针指向其他数据块的起始点,FileInfo记录了文件的一些meta信息。Data Block是HBase IO的基本单元,为了提高效率,

HRegionServer中有基于LRU的Block Cache机制。每个Data块的大小可以在创建一个Table的时候通过参数指定(默认块大小64KB),

大号的Block有利于顺序Scan,小号的Block利于随机查询。每个Data块除了开头的Magic以外就是一个个KeyValue对拼接而成,

Magic内容就是一些随机数字,目的是防止数据损坏,结构如下。

HFile结构图如下:

Data Block段用来保存表中的数据,这部分可以被压缩。Meta Block段(可选的)用来保存用户自定义的kv段,可以被压缩。FileInfo段用来保存HFile的元信息,不能被压缩,用户也可以在这一部分添加自己的元信息。Data Block Index段(可选的)用来保存Meta Blcok的索引。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进行压缩和解压缩。(备注:DataBlock Index的缺陷。a) 占用过多内存 b) 启动加载时间缓慢)

HLog

  HLog(WAL log):WAL意为write ahead log,用来做灾难恢复使用,HLog记录数据的所有变更,一旦region server 宕机,就可以从log中进行恢复。

LogFlusher

  定期的将缓存中信息写入到日志文件中

LogRoller 

   对日志文件进行管理维护

以上是关于图文详解深入理解 Hbase 架构 Deep Into HBase Architecture的主要内容,如果未能解决你的问题,请参考以下文章

图文详解HBase 数据模型及其架构原理

图文详解 HBase 的读写流程

架构设计:远程调用服务架构设计及zookeeper技术详解

深入理解HBase的系统架构

[转]毕设- 深入HBase架构解析

一文让你理解微服务架构(图文详解)