HBase 的原型是 Google 的 BigTable 论文,受到了该论文思想的启发,目前作为 Hadoop的子项目来开发维护,用于支持结构化的数据存储。
HBase 是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用 HBASE 技术可在廉价 PC Server 上搭建起大规模结构化存储集群。
HBase 的目标是存储并处理大型的数据,更具体来说是仅需使用普通的硬件配置,就能够处理由成千上万的行和列所组成的大型数据。
Hbase 适合存储 PB 级别的海量数据,在 PB 级别的数据以及采用廉价 PC 存储的情况下,能在几十到百毫秒内返回数据。
这里的列式存储其实说的是列族存储,Hbase 是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定。
Hbase 的扩展性主要体现在两个方面,一个是基于上层处理能力(RegionServer)的扩展,一个是基于存储的扩展(HDFS)。
通过横向添加 RegionSever 的机器,进行水平扩展,提升 Hbase 上层的处理能力,提升 Hbsae服务更多 Region 的能力。
备注:RegionServer 的作用是管理 region、承接业务的访问,通过横向添加 Datanode 的机器,进行存储层扩容,提升 Hbase 的数据存储能力和提升后端存
储的读写能力。
由于目前大部分使用 Hbase 的架构,都是采用的廉价 PC,因此单个 IO 的延迟其实并不小,一般在几十到上百 ms 之间。这里说的高并发,主要是在并发的情况下,Hbase 的单个IO 延迟下降并不多。能获得高并发、低延迟的服务。
稀疏主要是针对 Hbase 列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间的。
从图中可以看出 Hbase 是由 Client、Zookeeper、Master、HRegionServer、HDFS 等
几个组件组成,下面来介绍一下几个组件的相关功能:
1)Client
Client 包含了访问 Hbase 的接口,另外 Client 还维护了对应的 cache 来加速 Hbase 的访问,比如 cache 的.META.元数据的信息。
2)Zookeeper
HBase 通过 Zookeeper 来做 master 的高可用RegionServer 的监控、元数据的入口以及集群配置的维护等工作。具体工作如下:通过 Zoopkeeper 来保证集群中只有 1 个 master 在运行,如果 master 异常,会通过竞争机制产生新的 master 提供服务通过 Zoopkeeper 来监控 RegionServer 的状态,当 RegionSevrer 有异常的时候,通过回调的形式通知 Master RegionServer 上下线的信息通过 Zoopkeeper 存储元数据的统一入口地址。
3)Hmaster
master 节点的主要职责如下:为 RegionServer 分配 Region
维护整个集群的负载均衡维护集群的元数据信息发现失效的 Region,并将失效的 Region 分配到正常的 RegionServer 上 当 RegionSever 失效的时候,协调对应 Hlog 的拆分。
4)HregionServer
HregionServer 直接对接用户的读写请求,是真正的“干活”的节点。它的功能概括如下:管理 master 为其分配的 Region
处理来自客户端的读写请求负责和底层 HDFS 的交互,存储数据到 HDFS负责 Region 变大以后的拆分负责 Storefile 的合并工作。
5)HDFS
HDFS 为 Hbase 提供最终的底层数据存储服务,同时HBase 提供高可用(Hlog 存储在HDFS)的支持,具体功能概括如下:提供元数据和表数据的底层分布式存储服务数据多副本,保证的高可靠和高可用性。
与 nosql 数据库们一样,RowKey 是用来检索记录的主键。访问 HBASE table 中的行,只
有三种方式:
RowKey 行键 (RowKey)可以是任意字符串(最大长度是 64KB,实际应用中长度一般为
10-100bytes),在 HBASE 内部,RowKey 保存为字节数组。存储时,数据按照 RowKey 的字
典序(byte order)排序存储。设计 RowKey 时,要充分排序存储这个特性,将经常一起读取的
行存储放到一起。(位置相关性)
列族:HBASE 表中的每个列,都归属于某个列族。列族是表的 schema 的一部 分(而列
不是),必须在使用表之前定义。列名都以列族作为前缀。例如 courses:history,courses:math
都属于 courses 这个列族。
由{rowkey, column Family:columu, version} 唯一确定的单元。cell 中的数据是没有类型
的,全部是字节码形式存贮。
关键字:无类型、字节码
HBASE 中通过 rowkey和 columns 确定的为一个存贮单元称为cell。每个 cell都保存 着
同一份数据的多个版本。版本通过时间戳来索引。时间戳的类型是 64 位整型。时间戳可以
由 HBASE(在数据写入时自动 )赋值,此时时间戳是精确到毫秒 的当前系统时间。时间戳
也可以由客户显式赋值。如果应用程序要避免数据版 本冲突,就必须自己生成具有唯一性
的时间戳。每个 cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。
为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,HBASE 提供 了两
种数据版本回收方式。一是保存数据的最后 n 个版本,二是保存最近一段 时间内的版本(比
如最近七天)。用户可以针对每个列族进行设置。
1)Client 先访问 zookeeper,从 meta 表读取 region 的位置,然后读取 meta 表中的数据。meta
中又存储了用户表的 region 信息;
2)根据 namespace、表名和 rowkey 在 meta 表中找到对应的 region 信息;
3)找到这个 region 对应的 regionserver; 4)查找对应的 region; 5)先从 MemStore 找数据,如果没有,再到 BlockCache 里面读;
6)BlockCache 还没有,再到 StoreFile 上读(为了读取的效率); 7)如果是从 StoreFile 里面读取的数据,不是直接返回给客户端,而是先写入 BlockCache,
再返回给客户端。
1)Client 向 HregionServer 发送写请求;
2)HregionServer 将数据写到 HLog(write ahead log)。为了数据的持久化和恢复;
3)HregionServer 将数据写到内存(MemStore);
4)反馈 Client 写成功。
1)当 MemStore 数据达到阈值(默认是 128M,老版本是 64M),将数据刷到硬盘,将内存
中的数据删除,同时删除 HLog (WAL)中的历史数据;
2)并将数据存储到 HDFS 中;
3)在 HLog 中做标记点。
1)当数据块达到 4 块,Hmaster 触发合并操作,Region 将数据块加载到本地,进行合并;
2)当合并的数据超过 256M,进行拆分,将拆分后的 Region 分配给不同的 HRegionServer
管理;
3)当HRegionServer宕机后,将HregionServer上的hlog拆分,然后分配给不同的HRegionServer加载,修改.META.;
4)注意:HLog 会同步到 HDFS。
==========2020-10-15