看看HBase Bulkload 源码

看看HBase Bulkload 源码

什么都别说先看代码

val regionLocator = new HRegionLocator(hbTableName, classOf[ClusterConnection].cast(conn))
val loader = new LoadIncrementalHFiles(hbaseConf)
val admin = conn.getAdmin()
loader.doBulkLoad(new Path(path),admin,realTable,regionLocator)
-- PS 我看的源码版本是 hbase-client-1.2.1

从上面可以直观的看到2个关键的信息 HRegionLocator 、**LoadIncrementalHFiles **,接下来先看看这2个类有没有说明信息。

HRegionLocator(org.apache.hadoop.hbase.client.HRegionLocator)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ddfJ4oku-1590163467306)(看看HBase Bulkload 源码.assets/1590073793607.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4pCzOzoS-1590163703542)(D:%5Cgithubcom%5CDeceasedLike%5Csrc%5Cmain%5Cmd%5C%E7%9C%8B%E7%9C%8BHBase%20Bulkload%20%E6%BA%90%E7%A0%81.assets%5C1590073793607.png#pic_center)]

翻译下上面的英文起作用:用于查看单个HBase表的区域位置信息,感觉是一些辅助性信息。再看看LoadIncrementalHFiles

LoadIncrementalHFiles (org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles)

“Tool to load the output of HFileOutputFormat into an existing table” 是一个加载HFile文件到HBase的工具,

这个工具类在构造函数中,有几个信息比较有意思:
在这里插入图片描述

  • HFILE_BLOCK_CACHE_SIZE_KEY= "hfile.block.cache.size" -- 设置块缓存大小
    -- 此处禁用了块缓存
    -- 这个块缓存与 bucket cache 有关
    
  • public static final String MAX_FILES_PER_REGION_PER_FAMILY
      = "hbase.mapreduce.bulkload.max.hfiles.perRegion.perFamily"; -- 设置最大的列族个数
    
doBulkLoad (org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles#doBulkLoad)

然后就到了关键的步骤doBulkLoad,上源码:
在这里插入图片描述

  1. 上来就是检查要导入的表,在HBase中是否存在,不存在就抛异常结束

  2. 然后根据配置hbase.loadincremental.threads.max参数,构造一个线程池,这里这个参数既然可以手动配置那么后续就可以考虑适当的增加以提高效率,可以当成后续的优化参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sjOZLhjI-1590163467312)(看看HBase Bulkload 源码.assets/1590075957059.png)]

  1. 这里涉及另一个参数 hbase.loadincremental.validate.hfile,是否需要校验HFile,当文件个数很多时,会比较耗时,如果可以保证HFile文件时正确的时候可以考虑改为false,会提高下效率

  2. 将要加载的HFile封装成LQT,并放入到queue中,然后检查HFile中是否含有目标表中不存在列族,有则抛出异常
    在这里插入图片描述

  3. 参数hbase.bulkload.retries.number控制了hbase对一个hfile最多plit多少次 ,如果Hfile文件 跨越多个region,bulkload会自动地将Hfile文件split,但是对于每次retry只会将指定的Hfile文件split一次

  4. LQI队列转为Multimap,通过groupOrSplitPhase
    在这里插入图片描述

  5. groupOrSplit 方法中尝试将HFile 逻辑上分配给对应的Region ,如果HFile跨越了Region,那么就将其分割,产生2个LQI
    在这里插入图片描述

  6. bulkLoadPhase方法中,利用线程池尝试原子的加载数据tryAtomicRegionLoad(conn, table.getName(), first, lqis)
    在这里插入图片描述

  7. 一系列的操作之后,终于到了加载HFile文件的地方HStore#bulkLoadHFile

bulkLoadHFile(org.apache.hadoop.hbase.regionserver.HStore#bulkLoadHFile(org.apache.hadoop.hbase.regionserver.StoreFile))

先上源码图:
在这里插入图片描述

StoreFileManager有两个实现类:DefaultStoreFileManager(标准了Not thread-safe)、StripeStoreFileManager,我们每个都看看到底都做了什么。

  1. DefaultStoreFileManager [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-benWmO9u-1590163467318)(看看HBase Bulkload 源码.assets/1590134519809.png)]

    • 维护最新的storeFiles的ImmutableList列表

    • sortAndSetStoreFiles 从名字就能看出是排序storeFile,根据SeqId、FileSize、BulkTime、PathName,然后将排序后的storeFiles放到ImmutableList列表中

      private void sortAndSetStoreFiles(List<StoreFile> storeFiles) {
        Collections.sort(storeFiles, StoreFile.Comparators.SEQ_ID);
        storefiles = ImmutableList.copyOf(storeFiles);
      }
      
       public static final Comparator<StoreFile> SEQ_ID =
            Ordering.compound(ImmutableList.of(
                Ordering.natural().onResultOf(new GetSeqId()),
                Ordering.natural().onResultOf(new GetFileSize()).reverse(),
                Ordering.natural().onResultOf(new GetBulkTime()),
                Ordering.natural().onResultOf(new GetPathName())
            ));
      
      • 看完之后发现,总结下HStore 把要加载的HFile的一些重要信息,好像没做什么其他的操作,有点怀疑是不是自己看漏了什么…
  2. StripeStoreFileManager

    • 说这Manager之前要说一下,关于StripeCompactionPolicy,它的机制是:
      • 将Region划分为多个Stripes(相当于sub region)
      • 新Flush产生的文件先放入一个L0的区域,这个区域会有多个HFile文件
      • 然后L0区域进行compaction操作时,会将HFile对应的写入Stripes中
        • 这样可以加速Region Split操作(由全局转换为局部)
    • 这个Manager需要与StripeCompactionPolicy and StripeCompactor 一起使用
      在这里插入图片描述
      大致看了下流程,具体的实现没细看。不过从目前所看到的源码来说,在使用Bulkload批量加载数据的时候:
  • 没有经过MemCache
  • 没有涉及BlockCache
  • 是Region直接加载HFile文件到对应的Store的Stripes中
过程中涉及的可优化的参数
  1. hbase.loadincremental.threads.max构造一个工作线程池
  2. hbase.loadincremental.validate.hfile,是否需要校验HFile,如果可以保证HFile文件时正确的时候可以考虑改为false,会提高下效率
  3. **hbase.bulkload.retries.number控制了hbase对一个hfile最多plit多少次 **,可以尝试增加次数,但是如果报错了代表HFile文件跨过了多个Region,是不是本身也有问题?
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值