• 转 HBase LRUBlockCache与BucketCache二级缓存机制原理剖析与参数调优-OLAP商业环境实战


    原文地址 https://blog.csdn.net/shenshouniu/article/details/84577050

     版权声明:套技术专栏是作者(秦凯新)平时工作的总结和升华,并深度整理大量网上资源和专业书籍。通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,如有任何学术交流,可随时联系。 作者:秦凯新的技术社区 链接:https://juejin.im/post/5c7bdea6e51d45581b20572 https://blog.csdn.net/shenshouniu/article/details/84577050

    本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。版权声明:禁止转载,欢迎学习。QQ邮箱地址:1120746959@qq.com,如有任何学术交流,可随时联系。

    网上的Hbase调优资料参差不齐,实在是不忍卒读,有些都是拼凑且版本过时的东西,我这里决定综合所有优质资源进行整合,写一份最全,最有深度,不过时的技术博客。辛苦成文,各自珍惜,谢谢!

    1 BlockCache 唯一性

    • 一个 RegionServer只有一个BlockCache。
    • BlockCache的诞生就是用来优化读取性能的。
    • HBase Block 目前主要有DATA,ENCODED_DATA,META,FILE_INFO,ROOT_INDEX等。
    • BlockCache 目前主要有LRUBlockCache和SlabCache,以及BucketCache等。

    2 LRUBlockCache的三段缓存架构

    • hfile.block.cache.size.LRUBlockCache: 参数表示占用堆内存比例,默认是0.4,目前这是唯一的LRUBlockCache,无法被关闭。

    • BlockCache配置和Memstore配置的联动影响,即:Memstore+BlockCache的内存占比不能超过0.8(即80%),否则就会报错。注意必须留20%的机动空间:

            hbase.regionserver.global.memstore.size+hfile.block.cache.size<=0.8
      
      • 1
    • LRUBlockCache 完全基于JVM heap的LRU的方案,当缓存写满了之后,会根据LRU的算法来淘汰block。

    • LRUBlockCache的三段缓存架构:

      • 第一段single-access占用25%的比例,也即单次读取区,block被读出后先放到这个区域,当被读到多次后会升级到下一个区域。
      • 第二段multi-acsess占用50%的比例,也即多次读取区,当一个被缓冲到单次读取区后又被访问多次,会升级到这个区。
      • in-memory占用25%的比例,这个区域跟Block被访问几次没有什么关系,它只存放那些被设置了IN-MEMORY=true的列族中读取出来的block。

    3 LRUBlockCache的弊端

    LRUBlockCache完全基于JVM Heap的缓存,那么势必会造成一个后果,随着内存中对象越来越多,每隔一段时间肯定会产生Full GC。

    4 SlabCache 堆外内存的创意(已废弃)

    4.1 堆外内存烫手山芋

    • 因为堆外内存存储的数据都是原始数据,对于一个对象,比如先序列化之后才能存储,所以不能存储大对象。
    • 堆外内存并不是JVM的管理范围,所以当内存泄露的时候非常不好排查问题。
    • 对外内存使用的是物理内存,当使用过大的时候,物理内存可能会爆掉。

    5 BucketCache 应运而生

    5.1 BucketCache理论基础

    • CombinedBlockCache是一个LRUBlockCache和BucketCache的混合体。BucketCache是阿里贡献的。LRUBlockCache中主要存储Index Block和Bloom Block,而将Data Block存储在BucketCache中。因此一次随机读需要首先在LRUBlockCache中查到对应的Index Block,然后再到BucketCache查找对应数据块。

    • BucketCache可以有三种工作模式:heap、offheap、file。heap模式表示这些Bucket是从JVM Heap中申请,offheap模式使用DirectByteBuffer技术实现堆外内存存储管理,而file模式使用类似SSD的高速缓存文件存储数据块。

    • 无论在哪一种工作模式下,BucketCache都会申请许多带有固定大小标签的Bucket,一种Bucket只是一种指定的BlockSize的数据块,初始化的时候申请14个不同大小的Bucket,而且即使在某一种Bucket空间不足的情况下,系统也会从其他Bucket空间借用内存使用,不会出现内存使用率低下的情况。这里每个Bucket的大小上限为最大尺寸的Block * 4,比如最大容纳Block类型为512KB,那么每个Bucket的大小就是512KB*4 =2018。若配置了4,则会有2048/4=512个4K的空间。

    • 我们将物理空间划分为一堆等大的Bucket,每一个Bucket有一个序号及一个size标签,于是Block所在bucket的序号及其在bucket中的offset与block在物理空间的offset就形成了一一对应。我们通过BucketAllocator为指定大小的Block寻找一个Bucket进行存放,于是就得到了其在物理空间上的位置。

    • 每个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

    • 相同size标签的Bucket由同一个BucketSizeInfo管理

    • Bucket的size标签可以动态调整,比如64K的block数目比较多,65K的bucket被用完了以后,其他size标签的完全空闲的bucket可以转换成为65K的bucket,但是至少保留一个该size的bucket

    • 如果最大size的bucket为513K,那么超过这个大小的block无法存储,直接拒绝

    • 如果某个size的bucket用完了,那么会依照LRU算法触发block淘汰

    • hbase 表参数一览

        hbase(main):002:0> create 'Test',{NAME=>'d',IN_MEMORY=>'true'}
        0 row(s) in 4.4970 seconds
        => Hbase::Table - Test
        
        hbase(main):003:0> describe 'Test'
        Table Test is ENABLED                                                                                                                                                                            
        Test                                                                                                                                                                                             
        COLUMN FAMILIES DESCRIPTION                                                                                                                                                                      
        {NAME => 'd', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'true', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => 
        '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}                                                                                                                       
        1 row(s) in 0.2530 seconds
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    5.2 BucketCache的参数设置

    • BucketCache默认是开启的,如果不想让某个列族使用BucketCache,可以使用一下命令

        alter 'mytable' , CONFIGURATION => {CACHE_DATA_IN_L1 => 'true'}
      
      • 1
    • BucketCache 相关的配置项如下:

      • hbase.bucketcache.ioengine :使用的存储介质,可选值为heap ,offheap,file。不设置的话,默认为offheap。

      • hbase.bucketcache.combinedcache.enabled:是否打开组合模式(combinedcache),默认是true

      • hbase.bucketcache.size:BucketCache所占的大小

        如果设置为0.0-1.0 ,则代表占堆内存的百分比
        如果大于1,则代表实际的BucketCache的大小,单位为MB。
        默认值为0.0,即关闭BucketCache
        
        • 1
        • 2
        • 3
      • hbase.bucketcache.bucket.sizes:定义所有Block种类,默认是14中,默认值为4,8,16,32,40…

      • -XX:MaxDirectMemorySize:这是JVM启动参数,该参数定义了JVM可以获取的堆外内存上限。

    5.3 BucketCache组合模式的强强合作

    • 具体解释为把不同类型的Block分别放到LRUCache和BucketCache中,如:Index Block和Bloom Block会被放到LRUCache中,Data Block 被直接放进BucketCache中,所以每次查询,都会先去LRUCache查询一下,然后再去BucketCache中查询真正的数据。
    • LRUCache使用内存,BucketCache使用SSD,HFile使用机械硬盘。

    5.4 BucketCache 测试报告

    • BucketCache自己使用内存,碎片比较少,所以GC时间大部分都要比LRUBlockCache短。
    • 在缓存全部命中的情况下,LRUBlockCache是BucketCache吞吐量的两倍。在缓存基本命中的情况下,LRUBlockCache是BucketCache吞吐量相当。
    • 读写延迟,IO方面基本相当。
    • 强烈建议线上配置BucketCache模式。可能很多专家都测试过这两种模式下的GC、吞吐量、读写延迟等指标,看到测试结果都会很疑惑,BucketCache模式下的各项性能指标都比LruBlockCache差了好多,但是突然我弄明白了,测试肯定是在基本全内存场景下进行的,这种情况下确实会是如此。但是话又说回来,在大数据场景下又有多少业务会是全内存操作呢?

    5.5 RegionServer内存分配

      
    RegionServer进程的内存就是JVM内存,主要分为三部分:LRUBlockCache,用于读缓存;MemStore,用于写缓存;Other,用于RS运行所必须的其他对象

    6 总结

    网上的Hbase调优资料参差不齐,实在是不忍卒读,有些都是拼凑且版本过时的东西,我这里决定综合所有优质资源进行整合,写一份最全,最有深度,不过时的技术博客。辛苦成文,各自珍惜,谢谢

    秦凯新 于深圳 201811280111

  • 相关阅读:
    《当程序员的那些狗日日子》(二十七)大项目
    《当程序员的那些狗日日子》(四十二)内心的挣扎
    《当程序员的那些狗日日子》(二十一)加班,加班
    《当程序员的那些狗日日子》(三十四)人事变动
    《当程序员的那些狗日日子》(五十二)同学情与差距
    《当程序员的那些狗日日子》(四十四)是办公室还是牢房
    《当程序员的那些狗日日子》(四十七)躁动的空气
    《当程序员的那些狗日日子》(三十七)黯然离去
    《当程序员的那些狗日日子》(十六)告别
    《当程序员的那些狗日日子》(二十三)死在了今天的晚上
  • 原文地址:https://www.cnblogs.com/wanxqing/p/10910547.html
Copyright © 2020-2023  润新知