Spark-2.3.2 Java SparkSQL的自定义HBase数据源
由于SparkSQL不支持HBase的数据源(HBase-1.1.2),网上有很多是采用Hortonworks的SHC,而SparkSQL操作HBase自定义数据源大多数都是基于Scala实现,我就自己写了一个Java版的SparkSQL操作HBase的小案例。
1、SparkOnHBase
package com.mengyao.tag.utils.external.hbase; import org.apache.spark.SparkConf;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession; /**
*
* @author mengyao
*
*/
public class SparkSQLOnHBase { public static void main(String[] args) {
SparkConf conf = new SparkConf()
.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer"); SparkSession session = SparkSession.builder()
.config(conf)
.appName("SparkOnHBase")
.master("local[*]")
.getOrCreate(); Dataset<Row> df = session.read()
.format("com.mengyao.tag.utils.external.hbase.HBaseSource")
.option("zkHosts", "192.168.10.20")
.option("zkPort", "2181")
.option("hbaseTable", "tbl_tag_user")
.option("family", "test")
.option("selectFields", "id,username,email,phone")
//.option("selectFields", "uid,tids")
.load();
df.printSchema();
df.logicalPlan();
df.explain();
df.filter("id>10").show(); session.close();
} }
2、HBaseSource
package com.mengyao.tag.utils.external.hbase; import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.sources.BaseRelation;
import org.apache.spark.sql.sources.RelationProvider; import scala.collection.immutable.Map; /**
*
* @author mengyao
*
*/
public class HBaseSource implements RelationProvider {
@Override
public BaseRelation createRelation(SQLContext sqlContext, Map<String, String> options) {
return new HBaseRelation(sqlContext, options);
}
}
3、HBaseRelation
package com.mengyao.tag.utils.external.hbase; import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Stream; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.TableInputFormat;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
import org.apache.hadoop.hbase.util.Base64;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.spark.rdd.RDD;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.sources.BaseRelation;
import org.apache.spark.sql.sources.TableScan;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; import scala.Tuple2;
import scala.collection.JavaConverters;
import scala.collection.immutable.Map; /**
*
* @author mengyao
*
*/
public class HBaseRelation extends BaseRelation implements Serializable, TableScan {
private static final long serialVersionUID = 4234614443074355432L;
private static transient Logger logger = LoggerFactory.getLogger(HBaseRelation.class);
private final String HBASE_ZK_PORT_KEY = "hbase.zookeeper.property.clientPort";
private final String HBASE_ZK_PORT_VALUE = "zkPort";
private final String HBASE_ZK_QUORUM_KEY = "hbase.zookeeper.quorum";
private final String HBASE_ZK_QUORUM_VALUE = "zkHosts";
private final String HBASE_ZK_PARENT_KEY = "zookeeper.znode.parent";
private final String HBASE_ZK_PARENT_VALUE = "/hbase-unsecure";
private final String HBASE_TABLE = "hbaseTable";
private final String HBASE_TABLE_FAMILY = "family";
private final String HBASE_TABLE_SELECT_FIELDS = "selectFields";
private final String sperator = ",";
private final String ROW = "row";
private SQLContext sqlContext;
private java.util.Map<String, String> options;
private StructType schema = null;
private boolean updateSchema = true; public HBaseRelation(SQLContext sqlContext, Map<String, String> options) {
this.sqlContext = sqlContext;
this.options = JavaConverters.mapAsJavaMapConverter(options).asJava();
} @Override
public RDD<Row> buildScan() {
validParams(options);
return scan(sqlContext, options);
} @Override
public StructType schema() {
if (updateSchema || schema == null) {
List<StructField> fields = new ArrayList<>();
fields.add(DataTypes.createStructField(ROW, DataTypes.StringType, false));
String fieldsStr = options.get(HBASE_TABLE_SELECT_FIELDS);
String[] fieldStrs = fieldsStr.split(sperator);
Stream.of(fieldStrs).forEach(field -> fields.add(DataTypes.createStructField(field, DataTypes.StringType, false)));
schema = DataTypes.createStructType(fields);
updateSchema = false;
}
logger.info("==== HBaseSource Schema is:{} ====", schema);
return schema;
} @Override
public SQLContext sqlContext() {
return sqlContext;
} private void validParams(java.util.Map<String, String> options){
String zkHosts = options.get(HBASE_ZK_QUORUM_VALUE);
Preconditions.checkNotNull(zkHosts, "zkHosts not null!");
String zkPort = options.get(HBASE_ZK_PORT_VALUE);
Preconditions.checkNotNull(zkPort, "zkPort not null!");
String family = options.get(HBASE_TABLE_FAMILY);
Preconditions.checkNotNull(family, "family not null!");
String fieldsStr = options.get(HBASE_TABLE_SELECT_FIELDS);
Preconditions.checkNotNull(fieldsStr, "fieldsStr not null!");
} private RDD<Row> scan(SQLContext sqlContext, java.util.Map<String, String> options) {
try {
Configuration conf = HBaseConfiguration.create();
conf.set(HBASE_ZK_PORT_KEY, options.get(HBASE_ZK_PORT_VALUE));
conf.set(HBASE_ZK_QUORUM_KEY, options.get(HBASE_ZK_QUORUM_VALUE));
conf.set(HBASE_ZK_PARENT_KEY, HBASE_ZK_PARENT_VALUE);
String family = options.get(HBASE_TABLE_FAMILY);
String fieldsStr = options.get(HBASE_TABLE_SELECT_FIELDS);
String[] selectFileds = fieldsStr.split(sperator); Scan scan = new Scan();
conf.set(TableInputFormat.INPUT_TABLE, options.get(HBASE_TABLE));
ClientProtos.Scan proto = ProtobufUtil.toScan(scan);
String scanStr = Base64.encodeBytes(proto.toByteArray());
conf.set(TableInputFormat.SCAN, scanStr);
logger.info("==== HBaseSource Scan is:{} ====", scanStr); RDD<Tuple2<ImmutableBytesWritable, Result>> hbaseRdd = sqlContext.sparkContext().newAPIHadoopRDD(conf,
TableInputFormat.class, ImmutableBytesWritable.class, Result.class); return hbaseRdd.toJavaRDD().map(t -> t._2).map(r -> {
LinkedList<String> vals = new LinkedList<>();
String row = Bytes.toString(r.getRow());
vals.add(row);
Stream.of(selectFileds).forEach(field -> {
String val = Bytes.toString(r.getValue(Bytes.toBytes(family), Bytes.toBytes(field)));
vals.add(val);
});
return (Row) RowFactory.create(vals.toArray());
}).rdd();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Spark-2.3.2 Java SparkSQL的自定义HBase数据源的更多相关文章
- SparkSQL 如何自定义函数
1. SparkSql如何自定义函数 2. 示例:Average 3. 类型安全的自定义函数 1. SparkSql如何自定义函数? spark中我们定义一个函数,需要继承 UserDefinedAg ...
- spark提示Caused by: java.lang.ClassCastException: scala.collection.mutable.WrappedArray$ofRef cannot be cast to [Lscala.collection.immutable.Map;
spark提示Caused by: java.lang.ClassCastException: scala.collection.mutable.WrappedArray$ofRef cannot b ...
- [转]Java中实现自定义的注解处理器
Java中实现自定义的注解处理器(Annotation Processor) 置顶2016年07月25日 19:42:49 阅读数:9877 在之前的<简单实现ButterKnife的注解功能& ...
- 移动开发首页业界资讯移动应用平台技术专题 输入您要搜索的内容 基于Java Socket的自定义协议,实现Android与服务器的长连接(二)
在阅读本文前需要对socket以及自定义协议有一个基本的了解,可以先查看上一篇文章<基于Java Socket的自定义协议,实现Android与服务器的长连接(一)>学习相关的基础知识点. ...
- spark 执行报错 java.io.EOFException: Premature EOF from inputStream
使用spark2.4跟spark2.3 做替代公司现有的hive选项. 跑个别任务spark有以下错误 java.io.EOFException: Premature EOF from inputSt ...
- Java之SpringBoot自定义配置与整合Druid
Java之SpringBoot自定义配置与整合Druid SpringBoot配置文件 优先级 前面SpringBoot基础有提到,关于SpringBoot配置文件可以是properties或者是ya ...
- 《手把手教你》系列技巧篇(七十一)-java+ selenium自动化测试-自定义类解决元素同步问题(详解教程)
1.简介 前面宏哥介绍了几种关于时间等待的方法,也提到了,在实际自动化测试脚本开发过程,百分之90的报错是和元素因为时间不同步而发生报错.本文介绍如何新建一个自定义的类库来解决这个元素同步问题.这样, ...
- 0基础就可以上手的Spark脚本开发-for Java
前言 最近由于工作需要,要分析大几百G的Nginx日志数据.之前也有过类似的需求,但那个时候数据量不多.一次只有几百兆,或者几个G.因为数据都在Hive里面,当时的做法是:把数据从Hive导到MySQ ...
- 第十一篇:Spark SQL 源码分析之 External DataSource外部数据源
上周Spark1.2刚发布,周末在家没事,把这个特性给了解一下,顺便分析下源码,看一看这个特性是如何设计及实现的. /** Spark SQL源码分析系列文章*/ (Ps: External Data ...
随机推荐
- (生鲜项目)03. xadmin的配置
步骤1. 下载xadmin源码(git_hub上的源码已经不支持py3了,需要从其它老手那里获取),将本文件夹全部放置于合适的目录下(这里放到extra_apps内)2. 在settings的INST ...
- svn 版本控制搭建
1.安装SVN yum install subversion 2.开启服务 systemctl start svnserve.service 3.创建仓库 svnadmin create /opt/s ...
- git pull时 git cannot lock ref XXXXXX (unable to update local ref)错误解决方案
git pull : git cannot lock ref XXXXXX (unable to update local ref) pull代码的时候出现的错误,导致代码拉不下来. 看了一下 ...
- 文件上传速度查询方法(watch工具)
由于业务迁移,需要将大量文件拷贝到目标机器上的/mnt目录,在拷贝过程中,想要查看上传的速度,做法如下:[root@mail01 ~]# du -sh /mnt5.6G /mnt[root@mail0 ...
- 2019/7/18ACM集训
2019-07-18 09:15:34 这个是练习刷的题 Vus the Cossack and Numbers Vus the Cossack has nn real numbers aiai. I ...
- 1.Rabbitmq学习记录《本质介绍,协议AMQP分析》
1.RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现. RabbitMQ的优势-: 除了Qpid,RabbitMQ是唯一一个实现了AMQP ...
- 「APIO2016」烟花表演
「APIO2016」烟花表演 解题思路 又是一道 solpe trick 题,观察出图像变化后不找一些性质还是挺难做的. 首先令 \(dp[u][i]\) 为节点 \(u\) 极其子树所有叶子到 \( ...
- 2.8_Database Interface ADO由来
OLE-DB,它无法广为流行,因为如下两点: 1.由于OLE-DB太底层化,使用上非常复杂,需要程序员拥有高潮的技巧. 2.OLEDB标准的API是C++API,只能供C++语言调用. 为了使得流行的 ...
- 前端开发 Vue Vue.js和Nodejs的关系
首先vue.js 是库,不是框架,不是框架,不是框架. Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据. Vue.js 的核心是一个允许你 ...
- Linux ass2srt
Linux ass2srt bash script #! /usr/bin/env bash ] then echo "USAGE: $0 <directory> <fro ...