当前位置: 首页 > article >正文

【非关系型分布式数据库】HBase从入门到面试学习总结

国科大学习生活(期末复习资料、课程大作业解析、大厂实习经验心得等): 文章专栏(点击跳转)
大数据开发学习文档(分布式文件系统的实现,大数据生态圈学习文档等): 文章专栏(点击跳转)

HBase从入门到面试学习总结

  • 一、 HBase概述
    • 1.1 什么是HBase ?
    • 1.2 HBase 数据模型
      • 1.2.1 HBase 逻辑结构
      • 1.2.2 HBase 物理存储结构
      • 1.2.3 数据模型详解
    • 1.3 HBase基本架构
  • 二、HBase原理⭐
    • 2.1 Master架构
    • 2.2 RegionServer 架构
    • 2.3 HBase写流程
    • 2.4 MemStore Flush
    • 2.5 HBase读流程
      • 2.5.1 HFile 结构
      • 2.5.2 HBase读流程
      • 2.5.3 合并读取数据优化
    • 2.6 StoreFile Compaction
    • 2.7 Region Split
      • 2.7.1 预分区(自定义分区)
      • 2.7.2 系统分区
  • 三、HBase优化
    • 3.1 RowKey设计优化
    • 3.2 HBase 使用经验法则
  • 参考文献
  • 项目地址

一、 HBase概述

1.1 什么是HBase ?

Apache HBase是一个开源的非关系型分布式数据库(NoSQL),它建立在Apache Hadoop之上,特别是Hadoop的HDFS(Hadoop Distributed File System)和Hadoop MapReduce计算框架。
HBase设计用于存储大规模的稀疏数据集,它提供了对数据的随机实时读/写访问,并通过行键(RowKey)进行索引。

在这里插入图片描述

1.2 HBase 数据模型

HBase 的设计理念依据Google的BigTable论文,论文中对于数据模型的首句介绍为:Bigtable 是一个稀疏的、分布式的、持久的多维排序map。
之后对于map的解释如下:该map由行键、列键和时间戳索引;map映射中的每个值(Value)都是一个未解释的字节数组。

1.2.1 HBase 逻辑结构

HBase 可以用于存储多种结构的数据,以JSON为例,存储的数据原貌为:

{ 
	"row_key1":{ 
		"personal_info":{ 
			"name":"zhangsan", 
			"city":"北京", 
			"phone":"131********" 
		}, 
		"office_info":{ 
			"tel":"010-1111111", 
			"address":"atguigu" 
		} 
	}, 
	"row_key2":{
 		"personal_info":{
 			"city":"上海",
 			"phone":"132********" 
		},
 		"office_info":{ 
			"tel":"010-1111111" 
		} 
	}, 
	……
}

在HBase里边,定位一行数据会有一个唯一的值,这个叫做行键(RowKey)。而在HBase的列不是我们在关系型数据库所想象中的列。HBase的列(Column)都得归属到列族(Column Family)中。在HBase中用列修饰符(Column Qualifier)来标识每个列。
在HBase里边,先有列族,后有列。

在这里插入图片描述

1.2.2 HBase 物理存储结构

物理存储结构即为数据映射关系,而在上面概念视图的空单元格,底层实际根本不存储。

在这里插入图片描述

1.2.3 数据模型详解

  1. NameSpace:命名空间类似于关系型数据库的database概念,每个命名空间下有多个表(Table)。HBase两个自带的命名空间,分别是hbase和default,hbase中存放的是HBase内置的表,default表是用户默认使用的命名空间。
  2. Table类似于关系型数据库的表概念。不同的是,HBase定义表时只需要声明列族即可,不需要声明具体的列。因为数据存储时稀疏的,所有往HBase写入数据时,字段可以动态、按需指定。因此和关系型数据库相比,HBase能够轻松应对字段变更的场景。
  3. Row:HBase 表中的每行数据都由一个RowKey和多个Column(列)组成,数据是按照RowKey 的字典顺序存储的,并且查询数据时只能根据RowKey进行检索,所以RowKey的设计十分重要。
  4. Column:HBase 中的每个列都由Column Family(列族)和Column Qualifier(列限定符)进行限定,例如 info:name,info:age。建表时,只需指明列族,而列限定符无需预先定义。
  5. TimeStamp:用于标识数据的不同版本(version),每条数据写入时,系统会自动为其加上该字段,其值为写入HBase的时间。
  6. Region:HBase中数据的水平切片,每个Region包含表中一定范围的行。当 Region 增长到一定大小后,会进行分裂(split),以保持系统的可扩展性。每个 Region 由一个RegionServer管理。
  7. Cell数据存储的最小单元。由{rowkey, column Family:column Qualifier, timestamp} 唯一确定的单元,在 HBase 中,数据是按照 Cell 来组织的(数据的读写操作都是基于 Cell 的。例如,当你读取一行数据时,你实际上是在读取该行中所有Cell的值。同样,当你写入数据时,你也是在写入一个或多个Cell)。Cell中的数据全部是字节码形式存贮。

1.3 HBase基本架构

  1. HMaster
    • HBase 的主服务器,负责管理集群元数据和协调集群操作,如表的创建、删除、区域分配(region assignment)和负载均衡。
    • HMaster 监控集群状态,处理 RegionServer 的上线和下线,并负责表的元数据管理。(注意,读写数据的请求无需HMaster参与)。
  2. RegionServer
    • 负责处理客户端对数据的所有读写请求,例如写入数据put,查询数据get等
    • 管理表的物理存储,包括数据文件和索引文件。
    • 执行数据的存储和检索操作(即读写),以及数据的压缩、分裂和合并等维护任务(由HMaster监控,由RegionServer执行)。
  3. Zookeeper
    • HBase 通过Zookeeper 来做 master 的高可用、记录RegionServer的部署信息、并且存储meta表的位置信息。HBase对于数据的读写操作时直接访问Zookeeper。
  4. HDFS
    • HDFS为Hbase提供最终的底层数据存储服务,同时为HBase提供高容错的支持。

二、HBase原理⭐

2.1 Master架构

在这里插入图片描述

  • Meta表格:全称为hbase:meta,只是在list命令中被过滤掉了,本质上和HBase的其他表格一样。
  • RowKey: ([table],[region start key],[region id]) 即表名,region起始位置和regionID。
  • : info:regioninfo 为 region 信息,存储一个HRegionInfo 对象。 info:server 当前 region 所处的RegionServer 信息,包含端口号。info:serverstartcode 当前 region 被分到 RegionServer 的起始时间。

注意
在客户端对元数据进行操作的时候才会连接master,如果仅仅是对数据进行读写,直接连接zookeeper 读取目录/hbase/meta-region-server 节点信息,会记录meta表格的位置。直接读取即可,不需要访问master,这样可以减轻master的压力,相当于master专注meta表的写操作,客户端可直接读取meta表。

2.2 RegionServer 架构

在这里插入图片描述

架构图详解:

  1. MemStore
    写缓存,由于HFile中的数据要求是有序的,所以数据是先存储在MemStore中,排好序后,等到达刷写时机才会刷写到HFile,每次刷写都会形成一个新的HFile,写入到对应的文件夹store中。
  2. WAL
    由于数据要经MemStore 排序后才能刷写到HFile,但把数据保存在内存中会有很高的概率导致数据丢失,为了解决这个问题,数据会先写在一个叫做Write-Ahead logfile的文件中(预写日志),然后再写入MemStore中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。
  3. BlockCache
    读缓存,每次查询出的数据会缓存在BlockCache中,方便下次查询。

2.3 HBase写流程

在这里插入图片描述

具体流程:

  1. 首先访问Zookeeper,获取hbase:meta表位于哪个RegionServer;
  2. 访问对应的RegionServer,获取hbase:meta表并将其缓存到内存中,作为连接属性MetaCache,由于表格具有一定的数据量,所以导致此链接较慢。
  3. 之后使用创建的连接获取Table(一个轻量级的连接),只有在第一次创建的时候会检查表格是否存在而访问RegionServer,之后再获取Table时不会访问RegionServer;
  4. 调用Table的put方法写入数据,此时还需要解析RowKey,对照缓存的MetaCache,查看具体写入的位置有哪个RegionServer;
  5. 将数据顺序写入(追加)到WAL(预写日志),此处写入是直接落盘的,并设置专门的线程控制WAL预写日志的滚动(类似Flume);
  6. 根据写入命令的RowKey和ColumnFamily查看具体写入到哪个MemStore,并且在MemStore中排序;
  7. 向客户端发送ack;
  8. 等达到MemStore的刷写时机后,将数据刷写到对应的StoreFile中。

2.4 MemStore Flush

在这里插入图片描述

MemStore 刷写由多个线程控制,条件互相独立(同时生效):
主要的刷写规则是控制刷写文件的大小,在每一个刷写线程中都会进行监控.

  1. 当某个memstroe的大小达到了hbase.hregion.memstore.flush.size(默认值 128M), 其所在region的所有memstore都会刷写。
    当memstore 的大小达到了 hbase.hregion.memstore.flush.size(默认值 128M) * hbase.hregion.memstore.block.multiplier(默认值 4) 时,会刷写同时阻止继续往该memstore写数据(防止数据丢失)。

  2. 由 HRegionServer 中的属性 MemStoreFlusher 内部线程 FlushHandler 控制。标准为 LOWER_MARK(低水位线)和HIGH_MARK(高水位线),意义在于避免写缓存使用过多的内存造成OOM:
    当region server 中 memstore 的总大小达到低水位线

    java_heapsize * hbase.regionserver.global.memstore.size(默认值 0.4* hbase.regionserver.global.memstore.size.lower.limit(默认值 0.95

    region 会按照其所有memstore的大小顺序(由大到小)依次进行刷写。直到region server中所有memstore的总大小减小到上述值以下。
    当region server 中 memstore 的总大小达到高水位线 java_heapsize * hbase.regionserver.global.memstore.size(默认值 0.4) 时,会同时阻止继续往所有的memstore写数据。

  3. 为了避免数据过长时间处于内存之中,到达自动刷写的时间,也会触发 memstore flush。由 HRegionServer 的属性 PeriodicMemStoreFlusher 控制进行,由于重要性比较低,5min才会执行一次。

  4. 当WAL文件的数量超过hbase.regionserver.max.logs,region 会按照时间顺序依次进行刷写,直到WAL文件数量减小到hbase.regionserver.max.log 以下(该属性名已经废弃,现无需手动设置,最大值为32)。

2.5 HBase读流程

2.5.1 HFile 结构

在了解读流程之前,需要先知道读取的数据是什么样子的。

HFile 是存储在HDFS上面每一个Store文件夹下实际存储数据的文件。里面存储多种内容。包括数据本身(keyValue键值对)、元数据记录、文件信息、数据索引、元数据索引和一个固定长度的尾部信息(记录文件的修改情况)。每一个HFile还会维护一个布隆过滤器(就像是一个很大的Map,文件中每有一种key, 就在对应的位置标记,读取时可以大致判断要get的key是否存在HFile中)。
KeyValue 内容如下:

rowlength -----------→ key 的长度 
row -----------------→ key 的值 
columnfamilylength --→ 列族长度 
columnfamily --------→ 列族 
columnqualifier -----→ 列名 
timestamp -----------→ 时间戳(默认系统时间) 
keytype -------------Put

注:HFile 存储经过序列化,无法直接查看

2.5.2 HBase读流程

  1. 首先依然是创建connection连接(方法同HBase写流程)
  2. 创建Table对象发送get请求。
  3. 优先访问Block Cache,查找是否之前读取过,并且可以读取HFile的索引信息和布隆过滤器。
  4. 不管读缓存(Block Cache)中是否已经有数据了(因为可能已经过期),都需要再次读取写缓存和 store 中的文件(至少读取三个位置的数据)。
  5. 最终将所有读取到的数据合并版本,按照Get的要求返回即可。

2.5.3 合并读取数据优化

优化原因:每次读取数据都至少需要读取三个位置,最后进行版本的合并。效率会非常低,所以系统需要对此优化:

  1. HFile 带有索引文件,读取对应RowKey数据会比较快。
  2. Block Cache 会缓存之前读取的内容和元数据信息,如果HFile 没有发生变化(记录在HFile 尾信息中),则不需要再次读取。
  3. 使用布隆过滤器能够快速过滤当前HFile不存在需要读取的RowKey,从而避免读取文件。(布隆过滤器使用HASH算法,不是绝对准确的,出错会造成多扫描一个文件,对读取数据结果没有影响)

2.6 StoreFile Compaction

由于Memstore每次刷写都会生成一个新的HFile,文件过多读取不方便,所以会进行文件的合并,清理掉过期和删除的数据,会进行StoreFile Compaction
Compaction 分为两种,分别是Minor Compaction 和Major Compaction。

  • Minor Compaction 会将临近的若干个较小的HFile合并成一个较大的HFile,并清理掉部分过期和删除的数据, 由系统使用一组参数自动控制;
  • Major Compaction 会将一个Store下的所有的HFile合并成一个大HFile,并且会清理掉所有过期和删除的数据,由参数hbase.hregion.majorcompaction 控制,默认7天。

在这里插入图片描述

Minor Compaction 控制机制:
参与到小合并的文件需要通过参数计算得到,有效的参数有5个:

(1)hbase.hstore.compaction.ratio(默认 1.2F)合并文件选择算法中使用的比率。 
(2)hbase.hstore.compaction.min(默认 3) 为 Minor Compaction 的最少文件个数。 
(3)hbase.hstore.compaction.max(默认 10) 为 Minor Compaction 最大文件个数。 
(4)hbase.hstore.compaction.min.size(默认 128M)为单个 HFile 文件大小最小值,小于这个数会被合并。 
(5)hbase.hstore.compaction.max.size(默认 Long.MAX_VALUE)为单个 HFile 文件大小最大值,高于这个数不会被合并。

小合并(Minor Compaction)机制为拉取整个store中的所有文件,做成一个集合。之后按照从旧到新的顺序遍历。 判断条件为:

  1. 过小合并,过大不合并;
  2. 文件大小 / hbase.hstore.compaction.ratio < (剩余文件大小和) 则参与压缩。所以把比值设置过大,如10,会最终合并为1个特别大的文件,相反设置为0.4,会最终产生4个storeFile。 不建议修改默认值;
  3. 满足压缩条件的文件个数达不到个数要求(3 <= count <= 10)则不压缩。

2.7 Region Split

在这里插入图片描述

Region 切分分为两种,创建表格时候的预分区即自定义分区,同时系统默认还会启动一个切分规则,避免单个Region中的数据量太大

2.7.1 预分区(自定义分区)

每一个region维护着startRow 与endRowKey,如果加入的数据符合某个region维护的 rowKey 范围,则该数据交给这个region维护。那么依照这个原则,我们可以将数据所要投放的分区提前大致的规划好,以提高HBase性能。

2.7.2 系统分区

Region的拆分是由HRegionServer完成的,在操作之前需要通过ZK汇报master,修改对应的Meta表信息添加两列info:splitA和info:splitB信息。之后需要操作HDFS上面对应的文件,按照拆分后的Region范围进行标记区分,实际操作为创建文件引用,不会挪动数据。刚完成拆分的时候,两个Region都由原先的RegionServer管理。之后汇报给Master, 由Master将修改后的信息写入到Meta表中。等待下一次触发负载均衡机制,才会修改Region 的管理服务者,而数据要等到下一次压缩时,才会实际进行移动。
不管是否使用预分区,系统都会默认启动一套Region 拆分规则。不同版本的拆分规则有差别。Hbase 2.0 引入了新的split策略:

  • 如果当前RegionServer上该表只有一个Region, 按照 2 * hbase.hregion.memstore.flush.size 分裂,
  • 否则按照 hbase.hregion.max.filesize 分裂。

三、HBase优化

3.1 RowKey设计优化

一条数据的唯一标识就是RowKey,那么这条数据存储于哪个分区,取决于RowKey处于哪个一个预分区的区间内,设计rowkey的主要目的,就是让数据均匀的分布于所有的Region中,在一定程度上防止数据倾斜(即:热点问题)。那么如何解决热点问题(数据倾斜),一般考虑以下几种方式:

  1. Hash散列设计
    使用一个Hash值作为RowKey的前缀,Hash可以将数据负载均衡的分配到集群中;如何实现Hash散列,方式有很多,比如:将某一个字段假如是host字段取Hash之后放在rowkey的前面,或者说通过MD5Hash之后取前几位放在Rowkey的前面。这种方式可以很好的将rowkey均衡的分布到region上面,不会导致单个region的压力增大。
  2. 时间戳TimeStamp
    对于时间要求比较高的读来说,可以选择在Rowkey后面添加timestamp,比如如果我们根据时间去查询1分钟,1小时,1天内的数据,那么这个就可以考虑在Rowkey中加入timestamp。
  3. “翻转TimeStamp”
    “翻转timstamp”并将tiamestamp拼接上去,可以有效的保证第一条数据是最新的,这样当要get最新的一条数据的时候,根据条件读取第一条数据即可。(此翻转非彼翻转:RowKey = Host + Item + Long.MAX_VALUE – timestamp)。
  4. Salting
    Salting与加密无关,它指的是将随机数放在RowKey的起始处,salting给每一RowKey随机指定了一个前缀来让它与其它行键有着不同的顺序,以此解决热点问题。

3.2 HBase 使用经验法则

官方给出了权威的使用法则:

  1. Region 大小控制10-50G
  2. Cell大小不超过10M(性能对应小于100K的值有优化),如果使用mob(Medium sized Objects 一种特殊用法)则不超过50M。
  3. 1张表有1到3个列族,不要设计太多。最好就1个,如果使用多个尽量保证不 会同时读取多个列族。
  4. 1到2个列族的表格,设计50-100个Region
  5. 列族名称要尽量短,不要去模仿RDBMS(关系型数据库)具有准确的名称和描述。
  6. 如果RowKey设计时间在最前面,会导致有大量的旧数据存储在不活跃的Region 中,使用的时候,仅仅会操作少数的活动Region,此时建议增加更多的Region个数
  7. 如果只有一个列族用于写入数据,分配内存资源的时候可以做出调整,即写缓存不会占用太多的内存。

参考文献

Apache HBase – Apache HBase® Home

HBase架构详解及读写流程-腾讯云开发者社区-腾讯云 (tencent.com)

尚硅谷HBase2.x教程来袭,从零出发,全面掌握

项目地址

BigDataDev: 大数据核心框架学习pro (gitee.com)
在这里插入图片描述

欢迎大家参考!


15点23分 2024年10月18日
非关系型分布式数据库 —— HBase内容学习整理,如有错误,欢迎评论区交流指出。
不积跬步无以至千里!


http://www.kler.cn/a/372276.html

相关文章:

  • WPF拖拽交互全攻略及实现自定义拖拽控件及数据交换技巧解析
  • 大学必考的三个证书
  • 推荐一款优秀的pdf编辑器:Ashampoo PDF Pro
  • 【Linux网络】UdpSocket
  • Vue插件能做什么,Vue如何自定义插件
  • centos7.X zabbix监控参数以及邮件报警和钉钉报警
  • Python实现随机分布式延迟PSO优化算法(RODDPSO)优化DBSCAN膨胀聚类模型项目实战
  • IDEA 安装热部署 JRebel -新版-亲测有效
  • Android13预置应用及授权开发
  • Thread类及线程的核心操作
  • Java集合常见面试题总结(5)
  • 常见的开发工具及其作用
  • [论文阅读] GPT-4 Technical Report
  • Kotlin-协程基础
  • 【面试经典150】day 9
  • PostgreSQL 清理 WAL 文件
  • 2024“源鲁杯“高校网络安全技能大赛-Misc-WP
  • 逆变器竞品分析--绿联150W方案【2024/10/30】
  • Docker搭建官方私有仓库registry及相关配置
  • 基于树莓派的安保巡逻机器人--(一、快速人脸录入与精准人脸识别)
  • DGUS屏使用方法
  • 易至狂欢购车季火热开启,EV3青春版打造年轻一代出行新选择
  • 【MMIN】缺失模态想象网络用于不确定缺失模态的情绪识别
  • 相关矩阵图——Python实现
  • 【Android】Kotlin教程(4)
  • Ubuntu20.04安装VM tools并实现主机和虚拟机之间文件夹共享