一、简介
1.技术说明
通过一套DataSource API的扩展机制,可以访问(读、写)外部的数据源。将外部数据源按照表的方式注册,提供sql查询、数据插入(insert)能力。将外部数据源读取为RDD,提供RDD的算子(group、where、agg)、ML能力。当前可以对接的外部数据源:JDBC、ElasticSearch等。
2.优点
n 将外部数据源纳入到spark的生态系统,如oracle不支持预测分析,通过spark读取oracle数据转换为rdd,就可以利用spark中ML的算法。
n 统一数据源的访问方式,如注册为表,则都可以通过spark的sql方言访问各类数据源。
n 在数据源的读写能力之上,既可以提供跨数据源的数据迁移。如从kafka中获取数据写入到hdfs,然后通过注册ES外部数据源,将数据装载到ES中,最后通过sparksql访问ES。
二、需求场景
从各类数据源中抽取数据集,存储到SparkSQL的查询引擎中,对外提供自助分析。数据源支持如hive、oralce、vertica等,其实hive和加速引擎有可能不是一个Hadoop集群。从外部数据源获取数据集支持以SQL查询的方式提取数据集。
三、实现说明
1、API介绍
SQLContext
|
|
|
|
参考:http://spark.apache.org/docs/latest/api/java/index.html
2、API使用说明
实现功能:将JDBC数据源中多张表的查询结果,写入到HDFS Path。
方案一:
sqlContext.read().jdbc(url,“([SQL Query]) t”,properties).write().save(path)
说明:
1、SQL Query是JDBC数据源的查询。在sparksql使用该JDBC数据源的驱动访问数据库的时候将([SQL Query]) t拼装成select * from ([SQL Query]) t的查询,从而实现在JDBC数据源上直接执行查询。
2、在save函数之前可以通过mode函数制定写入的方式。
3、SQL Query是外部数据源的sql方言。那是否可以通过sparksql的方言来执行该查询?从技术行将是可以的,即将外部数据源的表都注册为external table,见方案二。
方案二:
1、注册为external table的方式
a) 使用API,SQLContext中提供多个“createExternalTable”的API
b) Spark提供的sql语法来创建外部表
2、举例已经注册了两个外部表ft1、ft2,分别对应外部数据源上的pt1、pt2。使用如下一行代码可实现类似的效果
sqlContext.read().sql(“[SQL Query])”,properties).write().save(path)
3、此时的SQL Query即为spark的sql方言
和方案一对比:
1、优点:实现了方言统一
2、缺点:spark内部在执行SQL Query的是没有做谓词下推的,实现方式是将pt1、pt2的表抽取到spark的rdd中然后用spark引擎做运算。在联邦场景或外部数据源是哑存储的情况下,该方式可以接受。但是对于JDBC数据源,显然没有方案一性能高。
方案三:在方案二基础上实现谓词下推
按照方案二的例子,即”注册了两个外部表ft1、ft2,分别对应外部数据源上的pt1、pt2”。在注册为ft1表的时候,对pt1做过滤。涉及到Dataset如下API。
Dataset
|
使用如下的语句可实现谓词下推。SQL Query中使用到ft1的时候,会按照drop、filter的设置提取相应的数据。
Dataset ds=SQLContext.createExternalTable(“ft1”...).drop().filter
缺点:对于where中有布尔运算的情况下,不容易实现filter的谓词下推。如SQL Query中where部分的条件为(ft1.c1>1 or ft2.c2 >10)需要解析该谓词判断如何注册定义ft1、ft2表。
方案四:
将sparksql的sql方言转换成外部数据源的执行计划,在某些情况下可实现方案一的效果。不过需要如下多种情况:
1、仅单数据源查询。
2、对应数据源无法处理某些sql函数的情况下。
3、联邦的情况。
方案四复杂度最高。
优选方案一,方案三是通用方案,需要增加谓词下压的解析模块。
3、部署执行
如上,通过scala或java方式开发job需要将该job提交到spark集群中运行。使用spark的thriftserver笔者猜测实现的功能是受限的。注册两个外表ft1、ft2,在jdbc驱动链接到thriftserver执行insert ft1 select ft2实现数据迁移,但是功能远远没有API丰富,如无法指定保存的模式等等。
四、DataSource API技术原理
1.技术原理
直接看这个博文即可(http://blog.youkuaiyun.com/oopsoom/article/details/42064075)。虽然最新的spark版本是2.1了,仍有参考意义。
2.扩展方式
在上节给出的博文已经给出扩展方式。另外还需要考虑数据类型的转换器的注册。在sparksql的表save到oracle的时候,通过直接推断每个字段的类型,直接在oracle上创建了表,利用的就是数据类型转换器的功能。