hbase的高可用
什么是hbase的高可用?指的是:让master节点能够有多个,当节点宕机后,能够有备份的节点顶的上来,此时认为master形成了高可用状态
如何实现hbase的主节点的高可用呢?环境为VMware 三台虚拟机
- 在hbase的conf目录下,创建backup-master文件,并添加如下内容:
node1中执行:
cd /export/server/hbase-2.1.0/conf/
vim backup-masters
内容如下:
node2.itcast.cn
node3.itcast.cn
- 将这个文件发送到node2和node3中
node1执行:
cd /export/server/hbase-2.1.0/conf/
scp backup-masters node2:$PWD
scp backup-masters node3:$PWD
- 启动hbase:
3.1) 先启动zookeeper
3.2) 接着启动 hadoop集群
3.3) 启动hbase
- 启动后, 可以将主节点进行宕机, 然后检测其他的节点是否升级为主节点操作, 如果可以, 说明高可用配置成功了
思考: 为什么第一次启动 每一次都node1成为主节点呢?
在启动过程中, node1往往是第一个先启动, 导致具有抢先权限, 导致node1往往是主节点
hbase的集群架构
Hbase的原理
hbase的读取流程
读取数据的流程:(注:防手机端看不清图片文字)
1. 客户端发起读取数据的请求,首先会连接zookeeper
2. 从zookeeper中获取hbase:meta表 被那个regionServer所管理着
(hbase:meta表Lhbase的元数据表,此表中主要适用于存储用户创建的表元数据信息,
包含有哪些表,每个表有哪些region,每个region被那些regionServer所管理,以及每个
region详细的信息数据。 如果执行get操作,只能返回一个regionServer地址,如果执行
scan操作,将这个表对应的所有regionServer地址返回)
3. 连接meta表对应regionServer,从meta表中获取当前读取的这个表对应的region被哪个regionServer所管理
4. 连接对应的regionServer,开始读取数据
5. 首先现行memstore--》blockCache(块缓存)--》storeFile --》大Hfile
注:如果执行scan扫描操作,块缓则没有实际意义
数据的写入流程
写入数据的流程:(注:防手机端看不清图片文字)
1. 客户端发起写入数据的请求,首先会连接zookeeper
2. 从zookeeper中获取hbase:meta表被哪个regionServer所管理着
3. 连接meta表对应的regionServer,从meta表获取当前要写入的表对应的region已经regionServer地址是什么
(只能返回一个regionServer地址)
4. 连接对应要写入数据的regionServer,开始进行数据的写入操作,将数据会写入到这个regionServer的Hlog和
对应的memStore(数据量大的话会有多个)中,当这两个位置都写入成功后,客户端就会认为数据写入完成
-------以上操作是hbade客户端写入流程------------
异步流程:
5. 随着客户端不断的写入数据,memStore中数据会越来越多,当memStore中到达一定阈值(128M / 1h)后,
就会触发flush刷新机制,将memStore的数据最终写入到HDFS上形成一个StoreFile文件
6. 随着不断的flush刷新,在HDFS上storeFile会越来越多,当storeFile达到一定阈值(3个及以上)后,就会触发
compact合并压缩的机制,将多个storeFile最终合并为一个大的HFile
7. 随着不断的合并,大的Hfile会越来越大,当这个Hfile达到一定的阈值(最终10GB)后,就会触发split切割机制,
将这个大的Hfile进行一分为二的操作,同时管理的region也会被一分为二,形成两个新的Hfile和两个新的region,
一个region管理一个Hfile,当分裂完成后,原有的就region和Hfile将下线并被删除
Hbase的原理及其相关的工作机制
Hbase的flush刷新机制(溢写合并机制)
flush刷新机制:
当客户端不断想memStore写入数据,memStore中数据达到一定的阈值后,就会触发这个flush的刷新机制,
最终将数据刷新到HDFS上,形成一个storeFile文件
阈值:128M / 1h
flush内部的流程机制:
1. 当memStore达到阈值后,首先会将当前这个memStore空间关闭,然后开启一个新的memStore接着进行写入操作
2. 将这个已经关闭的空间的数据(segment片段)防止到一个pipeLine管道中,pipeLine管道是一个只读管道,
等待进行flush到HDFS操作
hbase2.X以上架构:
存储在pipeLine中数据会尽可能晚的舒心到HDFS上,让更多的数据能够存储在pipeLine管道中,
以提升查询的效率,减少后续的IO读写操作
当整个region内存空间达到阈值,此时一次性将pipeLine管道中的全部数据写入到HDFS上,
在写入过程中,会将多个片段数据进行内存合并操作,将其合并为一个storeFile写入到HDFS上
hbae1.X架构
一旦数据达到pipeLine管道后,flush子线程检测到pipeLine管道中有数据,
直接将其flush到磁盘上形成一个storeFIle文件
注意:虽然说在hbase2.x提供了内存合并的方案, 但是这种方案默认情况下是没有开启的,
也就意味着在默认情况和hbase1.x是一样的
如何修改默认触发的阈值: hbase-site.xml
如何配置内存合并的操作
在内存合并的时候,主要可以采取三种合并方案:
basic(基础型):
在进行内存合并的时候,并不关心内存中数据是否有出现过期版本或者已经标记删除数据,
直接进行合并即可。
此种操作合并效率比较高
eager(饥渴型):
在进行内存合并的时候,观察数据是否已经发生过期,或者这条数据是否已经出现被打伤删除标记信息,
如果发现有,在合并的时候,直接将这些过滤掉,可以保证合并的文件更小,
而且当前这个文件也没有过期的数据了。
适用于:数据经常过期的场景,比如购物车
此种操作,效率比较低
adaptive(适应型):
在进行合并的时候,会校验整个数据集过期的数据是否比较多,如果比较多,自动采用饥渴型解决,
如果发现没有太多过期数据,采用基础型方案
在实际生产中,一般使用 basic 或者 eager 根据实际数据的特点选择对应的方案
配置方式:
- 全局配置: hbase-site.xml中 所有的表都会按照这种方式进行内存合并
- 默认值: none (不开启)
- 针对某个表来设置:
- 默认值: none
HBase的storeFile的合并机制
compact合并机制:
当flush不断的被触发, 在HDFS上就会形成越来越多的storeFile文件, 当storeFile达到一定的阈值后,
就会触发compact合并压缩的机制操作
minor: 将多个小的storeFile合并为一个较大的Hfile过程
触发阈值: 达到3个及以上 或者在启动Hbase的时候进行检测
注意:
minor在合并过程中, 仅在数据进行排序操作, 并不关心数据是否存在过期以及已经打上删除标记
minor在执行合并效率比较高
在合并的时候, 也是需要将这些数据边读取到内存, 然后边通过追加的方式合并到HDFS上
major: 将这个较大的Hfile合并之前大的Hfile进行合并成最终一个大的Hfile过程
触发阈值: 7天 或者在启动Hbase的时候检测
注意:
major在进行合并操作的时候, 会将之前较大的Hfile和当前的这个大的Hfile进行最终合并为一个Hfile操作,
此时由于可以拿到region下所有的数据, 所以在合并过程中, 如果发现有些版本数据已经过期, 或者说已经被标记删除了,
在合并的过程中将处理清洗掉, 保证大的Hfile中不存在过期或者标记删除的数据
由于此操作需要处理的数据量比较庞大, 整个执行对当前regionServer影响比较高, 一般建议关闭自动触发,
改为手动(在不是很繁忙的时候触发执行即可)
hbase和HDFS存在一些矛盾关系: hdfs不支持随机读写, 但是基于HDFS的hbase却支持高效的随机读写
1) 在进行写入 修改 删除操作的时候, 对于hbase都是一种添加数据的操作, 而且都是将数据添加到内存中
(从而提升写入数据性能)
2) 那么一旦修改后, 或者删除后, 之前的版本的数据可能就会过期, 这些过期的时候就要分为二个阶段来处理:
第一个阶段: 内存合并阶段 此阶段只能将当前在内存中过期数据清除掉
第二个阶段: major合并阶段 此阶段将会进行完整的清除工作
3) 所有在写入到HDFS的数据都是采用追加的方式进行写入操作
4) hbase为了提供读取数据的性能, 专门定义一种hbase独有的文件格式: HFile 此文件中存储大量的索引信息数据,
从而保证能够更快检索数据, 同时每个region定义存储数据范围 , 能够快速找到对应的文件
Hbase的split机制(region分裂)
默认情况下, 当一个region所管理的Hfile文件达到10GB的时候, 就会触发split分裂机制, 此时会将region进行一分为二,
形成两个新的region, 而region对应管理Hfile也会进行一分为二,形成两个新的Hfile,
这个两个hfile与两个新的region一一对应管理即可, 一旦分裂完成后, 旧的region和对应数据就会下线并删除
思考: 默认情况下, 创建一个表只有一个region, 一个region最终也只能被一个regionServer所管理,
当我们对这个表进行大量的读写请求操作的时候, 所有的请求将全部打向到这一个regionServer上 ,
此时对这个regionServer会产生什么影响呢?
答:
会导致这个regionServer整个读写的效率的下降, 甚至出现宕机风险
如何解决呢?
如果可以让这个表尽早的进行分裂为多个region, 一旦一个表有个多个region, 不同region可以被不同的regionServer所管理,
此时在执行读写请求操作的时候, 相当于有多个regionServer一同来承担读写请求, 从而减轻了单台节点的压力
但是 如果默认是10GB的化, 那么从 0~10GB操作貌似有点太长了, 所以这样也是不合适的, hbase为了解决这个问题,
专门提供了一个算法公式, 来计算何时进行分裂操作:
Min(R^2 * "hbase.hregion.memstore.flush.size", "hbase.hregion.max.filesize")
说明: R 表示一个表的region数量
基于以上公式, 可以看出分裂的时间:
第一次: 当region达到128M的时候, 就会触发一次的region的分裂操作
第二次: 当region达到512M的时候, 救护粗发一次region的分裂操作
第三次: . .....
依次类推,知道region的数量达到9个的时候, 此时min计算后的值就是10GB 在以后即使按照10GB 进行分裂
region server的上线和下线流程:
master的上线和下线
当master称为active节点后, 如何进行region的管理分配操作呢?
1) 当master启动后, 首先会先和各个从节点进行通信, 让各个从节点汇报自己的目前所管理的region信息
2) master会再去读取meta表, 从中获取到所有的region信息
3) 根据meta表中region信息 以及各个 从节点汇报上来region 进行比对, 查找出那些region还没有分配,
或者说那个从节点管理的region数量过多
4) 将那些没有分配的region进行重新分配给那些管理region数量比较少的从节点,
同时在这个过程需要保证各个从节点管理region数量的负载均衡(底层还需要一个表中多个region被不同regionServer所管理)
在整个hbase启动过程中, compact合并机制在此时也会进行校验, 首先会先校验是否可以触发minor,
如果可以 直接触发执行, 执行后, 接着在判断是否可以进行major操作, 如果满足阈值, 也会触发执行,
因为这个时候执行操作是最佳执行时间
注意: 由于master只对表和region的元数据进行管理操作, 并不会参与表数据的IO工作,
所以说短暂master下线并不会影响整个hbase的集群(大部分的操作都是表数据读写)
当master宕机后, 主要会影响什么呢? 主要会影响需要修改元数据的操作
比如: 创建表 修改表 删除表 清空表 , 执行负载均衡, 分配region的操作
唯独region分裂是可以正常执行的, 因为region的分裂master并不会参与
HBase的Bulk Load 批量加载操作
思考:
当我们需要将一大批数据往Hbase的表中进行添加的时候, 一般采用的方案通过JAVA API 一条一条的将数据写入到HBase中, 整个写入操作, 先将数据写入到memStore中, 然后在flush到HDFS上形成storeFile, 然后storeFile在合并为一个大的Hfile, 最后这个大的Hfile进行分裂形成多个region, 依次不断的处理即可
在此流程中, 如果数据量比较大, 写入操作会占用时间也会比较长, 同时由于写入操作一直在高效的写入, 此时对网络对服务器中资源都会进行大量的占用, 主要是带宽, 当写入操作将网络带宽占用过大, 就会导致读取数据操作性能会严重下降,甚至出现无法读取数据.
对于服务器由于不断传输数据, 可能服务器也会无法承载长时间高占用处理, 也会宕机
思考: 如何解决这个问题呢?
发现写入过程中, 数据最终就是落在HDFS上, 形成了一个Hfile文件格式数据, 那么依然如此, 那么是否可以将这一大批数据直接转换为对应Hfile格式数据,然后将这个数据直接放置对应表的对应HDFS的目录下
而这种解决思路, 就是BulkLoad方案
第一步: 将数据转换为HFile文件格式数据: MapReducer
第二步: 将这个HFile文件格式数据加载到对应的表中
适用于:
需要一次性写入一大批数据到HBase的场景