使用BulkLoad是由于实际业务的需要,每个月底都需要向HBase插入大约200G的数据,接近10亿条记录。在插入过程中需要占用大量的IO资源,极大影响了现有的实时数据入库业务的效率。因此需要寻找一种替代的方案来在不影响现有业务的基础上,不占用大量集群资源,快速高效的插入大量的数据。本文主要介绍了BulkLoad的工作机制和应用,以及在使用过程中遇到的问题,最后简要分析了BulkLoad的源码步骤。
BulkLoad简介
HBase可以使用多种方式将数据加载到表中,最直接的方法是使用MapReduce作业中的TableOutputFormat类,或者使用普通的客户端API。但是这些并不总是最有效的方法,涉及到的flush,split,compaction等操作都容易造成节点不稳定,数据导入慢,耗费资源等问题,在海量数据的导入过程极大的消耗了系统性能。
BulkLoad功能使用MapReduce作业直接在 HDFS 中生成持久化的 HFile 数据格式文件,然后将生成的HFile直接加载到正在运行的集群中,从而完成巨量数据快速入库的操作。配合 MapReduce 完成这样的操作,不占用 Region 资源,不会产生巨量的写入 I/O,所以需要较少的 CPU 和网络资源。
但是BulkLoad也有局限,正常的写入是先写WAL,然后在写memstore,而BulkLoad没有写WAL这一步,因此在BulkLoad出现异常情况下,HBase可无法恢复还未持久化的数据。股市数据要求严格,不能丢任意一条记录。因此BulkLoad的局限对其有很大的影响。如果出现数据缺少就要采用其它办法了。
BulkLoad的原理和流程
使用BulkLoad需要两个过程:
1、Transform阶段:使用MapReduce将HDFS上的数据生成成HBase的底层Hfile数据。
2、Load阶段:根据生成的目标HFile,利用HBase提供的BulkLoad工具将HFile Load到HBase目录下面。
下面使用精简化码来说明整个过程。
Transform阶段
编写Mapper,对数据进行简单的处理生成rowkey,put输出
public static class BulkLoadMapper extends Mapper<LongWritable, Text, ImmutableBytesWritable, Put> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] items =