HBase学习

一.概述
1.Hbase是基于Hadoop的,分布式、可扩展的、非关系型数据库
2.如果需要大量数据进行随机且实时的读写,那么可以考虑使用HBase
3.HBase能够管理非常大的表:billions of rows * millions of columns
4.HBase是仿照Google的Big Table来进行实现的,因此,HBase和Bigtable原理几乎一致,只是实现语言不同,HBase用的java,BigTable用的C
5.Hbase提供了2个大版本,并且2个版本都在同时更新。其中,Hadoop3.1.3版本支持的是HBase2.2.x及以上的版本
6.HBase作为非关系数据库,不支持标准的sql语法,提供了一套全新的命令
7.HBase能够存储稀疏类型的数据,也因此HBase能够存储结构化(数据本身有结构,经过解析之后,能过用传统的数据库中的一个或者几个表来存储)和半结构化数据(数据本省有结构,但是解析之后无法用传统的数据库的表来存储:比如json,存入时有的字段有,有的字段没有,后面还会新增一些列,传统数据库就无法新增,HBase可以动态新增列)
8.HBase本身作为数据库,提供了完整的增删改查的功能。HBase基于HDFS来进行存储,HDFS特点是允许一次写入多次读取,不允许修改而允许追加写入,但是HBase提供了“改”功能,HBase如何是实现“改”功能的?-HBase实际上没有去修改写入的数据,而是在文件末尾曲追加数据。HBase会对写入的每条数据自动添加一个时间戳,当用户获取数据的时候,HBase自动返回最新的数据,那么从用户角度看,就是发生了数据的修改
9.在HBase中,数据数据的每一个版本称为时间戳
10.如果要锁定唯一的一条数据,那么需要通过行键+列族+列+时间戳这四个维度来锁定,这种结构称之为是一个Cell(单元格)
11.HBase在创建表的时候,如果不指定,那么只对外提供一个版本的数据
12.如果建好表之后再修改可以获取的版本,那么已经添加的数据不起作用
13.即使表允许对外获取多个版本的数据,在获取的时候如果不指定,依然只获得一个版本的数据

二.基本概念
1.RowKey:行键
①在HBase中没有主键,取而代之的是行键
②不同于传统的关系型数据库,在HBase中,定义表的时候不需要按定行键列,而是在添加数据的时候手动添加行键
③HBase默认会对行健进行排序,按照字典序排序
2.Column Family:列族/列簇
①在HBase中,没有表关联的概念,取而代之的是用列族来进行设计
②在HBase中,一个表中至少要包含一个列族,可以包含多个列族,理论上不限制列族的数量
③在HBase中强调列族,但不强调列 - 在定义表的时候必须定义列族,但是列可以动态增删,一个列族中可以包含0到多个列
3.namespace:名称空间
①在HBase中没有database的概念,取而代之的是namespace
②在HBase的启动的时候,自带了两个空间:default和hbase。hbase下放的是HBase的基本信息;在建表的时候如果不指定,则表默认是放在default空间下

三.基本架构
1.HRegion
①在HBase中,会将一个表从行健的方向上进行切分,切分成一个或者多个HRegion
②切分之后,每一个HRegion交给某一个HRegionServer来进行管理
③一个表至少会包含一个HRegion,可以包含多个HRegion
④在HBase中,行健是有序的,因此从行健方向上来进行的切分,所以HRegion之间的数据是不会交叉的
⑤因为HRegionServer会交给HRegionServer来管理,并且HRegion之间的数据相互不交叉,所以保证请求不会集中于某一个节点上而是会分散到不同的节点上
⑥随着运行时间的推移,HRegion管理的数据会不断增多,达到指定条件的时候,会自动进行分裂
⑦每一个HRegion包含一个多个HStore,HStore的数量由列族的数量来决定的
⑧每一个HStore都会包含1个memStore以及包含0到多个StoreFile/HFile
在这里插入图片描述
2.Zookeeper的作用
①在HBase中,Zookeeper充当了注册中心
②当HBase启动之后,会自动的在Zookeeper上来注册一个HBase节点
③当HMaster启动之后,会自动的在Zookeeper上注册一个临时节点/hbase/master - 当Active HMaster宕机之后,这个临时节点就会消失,此时Zookeeper就会从Backup HMaster中选择最早注册的节点来切换为Active状态
④当Backup HMaster启动之后会自动的在Zookeeper的/hbase/backup-masters节点注册一个临时子节点
⑤当HRegionServer启动之后,也会自动的在Zookeeper的/hbase/rs节点下来注册子节点
在这里插入图片描述

3.HMaster
①在HBase中,允许用户在任意一台安装了HBase的节点上来启动HMaster,理论上不限制HMaster的数量
②HMaster的启动命令
hbase-demon.sh start master
③在HBase中,如果启动多个HMaster,那么HMaster之间就会分为Active和Backup两种状态
④如果多个HMaster,那么最先注册的就会成为Active状态,后注册到Zookeeper上的HMaster就会成为Backup状态
⑤当Active HMaster接受到请求之后,需要考虑数据同步给其他的Backup HMasters。
⑥因此在HBase中,虽然理论上不限制HMaster的个数,但是实际过程中,HMaster的个数一般不会超过3个:一个Active HMaster+2个Backup Master
⑦Active HMaster会实时监控Zookeeper上/hbase/back-masters下的节点变化以确定需要同步的节点是哪几个
⑧HMaster的作用
a.管理HRegonServer。需要注意的是,HMaster对HRegonServer的管理权限并不大,只能决定HRegion交由哪一个HRegionServer来进行管理
b.记录和存储元数据。HBase中的元数据包含namespace名、table名、column family名以及属性信息等。注意,在HBase中,列不是元数据,因为列可以动态增删,也就意味着凡是产生元数据的操作会经过HMaster,不产生元数据的操作不会经过HMaster。DDL(Data Defination Language,数据定义语言,例如create/drop等)以及namespace操作会产生元数据,DML(Data Manipulation Language,数据操作定义,例如put/get/scan/delete等)语言不会产生元数据

四.HBase的读写流程
1.当客户端要进行DML操作的时候,会首先发送请求道Zookeeper,请求获取hbase:meta表的位置,这个表中存储HBase的元数据
2.Zookeeper收到请求之后,会将hbase:meta表的位置返回给客户端。hbase:meta会由某一个HRegionServer管理
3.客户端收到hbase:meta表的位置之后,会请求对应的HRegionServer,来读取hbase:meta,这个表中获取到实际操作的HRegion所在的位置
4.客户端获取到HRegion的实际所在位置之后,会再次发送请求给对应的HRegionServer,来操作这个HRegion
5.注意问题
a.当客户端第一次请求Zookeeper之后,会自动缓存hbase:meta文件的位置,之后客户端的每次请求就可以不再访问Zookeeper
b.当客户端获取到HRegion的位置之后,也会自动缓存这个HRegion的位置,之后如果还操作这个HRegion,就可以直接访问
c.随着时间的推移,客户端缓存的位置就越来越多,此时效率就会越来越高,但是如果客户端发生宕机,那么此时会导致缓存崩溃,那么需要重新建立缓存
在这里插入图片描述
五.HRegionServer
1.在实际生产过程中,一般会考虑将HRegionServer和DataNode部署在相同的节点上,避免频繁的跨集群的请求
2.HRegionServer的作用是用于管理HRegion。官方文档中给定,每一个HRegionServer大概能够管理1000个HRegion。每一个HRegion默认能够最多管理10G数据
3.每一个HRegionServer包含三部分结构:1到多个WAL,一个BlockCache以及0到多个HRegion
在这里插入图片描述
①WAL(Write Ahead Log):发生写操作之前的日志
a.当HRegionServer接受到请求写之后,会先试图将请求记录到WAL中,之后再将数据更新到对应的memStore中
b.通过WAL这个机制,能够有效的保证数据不会产生丢失,但是因为WAL是落地在磁盘上的,因此会导致写入效率在一定程度上会降低。因此在实际过程中,如果容忍一定程度上的数据丢失的风险而提高写入写入效率,那么此时可以考虑关闭WAL机制
c.在Hbase0.94版本之前,WAK只能才用串行写机制;从HBase0.94版本开始,引入了NIO中的Channel机制,使得WAL支持使用并行写机制,从而保证效率能够提升
②blockCache:数据块缓存
a.BlockCache本质上是一个读缓存,维系在内存中,默认大小是128M
b.在HBase中,在读取数据的时候,会将读取到的数据放到BlockCache中,从而下次再次读取数据的时候,可以从BlockCache中获取,减少对HStore的读取
c.BlockCache在缓存的时候,还采用了”局部性“原理。所谓的”局部性“原理本质上就是一个猜测的过程,无非是利用时间或者空间条件来合理猜测以提高命中率
1) 时间局部性:在HBase中,如果一条数据被读取过,那么HBase会认为这条数据 被再次的概率要高于其他的没有被读取过的数据,那么此时HBase就会将这条数据放到缓存中 - 只要是读取过的数据就会放到
2)空间局部性:在HBase中,如果一条数据被读取过,那么HBase会认为与这条数据相邻的数据被读取的概率要高于其他的不相邻的数据,那么此时HBase就会将与这条数据相邻的数据也放到缓存中
d.随着时间的推移,BlockCache会被放满,那么此时BlockCache就会才用LRU(Least Recently Used,最近最少使用的数据就会被清理掉)策略
③HRegion:HBase分布式存储和管理的基本结构,但不是数据存储的最小单位
a.每一个HRegion会至少包含一个HStore,可以包含多个HStore,HStore的数量由列族的数量来决定
b.每一个HStore中会包含1个memStore以及0到多个HFile/StoreFile
c.memStore本质上是一个写缓存,维系在内存中,大小默认是128M,可以通过hbase.hregion.max.filesize属性来调节
d.当达到一定条件的时候,就会将memStore进行冲刷,冲刷产生HFile。HFile最终会以Block形式落地到DataNode上
e.memStore的冲刷条件
1)当memStore被用满之后,会自动的进行冲刷,产生一个HFile
2)当距离上一次冲刷达到指定的时间间隔之后(默认是1H - 360000ms,可以通过属性hbase.regionservers.optionalcacheflushinterval来修改,注意单位是毫秒)之后,也会自动的冲刷memStore产生HFile
3)当某一个HRegionServer上所有的memStore所占内存之后/实际物理内存>0.4,那么会冲刷当前HRegionServer上较大的几个memStore,直到这个值小于0.4为止
举例内存使用情况:
1个HRegionServer最多1000HRegion
1个HRegion最多nHStrore
1个HStore最多1个memStore
那么1HRegionServer最多1000nmemStore
考虑极端条件:在59min59秒之内,来了非常多的数据,每一个表中包含3个列族
1个HRegionServer有3000memStore
每一个memStore中的数据都不到128M
3000*128=384000M=375G
//除以0.9是可能电脑内存不可能全给memStore用,就算利用率为90%给memStore
375/0.4/0.9=1041G(一个memStore达到128M冲刷的服务器内存差不过1T,如果列族再多点就更不行了)
f.随着运行时间的推移,第三个条件更容易满足【上面(3)中】,此时冲刷产生大量的小文件

六.Compaction机制
1.在HBase中,提供了2种Compaction机制:minor compact和major compact
a.minor compact:初次合并。在合并的时候,会将当前HStore中相邻的几个小的HFile合并成一个大的HFile,原本就是HFile不参与合并,因此合并完成之后依然存在多个HFile
b.major compact:主要合并。在合并的时候,会将当前HStore中的所有的HFile进行合并,并因此合并完成之后只存在一个HFile
2.相对而言,minor compact合并效率更高一些,HBase中默认才用的合并机制也是minor compact。实际过程中,也会使用major compact,但是因为major compact的效率较低,需要对大量数据进行读写,因此一般是存放在相对空闲的时间来进行
3.需要注意的是,在major compact的时候,会自动清理掉被标记为删除的数据或者过时的数据

七.基本流程(写流程和读流程)
1.写流程
①当HRegionServer接收到写请求的时候,会先将这个请求记录到WAL中,记录成功之后会再将数据更新到memStore中
②数据在memStore中会进行排序,按照行健字典序->列族字典序->列字典序->时间戳倒序来进行排序
③当达到冲刷条件的时候,memStore会自动冲刷产生HFile。因为memStore中的数据已经排序,所以冲刷出来的单个HFile中的数据是有序的。所有的HFile之间是局部有序整体无序的
④HFile最终会以Block形式落地到HDFS的DataNode上
⑤HFile的v1版本的结构
在这里插入图片描述

a.DataBlock:数据块。用于存储数据
1)每一个HFile中包含1个到多个DataBlock,DataBlock是数据存储的基本结构/最小单元
2)因为HFile中的数据是有序的,所以切分出来的DataBlock之间的数据是不交叉的
3)每一DataBlock大小默认是64KB。小的DataBlock利于查询(get),大的DataBlock利于遍历(scan)
4)每一个DataBlock都是1个Magic(魔数)以及1到多个KeyValue来构成
Magic:魔数。本质上就是一个随机数,用于校验的
KeyValue:存储数据,没一个数据最终都会以键值对形式来进行存储
在这里插入图片描述

b.MetaBlock:元数据块。用于存储元数据的。注意,不是所有的HFile都包含这一部分,一般只有hbase:meta表对应的HFile会包含这一部分
c.FileInfo:文件信息。用于记录HFile大小、所属HStore等信息
d.DataIndex:数据索引,用于记录MetaBlock的索引
e.MetaIndex:元数据索引,用于记录MetaBlock的索引
f.Trailer:在文件末尾,占用固定的字节大小,用于记录fileInfo,DataIndex和MetaIndex在文件中的起始字节
⑥在HFile中,需要先读取文件末尾,通过Trailer来锁定DataIndex的位置,然后读取DataIndex,通过DataIndex来定位DataBlock的位置
⑦在HFile的v2版本中,引入BloomFilter(布隆过滤器)
在这里插入图片描述

2.读流程
①当HRegionServer结束到读请求的时候,会先考虑从BlockCache来获取数据
②如果BlockCache中没有数据,那么会试图从memStore中来获取
③如果memStore中也没有数据,那么会试图HFile中来获取。在读取HFile的时候,可以先根据行健范围进行筛选,筛选掉不符合范围的HFile,但是不代表剩余的HFile中一定有找的数据。筛选完成之后,如果开启了布隆过滤器,那么可以利用布隆过滤器再次筛选,被筛选掉的文件中一定没有要找的数据,但是不代表剩余的文件中有数据

八.设计原则
1.行键设计
a.行健在设计的时候要尽量的散列,列入可以考虑使用哈希、加密算法等使结果散列,这样能保证请求不会集中于一个节点上
b.行键设计最好有意义,如果行键真的完全随机,会增加查询难度,例如订单的行健可以设计为220510bj025分别代表(年)(月)(日)(省)(随机数),那么某天的数据就会全部集中在HRegionServer中,增加某台服务器的压力,可以设计把随机数放前面为520jb015012倒序就可以均匀分布在不同的HRegionServer了
c.行键在使用的时候要保证唯一
2.列族设计
a.在HBase中虽然理论上不限制列族的数量,但是实际过程中,一个表中的列族一般不会超过3个
b.在设计列族的时候,要尽量将具有相同特性的数据或者经常一起使用的数据放在一个列族中,尽量避免跨列族查询

九.优化
1.调节DataBlock的大小。小的DataBlock利于查询,大的DataBlock利于遍历。在建表的时候,就可以根据当前场景来确定DataBlock的大小。例如:
create ‘person’ ,{NAME => ‘basic’ , BLOCKSIZE = ‘32768’}
2.关闭BlockCache。如果HBase的遍历偏多,此时没有必要将数据放到读缓存中,此时可以考虑关闭BlockCache(因为你刚遍历很多放到内存之后,满了通过LRU删除,又往返放到内存又删除)
create ‘person’ ,{NAME => ‘basic’ , BLOCKCACHE = ‘false’}
alter ‘person’ ,{NAME => ‘basic’ , BLOCKCACHE = ‘false’}
3.更该BloomFilter的级别。BloomFilter支持三种方式:NONE,ROW以及ROWCOL。NONE不使用BloomFilter,如果节点硬件性能一般,可以考虑关闭BloomFilter;ROW对行键进行过滤,BloomFilter默认就是这个值;ROWCOL表示对行键、列族和列同时过滤,如果节点硬件性能较好,可以使用这个
4.开启数据压缩机制。如果HBase占用了大量的HDFS空间,导致HDFS空间不够,那么可以考虑对HBase的数据进行压缩。通过COMPRESSION属性来修改,只是NOME,LZO,SNAPPY和GZIP.其中NONE表示不压缩,HBase默认不对数据压缩
5.在查询的时候可以考虑显式地指定列,此时可以减少在网路中传输的数据量。例如
get ‘person’ , ‘p1’(网络传输要拿出他所有的列族和列)
get ‘person’ , ‘p1’ , ‘basic’(网络传输要拿出basic列族下所有和列)
get ‘person’ , ‘p1’ , ‘basic:name’(网络传输要拿出basic列族下name列)
6.如果数据量较大,那么在读写的时候可以考虑使用批量读写(代码用先放入集合再写入HBase中)
7.关闭WAL。如果想要提高写入效率,又能够容忍一定的数据丢失,那么可以考虑关闭WAL
8.预创建HRegion。当HRegion管理的数据比较多(默认是10G)的时候,会进行分裂。HRegion分裂之后可能会发生管理权的转移,此时HRegion分裂和转移都要花费时间。因此在能够预估数据来量的前提下,可以考虑在建表的时候就构建多个HRegion。例如
hbase org.apache.hadoop.hbase.util.RegionSpliter person HexStringSplit -c 15 -f base
9.调整Zookeeper的有效Session时长。默认情况下,HMaster和Zookeeper之间通过心跳来保证联系,心跳间隔时间默认是180s即3min,也就意味着HMaster每隔3min会给Zookeeper发送一次心跳。如果HMaster产生了故障,那么可能Zookeeper需要在3min之后才能发现故障。在业务高峰期,HBase有3min不能使用,此时会造成大量的损失。因此需要调节这个时长。通过属性zookeeper.session.timeout来调节,单位是秒,放在hbase-site.xml中

十.Hive和HBase的比较
1.Hive本质上是一个用于进行数据仓库管理的工具,在实际过程中经常用于对数据进行分析和清洗,提供了相对标准的SQL结构,底层会将SQL转化为MapReduce来执行,因此Hive的效率相对较低,更适合于离线开发的场景。Hive一般针对历史数据进行分析,一般只提供增加和查询的能力,一般不会提供修改和删除的功能
2.HBase本质上是一个分关系型数据库,在实际开发过程中,用于存储数据。因为HBase的读写效率较高,吞吐量较大,因此一般使用HBase来存储实时的数据,最终数据会落地到HDFS上。HBase作为数据库,提供了完整的增删改查的能力,但是相对而言,HBase的事务能力较弱。HBase不支持SQL,提供了一套完整的命令
3.总结:Hive强调的是分析能力,但是HBase强调的是存储能力,相同的地方在于两者都是利用HDFS来存储数据

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值