【HBase】HBase入门详解(一)

在这里插入图片描述在这里插入图片描述在这里插入图片描述

(图片来源于网络,侵删)


一、HBASE简介

在这里插入图片描述

【1.1】 什么是HBase

1)HBase译为“Hadoop Database”,是一个构建在HDFS之上的高可靠高性能列存储可伸缩实时读写NoSQL数据库系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群
NoSQL = Not Only SQL:会有一些把 NoSQL 数据的原生查询语句封装成 SQL,比如 HBase 就有 Phoenix 工具
2)因为HDFS可以存储存储结构化半结构化松散数据,所以HBase也可以用来存储结构化半结构化松散数据
3)HBase是Google Bigtable的开源实现,但是也有很多不同之处👇

  • HBase 依赖于 HDFS 做底层的数据存储,BigTable 依赖 Google GFS 做数据存储
  • HBase 依赖于 MapReduce 做数据计算,BigTable 依赖 Google MapReduce 做数据计算
  • HBase 依赖于 ZooKeeper 做服务协调,BigTable 依赖 Google Chubby 做服务协调

4)HBase的目标是存储并处理大型的数据,更具体来说是仅需使用普通的硬件配置,就能够处理由成千上万的行和列所组成的大型数据

5) 扩展:结构化、半结构化和非结构化👇

术语 概念
结构化 数据结构字段含义确定,清晰,典型的如数据库中的表结构
半结构化 具有一定结构,但语义不够确定,典型的如 HTML 网页,有些字段是确定的(title), 有些不确定(table)
非结构化 杂乱无章的数据,很难按照一个概念去进行抽取,无规律性
【1.2】 与传统数据库的对比

1)关系型数据库 和 非关系型数据库的典型代表

  • NoSQL:HBase、Redis、Mongodb
  • RDBMS:Mysql、Oracle、Sql Server、DB2

2)传统数据库遇到的问题:

  • ① 数据量很大的时候无法存储
  • ② 没有很好的备份机制
  • ③ 数据达到一定数量开始缓慢,很大的话基本无法支撑

3)HBASE优势:

  • ① 线性扩展,随着数据量增多可以通过节点扩展进行支撑
  • ② 数据存储在HDFS上,备份机制健全
  • ③ 通过Zookeeper协调查找数据,访问速度快
【1.3】 HBase 中的表特点

1:一个表可以有上十亿行,上百万列
2面向列:面向列(族)的存储和权限控制,列(簇)独立检索
3稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏
4无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一 张表中不同的行可以有截然不同的列

【1.4】 HBase集群中的角色

1)一个或者多个主节点 : HMaster
2)多个从节点 : HRegionServer
3)HBase依赖项 :

  • Zookeeper:管理HBase元数据、监听HMaster、HRegionServer上下线、Master选举
  • HDFS:依赖HDFS作为存储、HDFS提供良好的备份机制

二、HBASE数据模型

【2.1】 Row Key

什么是Row Key?
Row Key是HBase中数据的主键,访问数据的方式都需要通过Row Key进行查询

1)访问HBase Table中的数据,只有三种方式:

  • ① 通过单个row key访问 (get)
  • ② 通过row key的range(范围) (scan)
  • ③ 全表扫描 (scan)

2)HBase会对表中的数据按照Row Key排序(字典顺序)
3)Row key只能存储64k字节数据实际应用中长度一般为 10-100bytes),在HBase内部,Row Key保存形式为字节数组

【2.2】 Column Family列族 & Column列

1)HBase表中的每个列都归属于某个列族,列族必须作为表模式(schema)定义的一部分预先给出。如 create ‘表名’, ‘列族名’
2)列名以列族作为前缀,每个“列族”都可以有多个列成员(column);如course:math, course:english, 新的列族成员(列)可以随后按需动态的加入
3)权限控制、存储以及调优都是在列族层面进行的
4)HBase把同一列族里面的数据存储在同一目录下,由几个文件保存

【2.3】 Timestamp时间戳

1)在HBase每个cell存储单元对同一份数据有多个版本,根据唯一的时间戳来区分每个版本之间的差异,不同版本的数据按照时间倒序排序最新的数据版本排在最前面
2)时间戳的类型是 64位整型
3)时间戳可以由HBase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间
4)时间戳也可以由客户显式赋值,如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳
5)为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,HBase提供了两种数据版本回收方式

  • ①.保存数据的最后n个版本
  • ②.保存最近一段时间内的版本(设置数据的生命周期TTL)

6)用户可以针对每个列族进行设置

【2.4】 Cell单元格

1)由 RowKey 和 "ColumnFamily:Column"的座标交叉决定
2)单元格是有版本的
3)单元格的内容是未解析的字节数组, 由 {row key, column( =<family> +<qualifier>), version} 唯一确定的单元;cell中的数据是没有类型的,全部是字节码形式存贮

【2.5】 VersionNum

1)数据的版本号,每条数据可以有多个版本号,默认值为系统时间戳,类型为Long

【2.6】 Region

什么是Region?
Region可以类比成关系型数据库中的分区,每个Region存储一个表中的一部分连续数据

1)HBase自动把表水平划分成多个区域(region),每个region会保存一个表里面某段连续的数据;每个表默认一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,region就会等分成两个新的region(裂变)

在这里插入图片描述
在这里插入图片描述
2)当table中的行不断增多,就会有越来越多的region。这样一张完整的表被切分成多个Region,保存在多个RegionServer
3因为RegionServer管理Region,所以Region是HBase负责均衡的最小单元,最小单元就表示不同的Region可以分布在不同的HRegion Server上,对于一张表中不同的Region,可以分布在不同的HRegionServer上,但对于一张表中的一个Region是不会拆分到多个RegionServer上的

在这里插入图片描述
4)Region虽然是负载均衡的最小单元,但并不是物理存储的最小单元;
事实上,Region由一个或者多个Store组成每个Store保存一个column family;
每个Strore又由一个MemStore和0至多个StoreFile组成

在这里插入图片描述


三、HBase各角色作用解析

【3.1】 Client

1)Client包含了访问HBase的接口,另外Client还维护了对应的cache来加速HBase的访问,比如cache.META.元数据的信息

【3.2】 Zookeeper

1)保证任何时候,集群中只有一个Active Master,如果Master异常,会通过竞争机制产生新的Master提供服务
2)存贮所有Region的寻址入口
3)实时监控RegionServer的状态,将RegionServer的上线和下线信息实时通知给Master
4)存储HBase的schematable元数据信息

【3.3】 Master

1)为RegionServer分配Region
2)负责RegionServer的负载均衡
3)发现失效的RegionServer并重新分配其上的Region
4)处理对schema更新请求

【3.4】 RegionServer

1)RegionServer维护Master分配给它的Region,处理对Region的IO请求
2)RegionServer负责切分在运行过程中变得过大的Region;可以看到,Client访问HBase上数据的过程并不需要Master参与(寻址访问Zookeeper和RegionServer,数据读写访问RegioneServer),Master仅仅维护者table和Region的元数据信息,负载很低
3)负责和底层HDFS的交互,存储数据到HDFS
4)负责Storefile的合并工作


四、HBase基于HDFS、ZK架构图

在这里插入图片描述


五、HBASE读写流程

【5.1】 写数据

在这里插入图片描述

1)Client 访问 Zookeeper,获取 hbase:meta表位于哪个 RegionServer

2)访问对应的RegionServer,获取hbase:meta表,根据rowkey的范围确定RegionServer和Region,并将该table的Region信息以及meta表的位置信息缓存在客户端的 Meta cache,方便下次访问

3)Client与目标RegionServer进行通讯,发起写入数据请求

4)Client将数据写入(追加)到HLog(WAL,Write ahead log,预写日志),以防止数据丢失

5)然后将数据写入对应的MemStore,数据会在MemStore内进行排序

6)如果HLog和Memstore都写入成功,则这条数据写入成功,向客户端发送消息,告知写入成功,如果其中一个写入失败,就表示这次写入失败

7)等达到MemStore的阈值后,将数据flush到磁盘成为StoreFile,当StoreFile达到阈值(默认3个)后进行compact操作,将多个StoreFile合并成一个大StoreFile

注意:

1)此过程没有Master的参与
2)客户端在写数据时会先去查看本地的meta cache,如果有之前的缓存数据,直接通过缓存元数据访问 RegionServer,这时不通过Zookeeper获取meta表去查找元数据,。如果集群发生某些变化导致hbase:meta元数据更改,客户端再根据本地元数据表请求的时候就会发生异常,此时客户端需要重新加载一份最新的元数据表到本地
3MemStore触发时机

【5.2】读数据

在这里插入图片描述

1)Client 访问 Zookeeper,获取 hbase:meta表位于哪个 RegionServer

2)访问对应的RegionServer,获取hbase:meta表,根据rowkey确定当前将要读取的数据位于哪个RegionServer
中的哪个Region中。并将该table的region信息以及meta表的位置缓存在客户端 meta cache,方便下次访问

3)Client向该RegionServer服务器发起读取数据请求,然后RegionServer收到请求并响应

4)分别在BlockCache(读缓存)、MemStore和StoreFile(BlockCache中有的数据
在StoreFile中就不再读取)中查询目标数据,并将查到的所有数据进行合并;
此处的所有数据指的是同一条数据的不同版本(Time Stamp)或者不同的类型(Put/Delete)

5)将从文件中查询到的数据块(Block,HFile数据存储单元,默认大小为64KB)缓存到Block Cache

6)将合并后的最终结果返回给客户端

注意:

1)此过程没有Master的参与
2)客户端在读数据时会先去查看本地的meta cache,如果有之前的缓存数据,直接通过缓存元数据访问 RegionServer,这时不通过Zookeeper获取meta表去查找元数据,。如果集群发生某些变化导致hbase:meta元数据更改,客户端再根据本地元数据表请求的时候就会发生异常,此时客户端需要重新加载一份最新的元数据表到本地

【5.3】 Flush 机制

在这里插入图片描述

flush 大致可以分为三个阶段:prepare 阶段flush 阶段commit 阶段

1)prepare 阶段
遍历当前 Region所有的 Memstore,将Memstore中当前数据集CellSkipListSet 做一个快照snapshot,之后创建一个新的CellSkipListSet,后期写入的数据都会写入新的CellSkipListSet

2)flush 阶段
遍历所有Memstore,将 prepare阶段生成的 snapshot 持久化为临时文件,临时文件会统一放到目录.tmp下。这个过程因为涉及到磁盘IO操作,因此相对比较耗时

3)commit 阶段
遍历所有 Memstore,将 flush阶段生成的临时文件移到指定的ColumnFamily目录下,针对HFile生成对应的storefileReader,把storefile添加到HStore的storefiles列表中,最后再清空prepare阶段生成的snapshot

flush 的触发条件一般分为: memstore 级别region 级别regionServer 级别HLog数量上限,具体配置可在官网文档中查询到

【5.4】 compact 机制

compact 合并机制,主要分为 minor compaction 小合并 、major compaction 大合并两个阶段

1)minor compaction 小合并
将Store中多个HFile合并为一个HFile,一次Minor Compaction的结果是HFile数量减少并且合并出一个更大的StoreFile,这种合并的触发频率很高

2)major compaction 大合并
合并 Store所有的 HFile一个HFile,此时被清理的数据有:被标记删除的数据TTL过期数据版本号超过设定版本号的数据。合并频率比较低,默认7天执行一次,并且性能消耗非常大,建议生产关闭(设置为0),在应用空闲时间手动触发。一般可以是手动控制进行合并,防止出现在业务高峰期

【5.5】 region的拆分

为什么要拆分 region 呢?
因为region中存储的是大量rowkey 数据 ,当 region 中的数据条数过多, region 变得很大的时候,直接影响查询效率,因此当 region 过大的时候.hbase会拆分region , 这也是HBase的一个优点

region 拆分策略
0.94版本前默认切分策略,当region大小大于某个阈值(hbase.hregion.max.filesize=10G)之后就会触发切分,一个region等分为2个region
0.94版本~2.0版本默认切分策略 :根据拆分次数来判断触发拆分的条件

region split的计算公式是:
regioncount^3 * 128M * 2,当region达到该 size 的时候进行split
例如:
第一次split:1^3 * 256 = 256MB
第二次split:2^3 * 256 = 2048MB
第三次split:3^3 * 256 = 6912MB
第四次split:4^3 * 256 = 16384MB > 10GB,因此取较小的值10GB
后面每次split的size都是10GB了

预分区机制
当一个Hbase 表刚被创建的时候,Hbase默认的分配一个 region 给table。也就是说这个时候,所有的读写请求都会访问到同一个 regionServer 的同一个region中,这个时候就达不到负载均衡的效果了,集群中的其他 regionServer 就可能会处于比较空闲的状态

为了解决这个问题,就有了 pre-splitting,也就是预分区机制,在创建table的时候就配置好,生成多个region,这样的好处就是可以优化数据读写效率,并且使用负载均衡机制防止数据倾斜

操作很简单,在创建表时,手动指定分区就好了:
例如👇

create 'person','info1','info2',SPLITS => ['1000','2000','3000','4000']
【5.6】 region的合并

Region的合并不是为了性能, 而是出于维护的目的
比如删除了大量的数据 ,这个时候每个Region都变得很小 ,存储多个 Region就浪费了 ,这个时候可以把Region合并起来,进而可以减少一些 Region 服务器节点,由此可见 region 的合并其实是为了更好的维护 Hbase 集群


都看到这里了,点赞评论一下吧!!!

在这里插入图片描述

点击查看👇

【HBase】HBase入门详解(二)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章