IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 三、HBase RegionServer介绍 HLog、MemStore、BlockCache -> 正文阅读

[大数据]三、HBase RegionServer介绍 HLog、MemStore、BlockCache

HBase RegionServer介绍

HBase客户端

Hbase客户端读写数据时,都要先根据hbase:meta表(元数据表)确定数据在哪个Region上,然后再根据Region的RegionServer信息,去对应的RegionServer上读取数据。hbase:meta表,专门用来存放整个集群所有的Region信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gFfkwMiJ-1652790898837)(三、HBase RegionServer介绍.assets/image-20220424120640651.png)]

HBase保证hbase:meta表始终只有一个Region,这是为了确保meta表多次操作的原子性,因为HBase本质上只支持Region级别的事务。

hbase:meta表只有一个Region,如果所有的流量都先请求hbase:meta表找到Region,再请求Region所在的RegionServer,那么hbase:meta表的将承载巨大的压力,这个Region将马上成为热点Region,且根本无法承担数千万的流量。

HBase客户端缓存hbase:meta表的Region信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-REB6wQzB-1652790898838)(三、HBase RegionServer介绍.assets/image-20220426175338828.png)]

HBase客户端有一个叫做MetaCache的缓存,在调用HBase API时,客户端会先去MetaCache中找到业务rowkey所在的Region,此时可能有三种情况:

  • Region信息为空,MetaCache没有这个region的缓存数据;首先通过zookeeper获取hbase:meta表所在的RegionServer,然后在hbase:meta表找到业务rowkey所在的region,接着缓存信息到MetaCache;
  • Region信息不为空,但是请求对应RegionServer后发现Region并不在这个RegionServer上,MetaCache信息过期;通过hbase:meta表找到正确的Region并缓存;
  • Region信息不为空,但是请求对应RegionServer后发现Region是正确的
HBase常见的超时参数
  • hbase.rpc.timeout:表示单次RPC请求的超时时间,一旦单次RPC超过该时间,上层将收到TimeoutException。默认为60000ms。

  • hbase.client.retries.number:表示调用API时最多容许发生多少次RPC重试操作。默认为35次。

  • hbase.client.pause:表示连续两次RPC重试之间的休眠时间,默认为100ms。注意,HBase的重试休眠时间是按照随机退避算法计算的,若hbase.client.pause=100,则第一次RPC重试前将休眠100ms左右,第二次RPC重试前将休眠200ms左右,第三次RPC重试前将休眠300ms左右,第四次重试前将休眠500ms左右,第五次重试前将休眠1000ms左右,第六次重试则将休眠2000ms左右……也就是重试次数越多,则休眠的时间会越长。因此,若按照默认的hbase.client.retries.number=35,则可能长期卡在休眠和重试两个步骤中。

  • hbase.client.operation.timeout:表示单次API的超时时间,默认值为1200000ms。注意,get/put/delete等表操作称为一次API操作,一次API可能会有多次RPC重试,这个operation.timeout限制的是API操作的总超时。

假设某业务要求单次HBase的读请求延迟不超过1s,那么该如何设置上述4个超时参数呢?

首先,hbase.client.operation.timeout应该设成1s。

其次,在SSD集群上,如果集群参数设置合适且集群服务正常,则基本可以保证p99延迟在100ms以内,因此hbase.rpc.timeout设成100ms。这里,hbase.client.pause用默认的100ms。

最后,在1s之内,第一次RPC耗时100ms,休眠100ms;第二次RPC耗时100ms,休眠200ms;第三次RPC耗时100ms,休眠300ms;第四次RPC耗时100ms,休眠500ms(不是完全线性递增的)。因此,在hbase.client.operation.timeout内,至少可执行4次RPC重试,实际中单次RPC耗时可能更短(因为有hbase.rpc.timeout保证了单次RPC最长耗时),所以hbase.client.retries.number可以稍微设大一点(保证在1s内有更多的重试,从而提高请求成功的概率),比如设成6次。

RegionServer

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ulu7IQN1-1652790898839)(三、HBase RegionServer介绍.assets/image-20220427200114815.png)]

一个RegionServer由一个(或多个)HLog、一个BlockCache以及多个Region组成。

HLog用来保证数据写入的可靠性;

BlockCache可以将数据块缓存在内存中以提升数据读取性能;

Region是HBase中数据表的一个数据分片,一个RegionServer上通常会负责多个Region的数据读写。

一个Region由多个Store组成,每个Store存放对应列簇的数据,比如一个表中有两个列簇,这个表的所有Region就都会包含两个Store。

每个Store包含一个MemStore和多个HFile,用户数据写入时会将对应列簇数据写入相应的MemStore,一旦写入数据的内存大小超过设定阈值,系统就会将MemStore中的数据落盘形成HFile文件。

HFile存放在HDFS上,是一种定制化格式的数据存储文件,方便用户进行数据读取。

HLog

HBase中系统故障恢复以及主从复制都基于HLog实现。默认情况下,所有写入操作(写入、更新以及删除)的数据都先以追加形式写入HLog,再写入MemStore。大多数情况下,HLog并不会被读取,但如果RegionServer在某些异常情况下发生宕机,此时已经写入MemStore中但尚未flush到磁盘的数据就会丢失,需要回放(replay)HLog补救丢失的数据。

HBase主从复制需要主集群将HLog日志发送给从集群,从集群在本地执行回放操作,完成集群之间的数据复制。

HLog生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cY2lRJiE-1652790898840)(三、HBase RegionServer介绍.assets/image-20220427201645090.png)]

HLog生命周期包含4个阶段:

  • HLog构建:HBase的任何写入(写入、更新、删除)操作都会先将记录追加写入到HLog文件中。
  • HLog滚动:HBase后台启动一个线程,每隔一段时间(由参数’hbase.regionserver.logroll.period’决定,默认1小时)进行日志滚动。日志滚动会新建一个新的日志文件,接收新的日志数据。
  • HLog失效:写入数据一旦从MemStore中落盘,对应的日志数据就会失效。为了方便处理,HBase中日志失效删除总是以文件为单位执行。一旦日志文件失效,就会从WALs文件夹移动到oldWALs文件夹。注意此时HLog并没有被系统删除。
  • HLog删除:Master后台会启动一个线程,每隔一段时间(参数’hbase.master.cleaner.interval’,默认1分钟)检查一次文件夹oldWALs下的所有失效日志文件,确认是否可以删除,确认可以删除之后执行删除操作。确认条件主要有两个:
    • 该HLog文件是否还在参与主从复制。
    • 该HLog文件是否已经在OldWALs目录中存在10分钟。设置日志文件的TTL(参数’hbase.master.logcleaner.ttl’,默认10分钟)
MemStore

HBase系统中一张表会被水平切分成多个Region,每个Region负责自己区域的数据读写请求。水平切分意味着每个Region会包含所有的列簇数据,HBase将不同列簇的数据存储在不同的Store中,每个Store由一个MemStore和一系列HFile组成。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xj8oq0PD-1652790898840)(三、HBase RegionServer介绍.assets/image-20220429094018565.png)]

HBase基于LSM树模型实现,所有的数据写入操作首先会顺序写入日志HLog,再写入MemStore,当MemStore中数据大小超过阈值之后将数据批量写入磁盘,生成一个新的HFile文件。

  • 将一次随机IO写入转换成一个顺序IO写入(HLog顺序写入)加上一次内存写入(MemStore写入),极大提升写入性能;

  • HFile中KeyValue数据是按照Key排序的,数据flush到HFile前已经在MemStore中排好序;

  • MemStore总是缓存着最近写入的数据。对于很多业务来说,最新写入的数据被读取的概率会更大;

  • MemStore采用跳跃表的数据结构,既保证高效的写入效率,又保证高效的多线程读取效率;

MemStore的GC问题

MemStore是一块缓存,可以称为写缓存。大内存java系统总会面临GC问题,MemStore本身会占用大量内存;一个RegionServer由多个Region构成,每个Region根据列簇的不同又包含多个MemStore,不同Region的数据写入对应的MemStore,因为共享内存,在JVM看来所有MemStore的数据都是混合在一起写入Heap的。

MSLAB内存管理方式

MemStore本地分配缓存(MemStore-Local Allocation Buffer,MSLAB)

MemStoreLAB会申请一个2M大小的Chunk数组,同时维护一个Chunk偏移量(初始为0);

数据data写入Chunk数组,Chunk偏移量移动data.length;

Chunk数组写满后,再申请一个新的Chunk数组;

MemStore Chunk Pool

MSLAB存在的问题,一个Chunk写满之后,系统会重新申请一个新的Chunk(新建Chunk对象会在JVM新生代申请新内存,如果申请比较频繁会导致JVM新生代Eden区满掉,触发YGC。)

MemStore Chunk Pool的核心思想:chunk循环利用,系统不需要申请新的Chunk

MSLAB相关配置

HBase中MSLAB功能默认是开启的,默认的ChunkSize是2M,可通过参数"hbase.hregion.memstore.mslab.chunksize"进行设置,建议保持默认值。

Chunk Pool功能默认是关闭的,需要配置参数"hbase.hregion.memstore.chunkpool.maxsize"为大于0的值才能开启,该值默认是0。"hbase.hregion.memstore.chunkpool.maxsize"取值为[0,1],表示整个MemStore分配给Chunk Pool的总大小为hbase.hregion.memstore.chunkpool.maxsize * Memstore Size。

"hbase.hregion.memstore.chunkpool.initialsize"取值为[0,1],表示初始化时申请多少个Chunk放到Pool里面,默认是0,表示初始化时不申请内存。

BlockCache

BlockCache是读缓存,客户端读取某个Block,首先会检查该Block是否存在于Block Cache,如果存在就直接加载出来,如果不存在则去HFile文件中加载,加载出来之后放到Block Cache中,后续同一请求或者邻近数据查找请求可以直接从内存中获取,以避免昂贵的IO操作。

Block是HBase中最小的数据读取单元,即数据从HFile中读取都是以Block为最小单元执行的。

三种BlockCache方案

LRUBlockCache是最早的实现方案,第二种方案是SlabCache,第三种方案是BucketCache;

三种方案的不同之处主要在于内存管理模式

  • LRUBlockCache是将所有数据都放入JVM Heap中,交给JVM进行管理;

  • 后两种方案采用的机制允许将部分数据存储在堆外。这种演变本质上是因为LRUBlockCache方案中JVM垃圾回收机制经常导致程序长时间暂停,而采用堆外内存对数据进行管理可以有效缓解系统长时间GC。

LRUBlockCache

缓存Block是将BlockKey和对应的Block放入HashMap中,查询缓存是根据BlockKey从HashMap中获取,

采用了LRU淘汰算法。

实现细节关注点

  • 缓存分层策略

    HBase采用了缓存分层设计,将整个BlockCache分为三个部分:single-access、multi-access和in-memory,分别占到整个BlockCache大小的25%、50%、25%,3个分层中的Block会分别执行LRU淘汰算法进行数据淘汰。

    在一次随机读中,一个Block从HDFS中加载出来之后首先放入single-access区,后续如果有多次请求访问到这个Block,就会将这个Block移到multi-access区。

    in-memory区表示数据可以常驻内存,一般用来存放访问频繁、量小的数据,比如元数据,用户可以在建表的时候设置列簇属性IN_MEMORY=true,设置之后该列簇的Block在从磁盘中加载出来之后会直接放入in-memory区。

    因为HBase系统元数据(hbase:meta,hbase:namespace等表)都存放在in-memory区,设置数据属性IN_MEMORY=true时需要非常谨慎,一定要确保此列簇数据量很小且访问频繁,否则可能会将hbase:meta等元数据挤出内存,严重影响所有业务性能。

  • LRUBlockCache方案优缺点

    LRUBlockCache方案使用JVM提供的HashMap管理缓存,简单有效。但随着数据从single-access区晋升到multi-access区或长时间停留在single-access区,对应的内存对象会从young区晋升到old区,晋升到old区的Block被淘汰后会变为内存垃圾。Full GC会将整个进程暂停,称为stop-the-world暂停(STW),因此长时间Full GC必然会极大影响业务的正常读写请求。

SlabCache

为了解决LRUBlockCache方案中因JVM垃圾回收导致的服务中断问题,SlabCache使用堆外内存存储,不再由JVM管理数据内存。

默认情况下,系统在初始化的时候会分配两个缓存区,分别占整个BlockCache大小的80%和20%,每个缓存区分别存储固定大小的Block,其中前者主要存储小于等于64K的Block,后者存储小于等于128K的Block。如果一个Block太大就会导致两个区都无法缓存。

采用了LRU淘汰算法,和LRUBlockCache不同的是,将该内存空间标记为空闲,后续可以复用。

不同表不同列簇设置的BlockSize都可能不同,SlabCache Size无法确定;

DoubleBlockCache:SlabCache和LRUBlockCache搭配使用。在一次随机读中,一个Block从HDFS中加载出来之后会在两个Cache中分别存储一份。缓存读时首先在LRUBlockCache中查找,如果Cache Miss再在SlabCache中查找,此时如果命中,则将该Block放入LRUBlockCache中。

DoubleBlockCache方案弊端:SlabCache中固定大小内存设置会导致实际内存使用率比较低,而且使用LRUBlockCache缓存Block会因为JVM GC产生大量内存碎片。

BucketCache

BucketCache通过不同配置方式可以工作在三种模式下:heap,offheap和file。

  • heap模式表示Bucket是从JVM Heap中申请的;

  • offheap模式使用堆外内存存储;

  • file模式使用类似SSD的存储介质来缓存Data Block。

无论工作在哪种模式下,BucketCache都会申请许多(14种)带有固定大小标签的Bucket,如果某一种Bucket空间不足,系统会从其他Bucket空间借用内存使用,因此不会出现内存使用率低的情况。

CombinedBlock-Cache:BucketCache和LRUBlockCache搭配使用。一次随机读需要先在LRUBlockCache中查到对应的Index Block,然后再到BucketCache查找对应Data Block。

相比heap模式,offheap模式因为内存是操作系统分配,降低了因为内存碎片导致Full GC的风险。

内存分配时,相比offheap直接从操作系统分配内存,heap模式需要首先从操作系统分配内存再拷贝到JVM heap,因此更耗时;

读取缓存时,heap模式可以从JVM heap中直接读取,而offheap模式则需要首先从操作系统拷贝到JVM heap再读取,因此更费时。

相比heap模式,offheap模式因为内存是操作系统分配,降低了因为内存碎片导致Full GC的风险。

内存分配时,相比offheap直接从操作系统分配内存,heap模式需要首先从操作系统分配内存再拷贝到JVM heap,因此更耗时;

读取缓存时,heap模式可以从JVM heap中直接读取,而offheap模式则需要首先从操作系统拷贝到JVM heap再读取,因此更费时。

HFile
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-19 11:58:28  更:2022-05-19 11:58:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:07:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码