【HBase】数据模型与架构

580 阅读8分钟

「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战

零、简介

HBase 基于 GoogleBigTable 论文而来, 是一个分布式海量列式非关系型数据库系统, 可以提供超大规模数据集的实时随机读写。

BigTable 的开源实现: 架构上通过数据分片的设计配合 HDFS,实现了数据的分布式海量存储; 数据结构上通过列族的设计,实现了数据表结构可以在运行期自定义; 存储上通过 LSM 树的方式,使数据可以通过连续写磁盘的方式保存数据,极大地提高了数据写入性能。

(1)特点

  • 海量存储: 底层基于 HDFS 存储海量数据
  • 列式存储: HBase 表的数据是基于列族进行存储的,一个列族包含若干列
  • 极易扩展: 底层依赖 HDFS,当磁盘空间不足的时候,只需要动态增加 DataNode 服务节点就可以
  • 高并发: 支持高并发的读写请求
  • 稀疏: 稀疏主要是针对 HBase 列的灵活性, 在列族中, 你可以指定任意多的列, 在列数据为空的情况下, 是不会占用存储空间的。
  • 数据的多版本: HBase 表中的数据可以有多个版本值, 默认情况下是根据版本号去区分, 版本号就是插入数据的时间戳
  • 数据类型单一: 所有的数据在 HBase 中是以字节数组进行存储

(2)应用

  • 交通方面: 船舶 GPS 信息, 每天有上千万左右的数据存储。
  • 金融方面: 消费信息、贷款信息、信用卡还款信息等
  • 电商方面: 电商网站的交易信息、物流信息、游览信息等
  • 电信方面: 通话信息

总结: HBase 适合海量明细数据的存储, 并且后期需要有很好的查询性能(单表超千万、上亿,且并发要求高)

一、可伸缩架构

HBase为可伸缩海量数据存储而设计,实现面向在线业务的实时数据访问延迟。

HBase的伸缩性主要依赖其可分裂的HRegion及可伸缩的分布式文件系统HDFS实现。

架构图如下: 9f4220274ef0a6bcf253e8d012a6d4f7.png

  1. ZooKeeper
  • 实现了 HMaster 的高可用
    • 保存了 HBase 的元数据信息, 是所有 HBase 表的寻址入口
  • HMasterHRegionServer 实现了监控
  1. HMaster

所有 HRegion 的信息,包括存储的 Key 值区间、所在 HRegionServer 地址、访问端口号等,都记录在 HMaster 服务器上。 为了保证 HMaster 的高可用,HBase 会启动多个 HMaster,并通过 ZooKeeper 选举出一个主服务器。

  • HRegionServer 分配 Region
  • 维护整个集群的负载均衡
  • 维护集群的元数据信息
  • 发现失效的 Region , 并将失效的 Region 分配到正常的 HRegionServer
  1. HRegionServer

HRegionServer 是物理服务器,每个 HRegionServer 上可以启动多个 HRegion 实例。 当一个 HRegion 中写入的数据太多,达到配置的阈值时,一个 HRegion 会分裂成两个 HRegion,并将 HRegion 在整个集群中进行迁移,以使 HRegionServer 的负载均衡。

  • 负责管理 Region
  • 接受客户端的读写数据请求
  • 切分在运行过程中变大的 Region
  1. HRegion

HBase 负责数据存储的主要进程,应用程序对数据的读写操作都是通过和 HRegion 通信完成。 上面是 HBase 架构图,可以看到在 HBase 中,数据以 HRegion 为单位进行管理,也就是说应用程序如果想要访问一个数据,必须先找到 HRegion,然后将数据读写操作提交给 HRegion,由 HRegion 完成存储层面的数据操作。 每个 HRegion 中存储一段 Key 值区间[key1, key2) 的数据。

  • 每个 HRegion 由多个 Store 构成
  • 每个 Store 保存一个列族(Columns Family), 表有几个列族, 则有几个 Store
  • 每个 Store 由一个 MemStore 和多个 StoreFile 组成, MemStoreStore 在内存中的内容, 写到文件后就是 StoreFileStoreFile 底层是以 HFile 的格式保存。

读取时序图,如下:

9fd982205b06ecd43053202da2ae08ab.png

如上时序图,可知步骤:

  1. 应用程序通过 ZooKeeper 获得主 HMaster 的地址
  2. 输入 Key 值获得这个 Key 所在的 HRegionServer 地址
  3. 然后请求 HRegionServer 上的 HRegion,获得所需要的数据。

小结:

  1. HBase 的核心设计目标是解决海量数据的分布式存储,和 Memcached 这类分布式缓存的路由算法不同。

  2. HBase 的做法是按 Key 的区域进行分片,这个分片也就是 HRegion

  3. 应用程序通过 HMaster 查找分片,得到 HRegion 所在的服务器 HRegionServer,然后和该服务器通信,就得到了需要访问的数据。

二、可扩展数据模型

为了提高数据写入速度,HBase 使用了一种叫作 LSM 树的数据结构进行数据存储。

LSM 树 : Log Structed Merge Tree,即 Log 结构合并树。

数据写入的时候以 Log 方式连续写入,然后异步对磁盘上的多个 LSM 树进行合并。

LSM 树,如图:

5fbd17a9c0b9f1a10347a4473d00ad3b.jpg

LSM 树可以看作是一个 N 阶合并树。

数据写操作(包括插入、修改、删除)都在内存中进行,并且都会创建一个新记录(修改会记录新的数据值,而删除会记录一个删除标志)。

这些数据在内存中仍然还是一棵排序树,当数据量超过设定的内存阈值后,会将这棵排序树和磁盘上最新的排序树合并。

当这棵排序树的数据量也超过设定阈值后,会和磁盘上下一级的排序树合并。

合并过程中,会用最新更新的数据覆盖旧的数据(或者记录为不同版本)。

在需要进行读操作时,总是从内存中的排序树开始搜索,如果没有找到,就从磁盘 上的排序树顺序查找。

LSM 树上进行一次数据更新不需要磁盘访问,在内存即可完成。

当数据访问以写操作为主,而读操作则集中在最近写入的数据上时,使用 LSM 树可以极大程度地减少磁盘的访问次数,加快访问速度。

三、数据模型

逻辑架构如图:

2020-08-2808:25.png

物理架构如图:

2020-08-2808:30.png

  1. NameSpace(数据库) 命名空间

类似于关系型数据库的 database 概念, 每个命名空间下有多个表。 HBase 两个自带的命名空间, 分别是 hbasedefault , hbase 中存放的是 HBase 内置的表, default 表是用户默认使用的命名空间。 一个表可以自由选择是否有命名空间, 如果创建表的时候加上了命名空间后, 这个表名字以: 作为区分!

  1. Table 类似于关系型数据库的表概念。

不同的是, HBase 定义表时只需要声明列族即可, 数据属性, 比如超时时间(TTL), 压缩算法(COMPRESSION)等, 都在列族的定义中定义,不需要声明具体的列。

  1. Row

(一行逻辑 HBase 表中的每行数据都由一个 RowKey 和多个 Column (列)组成。一个行包含了多个列,这些列通过列族来分类,行中的数据所属列族只能从该表所定义的列族中选取, 不数据) 能定义这个表中不存在的列族, 否则报错 NoSuchColumnFamilyException

  1. RowKey (每行据主键)

Rowkey 由用户指定的一串不重复的字符串定义, 是一行的唯一标识! 数据是按照 RowKey 的字典顺序存储的, 并且查询数据时只能根据 RowKey 进行检索, 所以 RowKey 的设计十分重要。 如果使用了之前已经定义的 RowKey , 那么会将之前的数据更新掉!

  1. Column Family(列族)

列族是多个列的集合。

  • 一个列族可以动态地灵活定义多个列。
  • 表的相关属性大部分都定义在列族上, 同一个表里的不同列族可以有完全不同的属性配置, 但是同一个列族内的所有列都会有相同的属性。
  • 列族存在的意义是 HBase 会把相同列族的列尽量放在同一台机器上, 所以说, 如果想让某几个列被放到一起, 你就给他们定义相同的列族。
  1. Column Qualifier (列)

Hbase 中的列是可以随意定义的, 一个行中的列不限名字、不限数量, 只限定列族。 因此列必须依赖于列族存在! 列的名称前必须带着其所属的列族! 例如 info:name,info:age

  1. TimeStamp (时间戳--》版本)

用于标识数据的不同版本( version )。 时间戳默认由系统指定, 也可以由用户显式指定。 在读取单元格的数据时, 版本号可以省略, 如果不指定, Hbase 默认会获取最后一个版本的数据返回!

  1. Cell

一个列中可以存储多个版本的数据。而每个版本就称为一个单元格( Cell )。

  1. Region (表的分区)

Region 由一个表的若干行组成! 在 Region 中行的排序按照行键(rowkey)字典排序。 Region 不能跨 RegionSever, 且当数据量大的时候, HBase 会拆分 Region