【云驻共创】终于看到Hbase技术原理,太不容易了

举报
铃虫 发表于 2021/12/16 21:15:20 2021/12/16
【摘要】 主要讲述开源的非关系型分布式数据库HBase,它可以满足大规模数据实时处理应用的需求。大数据平台所提供的主要功能是什么?大数据平台主要提供的是存储和计算,对于我们所学习的每一种组件,我们应该考虑其应用场景,而HBase能够去应对海量数据的存储,同时它也能够去支撑实时响应、查询、计算。


前言

本章主要讲述开源的非关系型分布式数据库HBase,它可以满足大规模数据实时处理应用的需求。

目标

学完本课程后,您将能够:

  • 熟悉HBase的系统架构和相关概念
  • 熟悉HBase的关键流程和突出特点
  • 熟悉HBase的性能优化
  • 熟悉HBase的基本Shell操作

大数据平台所提供的主要功能是什么?大数据平台主要提供的是存储和计算,对于我们所学习的每一种组件,我们应该考虑其应用场景,而HBase能够去应对海量数据的存储,同时它也能够去支撑实时响应、查询、计算。

一、HBase基本介绍

HBase是谷歌的BigTable的开源实现,HBase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统。

  • 适合于存储大表数据(表的规模可以达到数十亿行以及数百万列),并且对大表数据的读、写访问可以达到实时级别。
  • 利用Hadoop HDFS ( Hadoop Distributed File System )作为其文件存储系统,提供实时读写的分布式数据库系统。
  • 利用ZooKeeper作为协同服务。Zookeeper也为HBase提供分布式锁服务、监听服务,还有微数据库服务。


HBase与RDB的对比

HBase与传统的关系数据库的区别主要体现在以下几个方面:

数据索引:关系数据库通常可以针对不同列构建复杂的多个索引,以提高数据访问性能。HBase只有一个索引――行键,通过巧妙的设计,HBase中的所有访问方法,或者通过行间的某个区域,或者通过行键扫描,从而使得整个系统不会慢下来。

数据维护:在关系数据库中,更新操作会用最新的当前值去替换记录中原来的旧值盖后就不会存在。而在HBase中执行更新操作时,并不会删除数据旧的版本,而是生成新的版本,旧有的版本仍然保留。

可伸缩性:关系数据库很难实现横向扩展,纵向扩展的空间也比较有限。相反,HBase在BigTable这些分布式数据库就是为了实现灵活的水平扩展而开发的,能够轻易地通过在集群增加或者减少硬件数量来实现性能的伸缩。

HBase面向于海量数据存储的,存储的数据可以达到PB和TB级别。另外HBase它不需要完全拥有关系数据库的ACID特性。A代表事物的原子性,C代表了事物的一致性,I代表事物的独立性,D代表事物的持久性。再者HBase采用了zookeeper为其提供服务,可以提供了高吞吐量的客户端查询,在海量的数据中实现高效的随机读取机制。这个是通过了HBase的行键实现的,另外HBase具有很强的性能伸缩能力,我们通过了增加HBase的节点,能够去水平扩展HBase的存储以及查询能力,hHBase能够去同时处理结构化、半结构化以及非结构化的数据。


二、HBase相关概念

数据模型

  • 简单来说,应用程序是以表的方式在HBase存储数据的。
  • 表是由行和列构成的,所有的列是从属于某一个列族的。
  • 行和列的交叉点称之为cell,cell是版本化的。cell的内容是不可分割的字节数组。
  • 表的行键也是一段字节数组,所以任何东西都可以保存进去,不论是字符串或者数字。
  • HBase的表是按key排序的,排序方式是针对字节的。
  • 所有的表都必须要有主键-key。

存储在HBase表每一行数据都有可排序的关键字(Row Key)和任意列项( Column &Column Family )。在HBase中,仅能通过主键(Row Key )和主键版本号来检索数据,仅支持单行事务。下面以HBase存储搜索引擎的网页为例:

行键,相当于关系表的主键,每一行数据的唯一标识。字符串、整数、二进制串都可以作为RowKey。所有记录按照RowKey排序后存储。

Column Family,列簇,一个表在水平方向上由一个或多个CF组成。一个CF可以由任意多个Column组成。Column是CF下的一个标签,可以在写入数据时任意添加,因此CF支持动态扩展,无需预先定义Column的数量和类型。HBase中表的列非常稀疏,不同行的列的个数和类型都可以不同。此外,每个CF都有独立的TTL(生存周期)。可以只对行上锁,对行的操作始终是原始的。

HBase表结构

HBase每一行记录都有了行键。HBase有列族,在列族下又有了不同的列,行间和列相交的地方称为可以是单元格的内容。对于每一个单元格的内容它有版本,那么这个版本是根据时间戳来决定的。

比如说在T1时刻,我们存储进去是male,那么在T2时刻我们对male进行修改,实际上存储还是male,那么male、female都存储在HBase的单元格cell中。


  • 表:HBase采用表来组织数据,表由行和列组成,列划分为若干个列族
  • 行:每个HBase表都由若干行组成,每个行由行键(row key)来标识。
  • 列族:一个HBase表被分组成许多“列族”( column Family )的集合,它是基本的访问控制单元
  • 列限定符:列族里的数据通过列限定符(或列)来定位
  • 单元格:在HBase表中,通过行、列族和列限定符确定一个“单元格”( cell ),单元格中存储的数据没有数据类型,总被视为字节数组byte[]
  • 时间戳:每个单元格都保存着同一份数据的多个版本,这些版本采用时间戳进行去索引。

数据存储概念视图

有一个名为webtable的表,包含两个列族: contents和anchor.在这个例子里面,anchor有两个列(anchor:aa.com, anchor:bb.com),contents仅有一列(contents:html)


数据存储物理视图

尽管在概念视图里,表可以被看成是一个稀疏的行的集合。但在物理上,它的是区分列族存储的。新的columns可以不经过声明直接加入一个列族。


行存储

行存储,数据按行存储在底层文件系统中。通常,每一行会被分配固定的空间。

优点:有利于增加/修改整行记录等操作;有利于整行数据的读取操作。

缺点:单列查询时,会读取一些不必要的数据。


列存储

 HBase采用列存储

列存储,数据以列为单位,存储在底层文件系统中。

优点:有利于面向单列数据的读取/统计等操作。

缺点:整行读取时,可能需要多次I/O操作。



三、HBase体系架构

HBase架构介绍

HMaster

功能

  1. 监控 RegionServer
  2. 处理 RegionServer 故障转移
  3. 处理元数据的变更
  4. 处理 region 的分配或移除
  5. 在空闲时间进行数据的负载均衡
  6. 通过 Zookeeper 发布自己的位置给客户端
RegionServer

功能

  1. 负责存储 HBase 的实际数据
  2. 处理分配给它的 Region
  3. 刷新缓存到 HDFS
  4. 维护 HLog
  5. 执行压缩
  6. 负责处理 Region 分片


HBase的架构包括三个主要的功能组件:

  • 库函数:链接到每个客户端
  • Master主服务器
  •  HRegionServer服务器


  • 主服务器Master负责管理和维护HBase表的分区信息,维护Region服务器列表,分配Region负载均衡。
  • HRegionServer服务器负责存储和维护分配给自己的Region,处理来自客户端的读写请求。
  • 客户端并不是直接从Master主服务器上读取数据,而是在获得Region的存储位置信息后,直接从HRegionServer上读取数据。
  • 客户端并不依赖Master,而是通过Zookeeper来获得Region位置信息,大多数客户端甚至从来不和Master通信,这种设计方式使得Master负载很小。


Table  (HBase table)

     Region(Regions for the table)

         -Store(Store per ColumnFamily for each Region for the table)

          - MemStore   (MemStore for each Store for each Region for the table)

           - StoreFile   (StoreFiles for each Store for each Region for the table)

                 ~Block       (Blocks within a StoreFile within a Store for each Region for the tabie)

MemStore:顾名思义,就是内存存储,位于内存中,用来保存当前的数据操作,所以当数据保存在 WAL 中之后,RegsionServer 会在内存中存储键值对。

Store:HFile 存储在 Store 中,一个 Store 对应 HBase 表中的一个列族。

Region:Hbase 表的分片,HBase 表会根据 RowKey 值被切分成不同的 region 存储在 RegionServer 中,在一个 RegionServer 中可以有多个不同的 region。


表和Region

HBase表开始只有一个Region,后来不断分裂

Region拆分操作非常快,接近瞬间,因为拆分之后的Region读取的仍然是原存储文件,直到分裂过程结束,把存储文件异步地写到独立的文件之后,才会读取新文件


Region的定位

Region分为元数据Region以及用户Region两类。

Meta Region记录了每一个User Region的路由信息。

读写Region数据的路由,包括如下几步:

  • 找寻Meta Region地址
  • 再由Meta Region找寻user Region地址

为了加快访问速度,hbase:meta表会被保存在内存中。

假设hbase:meta表的每行(一个映射条目)在内存中大约占用1KB,并且每个Region限制为128MB。

两层结构可以保存的Region数目是128MB/1KB = 2的17次方个Region。


HMaster高可用

Zookeeper可以帮助选举出一个Master作为集群的总管,并保证在任何时刻总有唯—一个Master在运行,这就避免了Master的“单点失效”问题。

Master:主服务器Master主要负责表和Region的管理工作

  • 管理用户对表的增加、部除、修改、查询等操作。
  • 实现不同Region服务器之间的负载均衡。
  • 在Region分裂或合并后,负责重新调整Region的分布。
  • 对发生故疏失效的Region服务器上的Region进行迁移。

HRegionServer:HRegionServer是HBase中最核心的模块。负责维护分配给自己的Region。响应用户的读写请求。


四、HBase关键流程

用户读写数据过程

  • 用户写入数据时,被分配到相应HRegionServer去执行。
  • 用户数据首先被写入到Hlog中,再写入MemStore中,最终写到磁盘上形成StoreFile。
  • 只有当操作写入Hlog之后,commit()调用才会将其返回给客户端。
  • 当用户读取数据时,HRegionServer会首先访问MemStore缓存,如果找不到,再去磁盘上面的StoreFile中寻找。


缓存的刷新

●系统会周期性地把MemStore缓存里的内容刷写到磁盘的StoreFile文件中,清空缓存,并在Hlog里面写入一个标记

●每次刷写都生成-一个新的StoreFile文件, 因此,每个Store包含多个StoreFile文件

●每个HRegionServer都有一 个自己的HLog文件,每次启动都检查该文件,确认最近一 次执行缓存刷新操作之后是否发生新的写入操作;如果发现更新,则先写入MemStore,再刷写到StoreFile,开始为用户提供服务。


StoreFile的合并

  • 每次刷写都生成一个新的StoreFile,数量太多,影响查找速度调用Store.compact()把多个合并成一个
  • 合并操作比较耗费资源,只有数量达到一个阈值才启动合并



Store工作原理

Store是Region服务器的核心。多个StoreFile合并成一个。单个StoreFile过大时,又触发分裂操作,1个父Region被分裂成两个子Region 。


HLog工作原理

分布式环境必须要考虑系统出错。HBase采用HLog保证系统恢复。

HBase系统为每个Region服务器配置了一个HLog文件,它是一种预写式日志( writeAhead Log )。

用户更新数据必须首先写入日志后,才能写入MemStore缓存,并目,直到MemStore存内容对应的日志已经写入磁盘,该缓存内容才能被刷写到磁盘。


五、HBase突出特点

多HFile的影响

HFile文件数目越来越多,读取时延也越来越大。

如图所示,横坐标表示HFile文件的数目,纵坐标表示读取的时延。可以看到,在HFile文件数目较少的情况下,读取的实验呢大概在两个毫秒左右。但是随着HFile文件数目的不断增多,读取的时间将会越来越大。当HFile文件数目达到一万四千四百个左右的时候,读取的时间将达到二十毫秒,上升了一个级别,为了降低读取时延,我们采用了压缩的方法。

Compaction

Compaction的目的,是为了减少同一个Region中同一个ColumnFamily下面的小文件(HFile)数目,从而提升读取的性能。

Compaction分为Minor、Major两类:

Minor:小范围的Compaction。有最少和最大文件数目限制。通常会选择一些连续时间范围的小文件进行合并。

Major:涉及该Region该ColumnFamily 下面的所有的HFile文件。

Minor Compaction选取文件时,遵循一定的算法。

压缩( compaction)用于在 MergeOnRead存储类型时将基于行的log日志文件转化为parquet列式数据文件,用于加快记录的查找。用户可通过 hudi-cli提供的命令行显示触发 compaction或者在使用 HoodieDeltaStreamer将上游(Kafka/DFS)数据写入 hudi数据集时进行相应配置,然后由系统自动进行 compaction操作。压缩会影响到读写的性能。

OpenScanner

OpenScanner的过程中,会创建两种不同的Scanner来读取Hfile、MemStore的数据:

HFile对应的Scanner为StoreFileScannero。

MemStore对应的Scanner为MemStoreScanner。


BloomFilter

  • BloomFilter用来优化一些随机读取的场景,即Get场景。它可以被用来快速的判断一条用户数据在一个大的数据集合(该数据集合的大部分数据都没法被加载到内存中)中是否存在。
  • BloomFilter在判断一个数据是否存在时,拥有一定的误判率。但对于“用户数据XXXX不存在”的判断结果是可信的。
  • HBase的BloomFilter的相关数据,被保存在HFile中。

六、HBase性能优化

行键(Row Kev )

行键是按照字典序存储,因此,设计行键时,要充分利用这个排序特点,将经常一起读取的数据存储到一块,将最近可能会被访问的数据放在一块。

举个例子︰如果最近写入HBase表中的数据是最可能被访问的,可以考虑将时间戳作为行键的一部分,由于是字典序排序,所以可以使用Long.MAX_VALUE - timestamp作为行键,这样能保证新写入的数据在读取时可以被快速命中。


构建HBase二级索引

HBase只有一个针对行健的索引

访问HBase表中的行,只有三种方式:

  • 通过单个行健访问
  • 日通过一个行健的区间来访问
  • 全表扫描

为了提高访问速度可以构建二级索引,例如构建:

  • 多个表索引
  • 多个列索引
  • 基于部分列值的索引

七、HBase常用Shell命令

HBase常用Shell命令

create:创建表

list:列出HBase中所有的表信息

put:向表、行、列指定的单元格添加数据

scan:浏览表的相关信息

get:通过表名、行、列、时间戳、时间范围和版本号来获得相应单元格的值

enable/disable:使表有效或无效

drop:删除表


总结:

本章详细介绍了HBase数据库的知识。HBase数据库是BigTable的开源实现,和BigTable一样,支持大规模海量数据,分布式并发数据处理效率极高,易于扩展且支持动态伸缩,适用于廉价设备HBase实际上就是一个稀疏、多维、持久化存储的映射表,它采用行键、列键和时间戳进行索引,每个值都是未经解释的字符串。本章介绍了HBase数据在概念视图和物理视图中的差别。


学习推荐

华为Learning网站: https://support.huawei.com/learning

华为e学云: https://support.huawei.com/learning/elearning

华为Support案例库:https://support.huawei.com/enterprise


本文整理自华为云社区【内容共创系列】活动。
查看活动详情:https://bbs.huaweicloud.com/blogs/314887
相关任务详情:Hbase技术原理


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。