1.概述

在进行数据传输中,批量加载数据到HBase集群有多种方式,比如通过HBase API进行批量写入数据、使用Sqoop工具批量导数到HBase集群、使用MapReduce批量导入等。这些方式,在导入数据的过程中,如果数据量过大,可能耗时会比较严重或者占用HBase集群资源较多(如磁盘IO、HBase Handler数等)。今天这篇博客笔者将为大家分享使用HBase BulkLoad的方式来进行海量数据批量写入到HBase集群。

2.内容

在使用BulkLoad之前,我们先来了解一下HBase的存储机制。HBase存储数据其底层使用的是HDFS来作为存储介质,HBase的每一张表对应的HDFS目录上的一个文件夹,文件夹名以HBase表进行命名(如果没有使用命名空间,则默认在default目录下),在表文件夹下存放在若干个Region命名的文件夹,Region文件夹中的每个列簇也是用文件夹进行存储的,每个列簇中存储就是实际的数据,以HFile的形式存在。路径格式如下:

/hbase/data/default/<tbl_name>/<region_id>/<cf>/<hfile_id>

2.1 实现原理

按照HBase存储数据按照HFile格式存储在HDFS的原理,使用MapReduce直接生成HFile格式的数据文件,然后在通过RegionServer将HFile数据文件移动到相应的Region上去。流程如下图所示:

2.2. 生成HFile文件

HFile文件的生成,可以使用MapReduce来进行实现,将数据源准备好,上传到HDFS进行存储,然后在程序中读取HDFS上的数据源,进行自定义封装,组装RowKey,然后将封装后的数据在回写到HDFS上,以HFile的形式存储到HDFS指定的目录中。实现代码如下:

/**
* Read DataSource from hdfs & Gemerator hfile.
*
* @author smartloli.
*
* Created by Aug 19, 2018
*/
public class GemeratorHFile2 {
static class HFileImportMapper2 extends Mapper<LongWritable, Text, ImmutableBytesWritable, KeyValue> { protected final String CF_KQ = "cf"; @Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
System.out.println("line : " + line);
String[] datas = line.split(" ");
String row = new Date().getTime() + "_" + datas[];
ImmutableBytesWritable rowkey = new ImmutableBytesWritable(Bytes.toBytes(row));
KeyValue kv = new KeyValue(Bytes.toBytes(row), this.CF_KQ.getBytes(), datas[].getBytes(), datas[2].getBytes());
context.write(rowkey, kv);
}
} public static void main(String[] args) {
if (args.length != ) {
System.out.println("<Usage>Please input hbase-site.xml path.</Usage>");
return;
}
Configuration conf = new Configuration();
conf.addResource(new Path(args[]));
conf.set("hbase.fs.tmp.dir", "partitions_" + UUID.randomUUID());
String tableName = "person";
String input = "hdfs://nna:9000/tmp/person.txt";
String output = "hdfs://nna:9000/tmp/pres";
System.out.println("table : " + tableName);
HTable table;
try {
try {
FileSystem fs = FileSystem.get(URI.create(output), conf);
fs.delete(new Path(output), true);
fs.close();
} catch (IOException e1) {
e1.printStackTrace();
} Connection conn = ConnectionFactory.createConnection(conf);
table = (HTable) conn.getTable(TableName.valueOf(tableName));
Job job = Job.getInstance(conf);
job.setJobName("Generate HFile"); job.setJarByClass(GemeratorHFile2.class);
job.setInputFormatClass(TextInputFormat.class);
job.setMapperClass(HFileImportMapper2.class);
FileInputFormat.setInputPaths(job, input);
FileOutputFormat.setOutputPath(job, new Path(output)); HFileOutputFormat2.configureIncrementalLoad(job, table);
try {
job.waitForCompletion(true);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
} }
}

在HDFS目录/tmp/person.txt中,准备数据源如下:

 smartloli
smartloli2
smartloli3

然后,将上述代码编译打包成jar,上传到Hadoop集群进行执行,执行命令如下:

hadoop jar GemeratorHFile2.jar /data/soft/new/apps/hbaseapp/hbase-site.xml

如果在执行命令的过程中,出现找不到类的异常信息,可能是本地没有加载HBase依赖JAR包,在当前用户中配置如下环境变量信息:

export HADOOP_CLASSPATH=$HBASE_HOME/lib/*:classpath

然后,执行source命令使配置的内容立即生生效。

2.3. 执行预览

在成功提交任务后,Linux控制台会打印执行任务进度,也可以到YARN的资源监控界面查看执行进度,结果如下所示:

等待任务的执行,执行完成后,在对应HDFS路径上会生成相应的HFile数据文件,如下图所示:

2.4 使用BulkLoad导入到HBase

然后,在使用BulkLoad的方式将生成的HFile文件导入到HBase集群中,这里有2种方式。一种是写代码实现导入,另一种是使用HBase命令进行导入。

2.4.1 代码实现导入

通过LoadIncrementalHFiles类来实现导入,具体代码如下:

/**
* Use BulkLoad inport hfile from hdfs to hbase.
*
* @author smartloli.
*
* Created by Aug 19, 2018
*/
public class BulkLoad2HBase { public static void main(String[] args) throws Exception {
if (args.length != ) {
System.out.println("<Usage>Please input hbase-site.xml path.</Usage>");
return;
}
String output = "hdfs://cluster1/tmp/pres";
Configuration conf = new Configuration();
conf.addResource(new Path(args[]));
HTable table = new HTable(conf, "person");
LoadIncrementalHFiles loader = new LoadIncrementalHFiles(conf);
loader.doBulkLoad(new Path(output), table);
} }

执行上述代码,运行结果如下:

2.4.2 使用HBase命令进行导入

先将生成好的HFile文件迁移到目标集群(即HBase集群所在的HDFS上),然后在使用HBase命令进行导入,执行命令如下:

# 先使用distcp迁移hfile
hadoop distcp -Dmapreduce.job.queuename=queue_1024_01 -update -skipcrccheck -m /tmp/pres hdfs://nns:9000/tmp/pres # 使用bulkload方式导入数据
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles /tmp/pres person

最后,我们可以到指定的RegionServer节点上查看导入的日志信息,如下所示为导入成功的日志信息:

-- ::, INFO  [B.defaultRpcServer.handler=,queue=,port=] regionserver.HStore: Successfully loaded store file hdfs://cluster1/tmp/pres/cf/7b455535f660444695589edf509935e9 into store cf (new location: hdfs://cluster1/hbase/data/default/person/2d7483d4abd6d20acdf16533a3fdf18f/cf/d72c8846327d42e2a00780ac2facf95b_SeqId_4_)

2.5 验证

使用BulkLoad方式导入数据后,可以进入到HBase集群,使用HBase Shell来查看数据是否导入成功,预览结果如下:

3.总结

本篇博客为了演示实战效果,将生成HFile文件和使用BulkLoad方式导入HFile到HBase集群的步骤进行了分解,实际情况中,可以将这两个步骤合并为一个,实现自动化生成与HFile自动导入。如果在执行的过程中出现RpcRetryingCaller的异常,可以到对应RegionServer节点查看日志信息,这里面记录了出现这种异常的详细原因。

4.结束语

这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!

另外,博主出书了《Hadoop大数据挖掘从入门到进阶实战》,喜欢的朋友或同学, 可以在公告栏那里点击购买链接购买博主的书进行学习,在此感谢大家的支持。

HBase BulkLoad批量写入数据实战的更多相关文章

  1. 使用bulkload向hbase中批量写入数据

    1.数据样式 写入之前,需要整理以下数据的格式,之后将数据保存到hdfs中,本例使用的样式如下(用tab分开): row1 N row2 M row3 B row4 V row5 N row6 M r ...

  2. 使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历

    原文:使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历 常常遇到需要向SQL Server插入批量数据,然后在存储过程中对这些数据进行进一步处理的情况.存储过 ...

  3. MSSQL批量写入数据方案

    近来有一个项目Feature需要有批量写入数据的场景,正巧整理资料发现自己以前也类似实现的项目,在重构的同时把相关资料做了一个简单的梳理,方便大家参考. 循环写入(简单粗暴,毕业设计就这样干的)(不推 ...

  4. 使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历

    使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历   原文:使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历 常常遇 ...

  5. 聊一聊 HBase 是如何写入数据的?

    hi,大家好,我是大D.今天继续了解下 HBase 是如何写入数据的,然后再讲解一下一个比较经典的面试题. Region Server 寻址 HBase Client 访问 ZooKeeper: 获取 ...

  6. Elasticsearch 5.4.3实战--Java API调用:批量写入数据

    这个其实比较简单,直接上代码. 注意部分逻辑可以换成你自己的逻辑 package com.cs99lzzs.elasticsearch.service.imp; import java.sql.Tim ...

  7. java连接mysql批量写入数据

    1.采用公认的MYSQL最快批量提交办法 public void index() throws UnsupportedEncodingException, Exception { //1000个一提交 ...

  8. Hbase之批量删除数据

    import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; impo ...

  9. python elasticsearch 批量写入数据

    from elasticsearch import Elasticsearch from elasticsearch import helpers import pymysql import time ...

随机推荐

  1. 把H5打包成IOS APP其实可以很简单!签名?越狱?都不需要!

    很多小伙伴都在开发自己的app, 有的实现实现比较简单,就是一个h5页面,然后想要打包成app发布出去. 这个想法很单纯 打包生成个app这个是很简单的,网上一堆打包工具,分分钟可以完成 BUT…… ...

  2. vs2015配置OpenCV遇到的问题

    OpenCV的配置过程可以参考博文:https://www.cnblogs.com/linshuhe/p/5764394.html 简要记载配置过程: 1.官网下载OpenCV安装包,并解压到目录,例 ...

  3. Kafka详细配置

    转自:http://blog.csdn.net/suifeng3051/article/details/38321043?utm_source=tuicool&utm_medium=refer ...

  4. CentOS7上安装Snipe-IT4.6.3详细过程及注意事项

    笔者采用的是CentOS7,先对系统进行Update,然后安装军哥的LNMPA,详情请参考lnmp.org 注意:安装LNMPA前需要修改lnmp.conf中这一行为下面,也就是要安装PHP的File ...

  5. 【原创】XAF ITreeNode+NonPersistent 使用方式

    在XAF中使用非持久化对象创建出TreeList这种树形结构 private void SetShowRFID(TArchivesBorrow archivesInStorage, string rf ...

  6. 【转】priority_queue优先队列

    转自:http://www.cppblog.com/shyli/archive/2007/04/06/21366.html http://www.cppblog.com/shyli/archive/2 ...

  7. ora-01033 oracle initialization or

    这次出现这个问题是源于错删了 DBF文件. 解决方案如下: 1.打开SQL Plus 最后把你删掉的那个文件的表空间删掉就好了

  8. 手机touch事件及参数【转】(自己懒得写了,找了一篇摘过来)

    [html5构建触屏网站]之touch事件 前言 一个触屏网站到底和传统的pc端网站有什么区别呢,交互方式的改变首当其冲.例如我们常用的click事件,在触屏设备下是如此无力. 手机上的大部分交互都是 ...

  9. H5项目常见问题及注意事项,视频全屏,定位,屏幕旋转和触摸,偏页面重构向 来源joacycode的github

    Meta基础知识: H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 //一.HTML页面结构 <meta name="viewport" content="wi ...

  10. Spring Boot 实现 RabbitMQ 延迟消费和延迟重试队列

    本文主要摘录自:详细介绍Spring Boot + RabbitMQ实现延迟队列 并增加了自己的一些理解,记录下来,以便日后查阅. 项目源码: spring-boot-rabbitmq-delay-q ...