HBase BulkLoad批量写入数据实战
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批量写入数据实战的更多相关文章
- 使用bulkload向hbase中批量写入数据
1.数据样式 写入之前,需要整理以下数据的格式,之后将数据保存到hdfs中,本例使用的样式如下(用tab分开): row1 N row2 M row3 B row4 V row5 N row6 M r ...
- 使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历
原文:使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历 常常遇到需要向SQL Server插入批量数据,然后在存储过程中对这些数据进行进一步处理的情况.存储过 ...
- MSSQL批量写入数据方案
近来有一个项目Feature需要有批量写入数据的场景,正巧整理资料发现自己以前也类似实现的项目,在重构的同时把相关资料做了一个简单的梳理,方便大家参考. 循环写入(简单粗暴,毕业设计就这样干的)(不推 ...
- 使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历
使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历 原文:使用XML向SQL Server 2005批量写入数据——一次有关XML时间格式的折腾经历 常常遇 ...
- 聊一聊 HBase 是如何写入数据的?
hi,大家好,我是大D.今天继续了解下 HBase 是如何写入数据的,然后再讲解一下一个比较经典的面试题. Region Server 寻址 HBase Client 访问 ZooKeeper: 获取 ...
- Elasticsearch 5.4.3实战--Java API调用:批量写入数据
这个其实比较简单,直接上代码. 注意部分逻辑可以换成你自己的逻辑 package com.cs99lzzs.elasticsearch.service.imp; import java.sql.Tim ...
- java连接mysql批量写入数据
1.采用公认的MYSQL最快批量提交办法 public void index() throws UnsupportedEncodingException, Exception { //1000个一提交 ...
- Hbase之批量删除数据
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; impo ...
- python elasticsearch 批量写入数据
from elasticsearch import Elasticsearch from elasticsearch import helpers import pymysql import time ...
随机推荐
- NOIP2013 D1T3 货车运输 zz耻辱记
目录 先来证明下lemma: 图上2点间最小边权最大的路径一定在MST上 感性理解下: 每次kruskal algo都连接最大的不成环边 此时有2个未联通的联通块被连起来. 那么考虑u, v两点的联通 ...
- Python3 类和继承和组合
import random as r class Fish: def __init__(self): self.x = r.randint(0,10) self.y = r.randint(0,10) ...
- CSS水平垂直居中!
总结一下,最经典的面试题 分两种情况,宽高确定和不定宽高 (一)宽高确定 初始条件如下: 1. 绝对定位 + 负margin 里面的盒子相对于父盒子绝对定位,距离上面和左边分别为50%,此处的50%是 ...
- 定位方式(d16)
一,回顾, ①selector和xpath的区别,selector是解析的html,xpth是解析的xml,所以使用selector比使用xpath快, ②定位元素的单数和复数,当使用单数定位不到元素 ...
- docker 清理容器的一些命令,彻底或选择清理
越往下的,越要慎重 列出无用的卷 docker volume ls -qf dangling=true 清理无用的卷,容器,镜像 docker volume rm $(docker volume ls ...
- DataTable的Merge\COPY\AcceptChange使用说明
在C#内使用DataTable的Merge().Copy().AcceptChange().Clone()方法的用途如下: 1.Merge()可将两个不同的表结构的表进行合并,合并后新表的列为之前两表 ...
- Windows下安装Kafka
一.安装JDK 二.安装zooeleeper 下载安装包:http://zookeeper.apache.org/releases.html#download 下载后解压到一个目录: 1.进入Zook ...
- 使用自建Git服务器管理私有项目 Centos 7.3 + Git 2.11.0 + gitosis (实测 笔记)
环境: 系统硬件:vmware vsphere (CPU:2*4核,内存2G,双网卡) 系统版本:CentOS-7-x86_64-Minimal-1611.iso GIT服务器IP:192.168.1 ...
- hive的join
第一:在map端产生join mapJoin的主要意思就是,当链接的两个表是一个比较小的表和一个特别大的表的时候,我们把比较小的table直接放到内存中去,然后再对比较大的表格进行m ...
- yarn的工作原理
1.YARN 是什么? 从业界使用分布式系统的变化趋势和 hadoop 框架的长远发展来看,MapReduce的 JobTracker/TaskTracker 机制需要大规模的调整来修复它在可扩展性, ...