HBase架构深入分析(二)


HBase架构深入分析(二)

    通过《HBase机构深入分析(一)》已经知道HBase大致的架构和组件。二,继续深入分析HBase的架构设计。

Region的Flush

    当MemStore累积足够的数据时,整个排序的数据集被写入位于HDFS中的新的HFile中。HBase的每个列族使用多个HFiles,其中包含实际数据存储单元格(cell)或Key-Value的实例。这些HFile文件随着时间的推移而被创建,因为MemStores中排序的Key-Value编辑被刷新为文件到磁盘。 
    请注意,这也是HBase中列族数量有限制的一个原因。每个CF有一个MemStore;当一个的内存满时,他们将都被写入磁盘。它还保存最后写入的序列号,以便让系统知道到目前为止已经持久化的内容。 
    序列号作为HFile的元数据存储起来,这样就能够知道在哪里写入结束,应该从哪里开始。在Region启动时,首先读取序列号,最高的序列号用作新内容编辑的序列号。 
这里写图片描述

HBase HFile

    数据按排好序的key/value值保存在HFile中。当MemStore累加了足够多的数据时,整个的key/value数据集都会被写入到位于HDFS的HFile中。这是顺序写的,非常快,避免移动磁头。

这里写图片描述

HBase HFile结构

    HFile中包含了多个层次的索引,这样在HFile中查找数据是就不需要读取整个文件内容。 
多个层次的索引像是b+树:

  • key/value按递增的顺序存储
  • 按64k大小的key/value数据块对rowkey进行索引
  • 每个数据块都有他自己的叶索引
  • 每个数据块的最后一个键(rowkey)放在中间索引中
  • 根索引值指向中间指数

    尾部指针指向元数据块(meta block),并在数据持久化到文件后写入文件。尾部指针还包括bloom过滤器和时间范围的信息。bloom过滤器用来帮助跳过不包含某些rowkey的文件。时间范围用来跳过不在该时间范围的一些文件。 
这里写图片描述

HFile的索引

    我们刚刚讨论的索引,在打开HFile并将其内容保存在内存中时加载。这允许使用单个磁盘查找执行查找。 
这里写图片描述

HBase的读合并

    我们已经看到,对应于一行的Key/Value单元格可能保存在多个位置,一些行的单元格已经保留在Hfiles中,最近更新的单元格位于MemStore中,最近读取的单元格位于BlockCache中。那么,当你读取一行的时候系统该如何返回这一行匹配的单元格呢?读取操作将会合并blockcache,memstore和HFile中的对应的数据,合并的顺序如下:

  1. 首先,扫描程序在块缓存中查找Row单元格 - 读缓存。最近读取过的key/value值被缓存在这里,并且在需要时,最近最少使用的数据将会从缓存中清除。
  2. 第2步,扫描程序在MemStore中进行查找,这里保存了最近写过的数据。
  3. 第3步,如果扫描程序没有在Blockcache和Memstore中找到对应的数据,HBase将会使用块索引和bloom过滤算法,把包含目标数据的HFile加载到内存中。 
    这里写图片描述

HBase读合并

    如前所述,每个MemStore可能有许多HFiles,这意味着对于读取,可能需要检查多个文件,这可能会影响性能。 
这被称为读取放大。 
这里写图片描述

HBase辅助压缩(HBase Minor Compaction)

    HBase会自动选择一些小的HFile,并重新把它们合并成少量的大文件。这个过程被称为辅助压缩,它通过把大量的小文件合并成大文件,来减少HBase中文件的数量,同时还会对数据进行合并排序。 
这里写图片描述

HBase主压缩(HBase Major Compaction)

    Major Compaction会压缩合并和重写一个region上的所有HFile,重写成一个列族一个HFile,在这个过程中会删除过期的单元格数据。处理完成后,能提高读取数据的性能。但是该过程会重写所有的HFile,所以消耗大量网络IO和磁盘IO。这个过程被称为写放大。 
写放大可以被自动调度执行,由于比较消耗资源,一般写放大被放在周末或晚上执行。由于服务器故障或负载平衡,主压缩还会把远程的任何数据文件,保存在本地的RegionServer上。 
这里写图片描述

Region=连续的Key

我们快速回顾一下Region:

  • 一个表能被水平分成一个或多个Region
  • 一个Region包含一个由startkey和endkey组成的连续的区间
  • 每个Region默认是1G大小
  • HBase Client通过RegionServer来访问一个表的Region
  • 一个RegionServer可以服务于多个Region(默认是1000个),这些Region可以是属于同一表或不同的表。 
    这里写图片描述

Region的分裂

    初始化的时候一个表只有一个Region。当一个Region数据增长得太大时,被分割成两个子Region。这个两个子Region各代表原始Region的一半,在同一个RegionServer中被并行同时打开,并且把这个分裂报告给HMaster。由于负载均衡的原因HMaster可能会把新的子Region移动到其他的服务器上。 
这里写图片描述

HBase读负载均衡

    分裂发生在同一个RegionServer中,但由于负载均衡的原因,HMaster可能会把新的Region移动到其他服务器上去。这样会导致新的Region管理的数据在远端的HDFS Datanode上,直到主压缩过程把远端的数据移动到RegionServer所在的服务器。HBase数据在写入时会写在本地,当一个Region被移动时(由于负载均衡和数据恢复等原因),数据将不在本地,主压缩过程会重新使数据回到本地。 
这里写图片描述

HDFS数据复制

所有的读和写都来自/去向主节点。HDFS复制WAL和HFile数据块。HFile数据块的复制动作会自动发生。HBase依赖HDFS来提供数据的安全性,因为它依赖HDFS的文件存储。当数据写入HDFS时,会在本地写入一份复制,第2分复制会写入第2个节点,同时第3份复制会写入第3个节点。

这里写图片描述

HDFS数据复制2

WAL和HFile被持久化到磁盘上,并对数据进行了复制。那么HBase如何恢复没有被写入磁盘的Memstore中的数据呢?请看下面的一节: 
这里写图片描述

HBase宕机恢复

当一个RegionServer宕机,宕机的Region必须要通过恢复才能被访问。当Zookeeper检测到不再有RegionServer的心跳,它会决定哪一个节点宕机。HMaster将会通知RegionServer失败的消息。 
当HMaster检测到失败的RegionServer后,会重新分配已宕机服务器上的Region到其他活动的RegionServer上。 
为了恢复未刷新到磁盘的崩溃区域服务器的memstore编辑。 HMaster将属于崩溃区域服务器的WAL分为单独的文件,并将这些文件存储在新的区域服务器的数据节点中。然后,每个RegionServer从相应的分割WAL重播WAL,以重建该区域的memstore。 
这里写图片描述

HBase数据恢复

WAL文件中包含了一个操作的列表,每个编辑代表一次put或delete操作。操作按时间顺序写入,因此每一次的添加,持久化操作将会被写入到WAL文件的末尾。 
那么,当在内存中的数据还没有写入HFile中,会发生什么?WAL中的操作将会被重放。重放WAL中的操作时,先读取WAL文件,把内容添加到Memstore中,并对目前Memstore的内容进行排序。最后Memstore中改变的内容会被写入到磁盘上。 
这里写图片描述

HBase架构的优点总结

  • 强一致性模型 
    • 当写操作完成时,所有的读者将会看到相同的值
  • 自动扩展 
    • 当数据太大时,Region自动分裂
    • 使用HDFS来扩展和复制数据
  • 内建的自动恢复机制 
    • 使用WAL来避免内存数据丢失
  • 和Hadoop整合 
    • 直接使用Hadoop的MapReduce

HBase存在的问题

  • WAL重放比较慢
  • 对于比较复杂的灾难恢复比较慢
  • 在进行主压缩时比较消耗系统资源

猜你喜欢

转载自blog.csdn.net/wangshuminjava/article/details/80496362