Java大数据平台开发 学习笔记(70) —— Hbase 原理(附 Hbase 百度云盘下载地址)

一、简介

1.1、概述

  1. HBase是Yahoo!开发的后来贡献给了Apache的一套基于Hadoop的、分布式的、可伸缩的非关系型数据库
  2. HBase能够对大量数据进行随机且实时的读写
  3. HBase能够管理非常大的表:billions of rows X millions of columns
  4. HBase是Doug Cutting根据谷歌的论文来仿照实现的,因此HBase和Big Table的实现原理一模一样,只是语言不一样
  5. HBase在设计和存储的时候,借鉴了列存储的思想
  6. HBase作为一个非关系型数据库,不支持SQL
  7. HBase中没有表关联的概念
  8. HBase可以存储稀疏数据 - 适合于存储结构化和半结构化(数据本身有结构但是解析之后无法利用固定的字段来存储)数据
  9. HBase作为一个数据库,提供了完整的增删改查的功能,而HBase是基于HDFS来存储的。但是HDFS允许一次写入多次读取不允许修改但是允许追加,而HBase又提供了"改"这个功能,那么HBase怎么实现"改"的?- HBase的"改"并不是修改已经写入的数据,而是追加数据。追加完成之后,每次获取数据的时候,都会提供最后追加的数据,那么从用户角度而言,就实现了"改"的功能
  10. HBase会为每一条新加的数据来添加一个时间戳作为标记,这个时间戳称之为VERSION(版本)
    11.在HBae中,通过行键+列族+列+版本才能确定唯一的一条数据,这个结构称之为Cell(单元格)
  11. 在HBase中,如果不指定,那么表默认只会对外提供一个版本的数据,最多也只会保留一个版本的数据。如果需要对外获取多个版本的数据,那么需要在建表的时候给定,或者表建好之后,修改表的属性
  12. 在获取数据的时候,只要不指定,就只会获取1个版本的数据

1.2、基本概念

  1. RowKey - 行键
    a. 在HBase中,没有主键的概念,取而代之的是行键
    b. 不同于MySQL,在定义表的时候,不需要定义行键列,而是在添加数据的时候,手动指定行键
    c. 在HBase中,默认会对行键进行排序,默认是按照字典序排序
    d. 在实际开发中,可以考虑利用Elastic Search来对HBase的行键来建立索引
  2. Column Family - 列族/列簇
    a. 在HBase中,一张表中可以包含1到多个列族,理论上,不限制列族的数量。但是实际开发中,列族的数量一般不超过3个
    b. 每一个列族中,可以包含0到多个列 - 在HBase中,强调列族不强调列,列可以动态增删
  3. namespace - 名称空间
    a. HBase中没有database的概念,取而代之的是namesapce
    b. HBase启动的时候,会自带2个空间:default和hbase。其中hbase空间下一般存放hbase本身的一些信息;在建表的时候如果不指定,则表默认放在default空间下

1.3、命令

在这里插入图片描述

1.3、优化机制

  1. 在实际生产过程中,在设计行键的时候要尽量散列
  2. 行键在设计的时候要尽量短,且唯一
  3. 行键最好是字符串,且最好有意义
  4. 虽然在HBase中,不限制列族的数量,但是一般而言,列族的数量最好不要超过3个
  5. 在设计的时候,尽量将具有相似性值的列或者经常查询的列放在一个列族中
  6. 调节DataBlock的大小:小的DataBlock利于查询,大的DataBlock利用遍历
  7. 适当的关闭BlockCache:如果在遍历操作偏多的情况下,可以考虑关闭BlockCache
  8. 在HBase中,默认情况下,布隆过滤器是对行键来进行过滤。那么可以选择过滤级别:NONE/ROW/ROWCOL
  9. 如果HBase占用了大量的HDFS的空间导致HDFS的空间不够,那么可以考虑开启它的压缩机制。通过COMPRESSION来调节,默认为NONE,即默认对结果是不压缩的,可以将这个属性值改为LZO/GZIP/SNAPPY
  10. 在查询数据的时候,指定的信息越详细,那么在网络中传输的数据量就越少
  11. 在读写的时候,如果数据量较大,那么考虑将数据放到List集合中来进行批量读写
    如果能够忍受一定程度上的数据丢失,那么可以考虑关闭WAL日志,那么当HRegionServer接收到写请求只会就会直接将数据记录到memStore中而不用再将命令记录到WAL中,从而提高效率
  12. 在HBase中,当HRegion达到指定大小的时候,会进行分裂和转移,分裂和转移都会导致HBase的读写效率相对变低。在能够预估数据量的前提下,可以在建表的时候就提前创建好HRegion,从而减少HRegion的分裂和转移所花费的时间
  13. 减少HMaster和Zookeeper的心跳时间。默认情况下,Active HMaster每隔180s(3min)会给Zookeeper来发送一次心跳。也就意味着如果Active HMaster宕机,那么最坏的情况下,Zookeeper需要3min才能发掘Active HMaster的故障,才会将Backup HMaster切换为Active状态。在Active HMaster宕机期间,HBase集群会暂停对外提供服务。那么在实际生产环境中,是不能忍受3min的故障时间的,所以需要考虑将这个心跳时间缩短。所以需要在hbase-site.xml中文件中通过zookeeper.session.timeout来条件时间,单位是s。实际开发中,这个时间一般会设置为10~30S

二、基本理论

2.1、HRegion

  1. 在HBase中,会从行键方向上对HBase中的表进行切分,切出来的每一个块结构称之为是一个HRegion - 在HBase中,一个表由1个或者多个HRegion来构成的
  2. 每一个HRegion会交给一HRegionServer来进行管理,这样就保证数据和请求不会集中于一个节点上
  3. 因为行键是有序的,所以HRegion之间的数据是不交叉的,从而保证请求会散落到不同的节点上
  4. 随着时间延长,请求越来越多,那么HRegion中的数据也会越来越多。当HRegion达到指定大小(默认是10G),那么这个HRegion会就会产生分裂,平均裂为两个等大的HRegion。分裂完成之后,其中一个HRegion会发生转移,转移给其他的HRegionServer来进行管理 - 这个过程中几乎不会发生数据的转移,只是管理权的转移
  5. 每一个HRegion中,会包含1到多个HStore,HStore的数量由列族的数量决定
  6. 每一个HStore中,还会包含1个memStore以及0到多个HFile/StoreFile

2.2、Zookeeper

  1. Zookeeper充当了注册中心
  2. 当HBase启动的时候,会自动的在Zookeeper的根目录下注册一个子节点/hbase
  3. 当Active HMaster启动的时候,会自动的在Zookeeper上来注册一个临时节点/hbase/master
  4. 当Backup HMaster启动的时候,会自动的在Zookeeper的/hbase/backup-masters节点下来注册子节点
  5. 当HRegionServer启动的时候,也会自动的在Zookeeper的/hbase/rs节点下来注册子节点

2.3、HMaster

  1. 当HMaster全部宕机之后,整个HBase集群会暂停对外提供服务
  2. HBase允许在任何一台安装了HBase的服务器上来通过命令启动HMaster:hbase-daemon.sh start master
  3. 在HBase中,理论上不限制HMaster的个数
  4. 如果启动了多个HMaster,那么这多个HMaster之间会存在Active和Backup状态
  5. 如果启动了多个HMaster,那么最早在Zookeeper上注册节点的HMaster会成为Active状态,后注册的会成为Backup状态
  6. 当Active HMaster收到请求之后,需要将请求同步给其他的Backup HMaster。因此,虽然在HBase中,不限制HMaster的个数,但是在实际生产过程中,HMaster的个数一般不会超过3个:1个Active+2个Backup
  7. Active HMaster会实时监控/hbase/backup-masters下的节点的变化
  8. 如果Active HMaster宕机,那么Zookeeper自动的将最早注册的Backup HMaster切换为Active状态
  9. HMaster的职责
    a. 负责管理HRegionServer,主要负责管理HRegion在HRegionServer之间的分布和转移
    b. 负责记录元数据。所有的DDL(Data Defined Language - 数据定义语言,定义数据结构和属性,例如create/drop/alter等)操作都会经过HMaster,所有的DML(Data Manipulation Language - 数据操纵语言,改变数据,例如put/delete等)操作不会经过HMaster
  10. HBase中的元数据主要包含了namespace名、表名、列族名以及各种属性

2.4、读写流程

  1. 在0.96之前,.meta.文件是可切分的;从0.96开始,.meta.文件不允许切分
  2. 从0.96开始,客户端在访问Zookeeper之后,自动缓存.meta.文件的位置
  3. 从0.96开始,客户端会自动缓存HRegion的位置
  4. 也正因为客户端会做大量缓存,所以随着时间的推移,客户端的缓存会越来越多,HBase的效率也会越来越高。如果这个过程中,HRegion发生分裂转移或者客户端产生崩溃,都会导致客户端的缓存失效,客户端就需要重新建立缓存

2.5、HRegionServer

  1. c在实际生产过程中,为了方便数据的管理,减少跨集群的数据传输,所以一般会将DataNode和HRegionServer部署在相同的节点上
  2. HRegionServer的作用是用于管理HRegion。在官方文档中给定,一个HRegionServer最多允许管理1000个HRegion。HRegion的大小默认是10G,可以在1~20G之间进行调节
  3. HRegionServer由1到多个WAL、1个BlockCache以及0到多个HRegion来构成

2.6、WAL(HLog)- Write Ahead Log

  1. Write Ahead Log - 发生在写之前日志。在新的版本中,也成为HLog
  2. 当HRegionServer接收写请求的时候,会先将这个写请求记录到WAL中。如果记录成功,再将数据更新到对应的memStore中。数据记录到memStore中之后,会给客户端返回一个ACK表示写入成功
  3. WAL的作用保证数据不会产生丢失
  4. 当WAL达到一定大小(默认是1G)的时候,WAL会产生滚动生成一个OLD_WAL,同时会产生一个新的WAL。新的写操作会记录到这个新生成的WAL中,OLD_WAL会在某一个时刻被清理掉
  5. 在HBase0.94版本之前,WAL采用的是串行写机制;从HBase0.94版本开始,引入了NIO中的Channel机制,使得WAL允许进行并行写机制

2.7、BlockCache - 数据块缓存

  1. 本质上是一个读缓存,维系在内存中,默认大小是128M
  2. BlockCache在进行缓存的时候,会采用"局部性原理" - 所谓的"局部性原理",根据时间或者空间规律来进行合理的猜测以提高猜测的命中率
    a. 时间局部性:在HBase中,当一条数据被读取之后,HBase会认为这条数据再次被读取的概率要高于其他没有被读取过的数据,那么HBase会将这条数据放到缓存中
    b. 空间局部性:在HBase中,当一条数据被读取之后,HBase会认为与这条数据相邻的数据被读取的概率要高于其他不相邻的数据,那么HBase就会将与这条数据相邻的数据也放到缓存中
  3. BlockCache还采用了LRU(Least Recently Used - 最近最少使用)策略,在所有数据中,最长时间没有被用到的数据或者是使用次数最少的数据会被清理掉

2.8、HRegion

  1. HRegion可以看作是对数据的管理权,包含了1到多个HStore,HStore的数量由列族的数量来决定
  2. 每一个HStore中会包含1个memStore以及0到多个HFile/StoreFile
    。3. memStore本质上是一个写缓存,维系在内存中,大小默认是128M
    》4. 数据会先写到memStore中,当memStore达到一定条件之后,会进行冲刷,冲刷出一个HFile。每次冲刷都会产生一个新的HFile。HFile最终会落地到DataNode上以Block形式存储
  3. memStore的冲刷条件
    a. 当memStore被用满之后,会将这个memStore冲刷,产生HFile
    b. 当WAL产生滚动的时候,会将这个HRegionServer上的所有的memStore进行冲刷,产生多个HFile
    c. 当一台服务器上的所有的memStore所占内存之和/物理内存>0.35,那么会冲刷较大的几个memStore,直到不超过0.35为止
  4. 在实际生产过程中,上述的第三个冲刷条件更容易满足,也会导致HBase会冲刷出大量的小文件

2.9、Compact机制 - 合并机制

  1. Compact机制是HBase提供的一套用于对数据进行合并的机制,包含2种方式:minor compact和major compact
  2. minor compact:初代合并。在合并的时候,会将相邻的小的HFile合并成一个大的HFile,原来就是较大的HFile不参与合并。因此,合并完成之后,依然存在多个HFile
  3. major compact:主合并。在合并的时候,无论文件大小,会将所有的HFile合并成一个HFile。因此,合并完成之后,只会存在1个HFile
  4. 相对而言,minor compact的合并效率会高一些。如果不指定,则HBase中默认采用的也是初代合并
  5. major compact在合并的时候,相对而言更加的耗费资源,因此实际开发中,一般会将major compact放在相对空闲的时候(例如凌晨)进行
  6. 在合并的时候,会舍弃掉被标记为删除的数据或者是过时的数据

三、流程

3.1、写流程

  1. 当HRegionServer接收到写操作的时候,会先将这个写操作记录到WAL中,然后将数据更新到memStore中
  2. 数据在memStore中进行排序,按照行键字典序->列族字典序->列字典序->时间戳倒序来进行排序
  3. 当memStore达到冲刷条件的时候,会冲刷产生一个新的HFile。HFile最终会落地到HDFS上。因为数据在memStore中是有序的,所以冲刷出来的单个HFile中的数据是有序的,但是所有的HFile之间是局部有序整体无序的
  4. DataBlock:数据块。是用于存储数据的
    a. 一个HFile中可以包含多个DataBlock
    b. 因为HFile中的数据是有序的,所以DataBlock之间的数据是不交叉的,每一个DataBlock都会有自己的起始行键和结束行键
    c. DataBlock默认大小是64KB。小的DataBlock利于查询(get),大的DataBlock利于遍历(scan)
    d. BlockCache在进行空间局部性缓存的时候是以DataBlock为单位来进行缓存。即如果DataBlock中有一条数据被读取,那么整个DataBlock就会放到BlockCahce中
    e. 每一个DataBlock中包含1个Magic(魔数)以及多个KeyValue
  5. 在HFile的后续版本中,引入了BloomFilter(布过滤器)

3.2、读流程

  1. 当HRegionServer接收到读操作的时候,会先试图从BlockCache中读取数据
  2. 如果没有从BlockCache中读取到数据,那么试图从memStore中来读取数据
  3. 如果没有从memStore中读取到数据,那么试图从HFile中来读取数据
  4. 在读取HFile的时候,可以先根据行键范围进行筛选,先筛选掉不符合行键范围的HFile。之后再利用BloomFilter再次进行筛选。筛选完成之后,被筛掉的HFile中一定没有要找的数据,但是不代表剩下的文件中有要找的数据

四、Hbase 下载地址:

百度云盘链接:https://pan.baidu.com/s/1DIOaB_u5ZMr8m7lU-nKztA(提取码:546c
(如果提示过期,请评论再次更新)


• 由 ChiKong_Tam 写于 2021 年 1 月 29 日

猜你喜欢

转载自blog.csdn.net/qq_42209354/article/details/113172661