集群环境:一主三从,Spark为Spark On YARN模式

Spark导入hbase数据方式有多种

1.少量数据:直接调用hbase API的单条或者批量方法就可以

2.导入的数据量比较大,那就需要先生成hfile文件,在把hfile文件加载到hbase里面

下面主要介绍第二种方法:

该方法主要使用spark Java API的两个方法:

1.textFile:将本地文件或者HDFS文件转换成RDD

2.flatMapToPair:将每行数据的所有key-value对象合并成Iterator对象返回(针对多family,多column)

代码如下:

package scala;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.HFileOutputFormat2;
import org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.PairFlatMapFunction;
import org.apache.spark.storage.StorageLevel; import util.HFileLoader; public class HbaseBulkLoad { private static final String ZKconnect="slave1,slave2,slave3:2181";
private static final String HDFS_ADDR="hdfs://master:8020";
private static final String TABLE_NAME="DBSTK.STKFSTEST";//表名
private static final String COLUMN_FAMILY="FS";//列族 public static void run(String[] args) throws Exception {
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", ZKconnect);
configuration.set("fs.defaultFS", HDFS_ADDR);
configuration.set("dfs.replication", "1"); String inputPath = args[0];
String outputPath = args[1];
Job job = Job.getInstance(configuration, "Spark Bulk Loading HBase Table:" + TABLE_NAME);
job.setInputFormatClass(TextInputFormat.class);
job.setMapOutputKeyClass(ImmutableBytesWritable.class);//指定输出键类
job.setMapOutputValueClass(KeyValue.class);//指定输出值类
job.setOutputFormatClass(HFileOutputFormat2.class); FileInputFormat.addInputPaths(job, inputPath);//输入路径
FileSystem fs = FileSystem.get(configuration);
Path output = new Path(outputPath);
if (fs.exists(output)) {
fs.delete(output, true);//如果输出路径存在,就将其删除
}
fs.close();
FileOutputFormat.setOutputPath(job, output);//hfile输出路径 //初始化sparkContext
SparkConf sparkConf = new SparkConf().setAppName("HbaseBulkLoad").setMaster("local[*]");
JavaSparkContext jsc = new JavaSparkContext(sparkConf);
//读取数据文件
JavaRDD<String> lines = jsc.textFile(inputPath);
lines.persist(StorageLevel.MEMORY_AND_DISK_SER());
JavaPairRDD<ImmutableBytesWritable,KeyValue> hfileRdd =
lines.flatMapToPair(new PairFlatMapFunction<String, ImmutableBytesWritable, KeyValue>() {
private static final long serialVersionUID = 1L;
@Override
public Iterator<Tuple2<ImmutableBytesWritable, KeyValue>> call(String text) throws Exception {
List<Tuple2<ImmutableBytesWritable, KeyValue>> tps = new ArrayList<Tuple2<ImmutableBytesWritable, KeyValue>>();
if(null == text || text.length()<1){
return tps.iterator();//不能返回null
}
String[] resArr = text.split(",");
if(resArr != null && resArr.length == 14){
byte[] rowkeyByte = Bytes.toBytes(resArr[0]+resArr[3]+resArr[4]+resArr[5])
byte[] columnFamily = Bytes.toBytes(COLUMN_FAMILY);
ImmutableBytesWritable ibw = new ImmutableBytesWritable(rowkeyByte);
//EP,HP,LP,MK,MT,SC,SN,SP,ST,SY,TD,TM,TQ,UX(字典顺序排序)
//注意,这地方rowkey、列族和列都要按照字典排序,如果有多个列族,也要按照字典排序,rowkey排序我们交给spark的sortByKey去管理
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("EP"),Bytes.toBytes(resArr[9]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("HP"),Bytes.toBytes(resArr[7]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("LP"),Bytes.toBytes(resArr[8]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("MK"),Bytes.toBytes(resArr[13]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("MT"),Bytes.toBytes(resArr[4]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("SC"),Bytes.toBytes(resArr[0]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("SN"),Bytes.toBytes(resArr[1]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("SP"),Bytes.toBytes(resArr[6]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("ST"),Bytes.toBytes(resArr[5]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("SY"),Bytes.toBytes(resArr[2]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("TD"),Bytes.toBytes(resArr[3]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("TM"),Bytes.toBytes(resArr[11]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("TQ"),Bytes.toBytes(resArr[10]))));
tps.add(new Tuple2<>(ibw,new KeyValue(rowkeyByte, columnFamily, Bytes.toBytes("UX"),Bytes.toBytes(resArr[12]))));
}
return tps.iterator();
}
}).sortByKey(); Connection connection = ConnectionFactory.createConnection(configuration);
TableName tableName = TableName.valueOf(TABLE_NAME);
HFileOutputFormat2.configureIncrementalLoad(job, connection.getTable(tableName), connection.getRegionLocator(tableName)); //生成hfile文件
hfileRdd.saveAsNewAPIHadoopFile(outputPath, ImmutableBytesWritable.class, KeyValue.class, HFileOutputFormat2.class, job.getConfiguration()); // bulk load start
Table table = connection.getTable(tableName);
Admin admin = connection.getAdmin();
LoadIncrementalHFiles load = new LoadIncrementalHFiles(configuration);
load.doBulkLoad(new Path(outputPath), admin,table,connection.getRegionLocator(tableName)); jsc.close();
} public static void main(String[] args) {
try {
long start = System.currentTimeMillis();
args = new String[]{"hdfs://master:8020/test/test.txt","hdfs://master:8020/test/hfile/test"};
run(args);
long end = System.currentTimeMillis();
System.out.println("数据导入成功,总计耗时:"+(end-start)/1000+"s");
} catch(Exception e) {
e.printStackTrace();
}
} }

代码打包,上传到集群执行如下命令:

./spark-submit --master yarn-client --executor-memory 4G --driver-memory 1G --num-executors 100 --executor-cores 4 --total-executor-cores 400 
--conf spark.default.parallelism=1000 --class scala.HbaseBulkLoad /home/hadoop/app/hadoop/data/spark-hbase-test.jar

本次只测试导入了50000条数据,在测试导入15G(1.5亿条左右)数据时,导入速度没有MapReduce快

用spark导入数据到hbase的更多相关文章

  1. 批量导入数据到HBase

    hbase一般用于大数据的批量分析,所以在很多情况下需要将大量数据从外部导入到hbase中,hbase提供了一种导入数据的方式,主要用于批量导入大量数据,即importtsv工具,用法如下:   Us ...

  2. 通过phoenix导入数据到hbase出错记录

    解决方法1 错误如下 -- ::, [hconnection-0x7b9e01aa-shared--pool11069-t114734] WARN org.apache.hadoop.hbase.ip ...

  3. Hive导入数据到HBase,再与Phoenix映射同步

    1. 创建HBase 表 create 'hbase_test','user' 2. 插入数据 put 'hbase_test','111','user:name','jack' put 'hbase ...

  4. importTSV工具导入数据到hbase

    1.建立目标表test,确定好列族信息. create'test','info','address' 2.建立文件编写要导入的数据并上传到hdfs上 touch a.csv vi a.csv 数据内容 ...

  5. 导入数据到HBase的方式选择

    Choosing the Right Import Method If the data is already in an HBase table: To move the data from one ...

  6. 使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟

    使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟 Sqoop 大数据 Hive HBase ETL 使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟 基础环境 ...

  7. Hbase 学习(十一)使用hive往hbase当中导入数据

    我们可以有很多方式可以把数据导入到hbase当中,比如说用map-reduce,使用TableOutputFormat这个类,但是这种方式不是最优的方式. Bulk的方式直接生成HFiles,写入到文 ...

  8. 教程 | 使用Sqoop从MySQL导入数据到Hive和HBase

    基础环境 sqoop:sqoop-1.4.5+cdh5.3.6+78, hive:hive-0.13.1+cdh5.3.6+397, hbase:hbase-0.98.6+cdh5.3.6+115 S ...

  9. Spark实战之读写HBase

    1 配置 1.1 开发环境: HBase:hbase-1.0.0-cdh5.4.5.tar.gz Hadoop:hadoop-2.6.0-cdh5.4.5.tar.gz ZooKeeper:zooke ...

随机推荐

  1. netlink组播的使用

    Linux的netlink机制是非常好的Linux内核与应用层进行双向交互数据的方式.其常用的单播方式可以实现内核为服务端,应用层为客户端的通信方式.如果需要实现应用层为服务端,内核为客户端的通信方式 ...

  2. html的meta标签

    meta是一个空元素,没有结束标签:meta元素可以附带8个属性,其中4个是通用属性-–dir,lang,xml:lang和title,其他4个是meta特有的属性: schema,name,cont ...

  3. 一个简单的ruby生成器例子(用连续体Continuation实现)

    ruby中有很多经典的驱动器结构,比如枚举器和生成器等.这次简单介绍下生成器的概念.生成器是按照功能要求,一次产生一个对象,或称之为生成一个对象的方法.ruby中的连续体正好可以用来完成生成器的功能. ...

  4. 使用bootstrap table 插件固定表头时 表头与表格内容无法对齐

    在使用bootstrap table开发后台管理系统,表格利用bootstrap-table插件来实现,使用bootstrap-table过程中,会出现表头错位的情况 表头对不齐效果: 解决的方法: ...

  5. MySQL 中索引的限制

    MySQL 中索引的限制在使用索引的同时,我们还应该了解在MySQL 中索引存在的限制,以便在索引应用中尽可能的避开限制所带来的问题.下面列出了目前MySQL 中索引使用相关的限制.1. MyISAM ...

  6. imgAreaSelect 中文文档

    http://www.cnblogs.com/boychenney/archive/2011/10/08/2201996.html 一.技术文档 1.介绍 ImgAreaSelect是一jQuery插 ...

  7. manifold tangent classifier

    The Manifold Tangent Classifier (MTC) Putting it all together, here is the high level summary of how ...

  8. 如何使用Sencha touch 构建基于Cordova的安卓项目

     项目构建篇 1.生成sencha touch 项目 新建目录,在命令行进入该目录,sencha -sdk sdk-path generate app appName appPath 2.命令行中进入 ...

  9. ArcCore重构-Platform_Types.h实现辨析

    AUTOSAR定义了一系列PlatformTypes,如uint8/uint16/uint32等等基本类型. It contains all platform dependent types and ...

  10. Flask入门之flask-wtf表单处理

    参考文章 1. 使用 WTForms 进行表单验证  第11集 #Sample.py # coding:utf-8 from flask import Flask,render_template,re ...