HBase上关于CMS、GC碎片、大缓存的一种解决方案:Bucket Cache
介绍BucketCache前,先对HBase的Cache做个介绍:
一.HBase在读取时,会以Block为单位进行cache,用来提升读的性能;
二.Block可以分类为DataBlock(默认大小64K,存储KV)、BloomBlock(默认大小128K,存储BloomFilter数据)、IndexBlock(默认大小128K,索引数据,用来加快Row所在DataBlock的定位)
三.对于一次随机读,Block的访问顺序为BloomBlock、IndexBlock、DataBlock,如果Region下面的StoreFile数目为2个,那么一次随机读至少访问2次BloomBlock+1次IndexBlock+1次DataBlock
四.我们通常将BloomBlock和IndexBlock统称为MetaBlock,MetaBlock线上系统中基本命中率都是100%
五.Block的cache命中率对HBase的读性能影响十分大,所以DataBlockEncoding将KV在内存中进行压缩,对于单行多列和Row相似的场景,可以提高内存使用率,增加读性能
六.HBase中管理缓存的Block的类为BlockCache,其实现目前主要是下面三种:
6.1 LruBlockCache,默认的BlockCache实现,也是目前使用的BlockCache,使用一个HashMap维护Block Key到Block的映射,采用严格的LRU算法来淘汰Block,初始化时会指定容量大小,当使用量达到85%的时候开始淘汰block至75%的比例。
优点:直接采用jvm提供的HashMap来管理Cache,简单可依赖;内存用多少占多少,JVM会帮你回收淘汰的BlOCK占用的内存
缺点:
1.一个Block从被缓存至被淘汰,基本就伴随着Heap中的位置从New区晋升到Old区
2.晋升在Old区的Block被淘汰后,最终由CMS进行垃圾回收,随之带来的是Heap碎片
3.因为碎片问题,随之而来的是GC时晋升失败的FullGC,我们的线上系统根据不同的业务特点,因为这个而发生FullGC的频率,有1天的,1周的,1月半年的都有。对于高频率的,
在运维上通过在半夜手工触发FullGC来缓解
4.如果缓存的速度比淘汰的速度快,很不幸,现在的代码有OOM的风险(这个可以修改下代码避免)
6.2 SlabCache,针对LruBlockCache的碎片问题一种解决方案,使用堆外内存,处于实验性质,真实测试后,我们定位为不可用。说下它的原理:它由多个SingleSizeCache组成(所谓SingleSizeCache,就是只缓存固定大小的block,其内部维护一个ByteBuffer List,每个ByteBuffer的空间都是一样的,比如64K的SingleSizeCache,ByteBuffer的空间都是64K,cache Block时把Block的内容复制到ByteBuffer中,所以block的大小必须小于等于64K才能被这个SingleSizeCache缓存;淘汰block的时候只需要将相应的ByteBuffer标记为
空闲,下次cache的时候对其上的内存直接进行覆盖就行了),cache Block的时候,选择一个小于且最接近的SingleSizeCache进行缓存,淘汰block亦此。由于SingleSize的局限性,其使用上和LruBlockCache搭配使用,叫做DoubleBlockCache,cache block的时候LruBlockCache和SlabCache都缓存一份,get block的时候顺序为LruBlockCache、SlabCache,如果只有SlabCache命中,那么再将block缓存到LruBlockCache中(本人觉得它的这个设计很费,你觉得呢)
优点:其思想:申请固定内存空间,Block的读写都在这片区域中进行
缺点:
1.cache block和 get block的时候,需要内存复制
2.SingleSizeCache的设计,导致内存使用率很低
3.与LruBlockCache搭配使用不合理,导致所有的block都会去LruBlockCache中逗留一下,结果是CMS和碎片都不能有所改善
6.3 BucketCache,可以看成是对SlabCache思想在实现上的一种改进及功能扩展,其优点是解决LruBlockCache的缺点及支持面向高性能读的大缓存空间.
1.何谓大缓存?缓存Block的存储介质不再仅仅依赖在内存上,而是可以选择为Fusion-io、SSD等高速磁盘,我们称之为二级缓存
2.何谓Bucket?我们将缓存空间划分为一个个的Bucket,每个Bucket都贴上一个size标签,将Block缓存在最接近且小于size的bucket中(和SingleSizeCache很相似)
3.怎么解决CMS 碎片问题?Block存储在Bucket中,而每个Bucket的物理存储是不变的,也就是说系统刚启动的时候,我们就申请了一堆Bucket内存空间,而这些内存空间是一直在Old区,block的Get/Cache动作只是对这片空间的访问/覆写,CMS/碎片自然大大减少
4.怎么使用?上面的描述指出BucketCache可以有两种用法:
4.1 与LruBlockCache搭配,作为主要的内存cache方案使用
4.2 作为二级缓存使用,将Block缓存在我们的高速盘(Fusion-IO)中
5.BucketCache中的Cache/Get Block逻辑?
简单地描述下:
CacheBlock的时候,将Block放在一个RAMMap和一个Queue中,然后WriterThread异步从Queue中remove Block写入到IOEngine(内存或高速盘)中,并将BlockKey及其位置、长度等信息记录在backingMap
GetBlock的时候,先访问RAMMap,然后访问backingMap获取block的位置及长度,从IOEngine读取数据
6.Block在IOEngine中的位置是怎么分配的?
我们将物理空间划分为一堆等大的Bucket,每一个Bucket有一个序号及一个size标签,于是Block所在bucket的序号及其在bucket中的offset与block在物理空间的offset就形成了一一对应。我们通过BucketAllocator为指定大小的Block寻找一个Bucket进行存放,于是就得到了其在物理空间上的位置。
上图描述了BucketAllocator对于Bucket的组织管理:
6.1 每个Bucket都有一个size标签,目前对于size的分类,是在启动时候就确定了,如默认的有(8+1)K、(16+1)K、(32+1)K、(40+1)K、(48+1)K、(56+1)K、(64+1)K、(96+1)K ... (512+1)K
6.2 相同size标签的Bucket由同一个BucketSizeInfo管理
6.3 Bucket的size标签可以动态调整,比如64K的block数目比较多,65K的bucket被用完了以后,其他size标签的完全空闲的bucket可以转换成为65K的bucket,但是至少保留一个该size的bucket
6.4 如果最大size的bucket为513K,那么超过这个大小的block无法存储,直接拒绝
6.5 如果某个size的bucket用完了,那么会依照LRU算法触发block淘汰
问题:
6.6.如果系统一开始都是某个size的block,突然变成另外个size的block(不能存在同个size的bucket中),根据6.5不是会不停地进行淘汰算法?
是的,但是由于淘汰是异步的,影响不大,而且随着淘汰进行,bucket的大小会逐渐向那个block size大小bucket转移,最终稳定
6.7 BucketAllocator中allocate block的流程?
6.8 BucketAllocator中free block的流程?
6.9 第一种使用的测试结果
6.10 第二种使用的测试结果
6.11 更多细节,尽在代码中
https://issues.apache.org/jira/browse/HBASE-7404
HBase上关于CMS、GC碎片、大缓存的一种解决方案:Bucket Cache相关推荐
- B/S上传大文件的三种解决方案
总结一下大文件分片上传和断点续传的问题.因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况.http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件 ...
- SpringCloud上传大文件的三种解决方案
总结一下大文件分片上传和断点续传的问题.因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况.http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件 ...
- Windows:系统环境变量配置提示系统环境变量太大的问题三种解决方案亲测可用
系统环境变量配置 解决方案1: 解决方案2: 解决方案3: 解决方案1: 1.在系统环境变量中新建路径"path1" 2.在系统环境原来的path下新建路径包含上面的路径" ...
- 记录 | Latex 双栏排版插入图片后图片太大的问题 一种解决方案
问题描述 使用某会议的latex模板(双栏)完成论文时,出现了插入图片特别大.无法调整大小的问题: latex代码 \documentclass[conference,a4paper]{XXX}... ...
- HBase之CMS GC调优
HBase发展到现在,各种优化从未停止,GC优化更是重中之重,比如0.94版本提出的MemStoreLAB,MemStore Chunk Pool策略对写缓存MemStore进行优化开始,到0.96版 ...
- 史上最全,100+大数据开源处理工具汇总
本文除了一些常用的大数据工具,还总结汇总了其他大数据工具,几乎是最全的大数据工具的总结. 如果你想入门大数据,可以对他们进行简单的了解. 如果你想学习自己熟悉意外的大数据工具,可以看这篇文章. 如果你 ...
- Java中 9 种常见的 CMS GC 问题分析与解决
目录 Java中 9 种常见的 CMS GC 问题分析与解决 1. GC 1.1 引言 1.2 概览 2. GC 基础 2.1 基础概念 2.2 JVM 内存划分 2.3 分配对象 2.4 收集对象 ...
- 美团技术总结:Java中9种常见的CMS GC问题分析与解决
1. 写在前面 | 本文主要针对 Hotspot VM 中"CMS + ParNew"组合的一些使用场景进行总结.重点通过部分源码对根因进行分析以及对排查方法进行总结,排查过程会省 ...
- 美团技术:Java中9种常见的CMS GC问题分析与解决
目前,互联网上 Java 的 GC 资料要么是主要讲解理论,要么就是针对单一场景的 GC 问题进行了剖析,对整个体系总结的资料少之又少.前车之鉴,后事之师,美团的几位工程师历时一年多的时间,搜集了内部 ...
最新文章
- cocos2dx-CCScrollView的制作
- 关于Redis与关系型数据的一些区别
- 华为传输服务器系统类型,服务器操作系统类型
- 福建工程学院寒假作业G题
- Ubuntu 无法mount解决办法
- XMind软件简易使用教程
- 微机原理与接口技术实验
- C语言malloc函数详解
- c++基础复习(2)
- (OpenCV)图像目标尺寸检测
- 重装战姬服务器维护,重装战姬2020年10月1日更新维护公告_重装战姬2020年10月1日更新了什么_玩游戏网...
- java 文件上传漏洞_文件上传漏洞(绕过姿势)
- c语言各种输出错误提示,C语言错误处理-输出错误信息
- 数组的正负数分割排序
- Unity发布小游戏(五):小游戏的打包与上传到CCD云服务器
- 日历 fullCalendar 整合农历
- 重学计算机网络(二) - 曾记否,查IP地址
- 一个前辈的大二到大三的书单
- UART介绍版(勿看简单介绍)
- 稀疏图Johnson算法
热门文章
- python笔记之scrapy
- java中Robot
- 用commons-fileupload-1.2 实现文件上传
- MiniGUI开发环境搭建全记录(嵌入式计X86)
- myeclipse写简单bbs代码_RabbitMQ实现即时通讯居然如此简单!连后端代码都省得写了?...
- 编程实现基于二维易位置换机制进行信息加解密_基于TEE的TBOX安全技术
- 如何判断两个平面相交_数学提高平面与平面垂直的判定方法是什么
- vue前端架构文档_Dubbo分布式架构搭建教育PC站-Vue前端:课程和登录页
- docker和虚拟机的区别_详解win7操作系统下安装部署Docker环境
- php redis 扩展 编译安装,Linux 下 PHP 扩展 redis 编译安装