spark join操作解读
本文主要介绍spark join相关操作,Java描述。
讲述三个方法spark join,left-outer-join,right-outer-join
我们以实例来进行说明。我的实现步骤记录如下。
1、数据准备
2、HSQL描述
3、Spark描述
1、数据准备
我们准备两张Hive表,分别是orders(订单表)和drivers(司机表),通过driver_id字段进行关联。数据如下:
orders
hive (gulfstream_test)> select * from orders; OK orders.order_id orders.driver_id Time taken: row(s)
drivers
hive (gulfstream_test)> select * from drivers; OK drivers.driver_id drivers.car_id Time taken: row(s)
2、HSQL描述
JOIN
自然连接,输出连接键匹配的记录。
hive (gulfstream_test)> select * from orders t1 join drivers t2 on (t1.driver_id = t2.driver_id) ; OK t1.order_id t1.driver_id t2.driver_id t2.car_id Time taken: row(s)
LEFT OUTER JOIN
左外链接,输出连接键匹配的记录,左侧的表无论匹配与否都输出。
hive (gulfstream_test)> select * from orders t1 left outer join drivers t2 on (t1.driver_id = t2.driver_id) ; OK t1.order_id t1.driver_id t2.driver_id t2.car_id NULL NULL NULL NULL Time taken: row(s)
RIGHT OUTER JOIN
右外连接,输出连接键匹配的记录,右侧的表无论匹配与否都输出。
hive (gulfstream_test)> select * from orders t1 right outer join drivers t2 on (t1.driver_id = t2.driver_id) ; OK t1.order_id t1.driver_id t2.driver_id t2.car_id Time taken: row(s)
3、Spark描述
Join.java
spark实现join的方式也是通过RDD的算子,spark同样提供了三个算子join,leftOuterJoin,rightOuterJoin。
在下面给出的例子中,我们通过spark-hive读取了Hive表中的数据,并将DataFrame转化成了RDD。
在join之后,通过collect()函数把数据拉到Driver端本地,并通过标准输出打印。
需要指出的是:
1)join算子(join,leftOuterJoin,rightOuterJoin)只能通过PairRDD使用;
2)join算子操作的Tuple2<Object1, Object2>类型中,Object1是连接键,我只试过Integer和String,Object2比较灵活,甚至可以是整个Row。
package com.kangaroo.studio.algorithms.join; import com.google.common.base.Optional; import org.apache.spark.SparkConf; import org.apache.spark.api.java.JavaPairRDD; import org.apache.spark.api.java.JavaSparkContext; import org.apache.spark.api.java.function.PairFunction; import org.apache.spark.sql.DataFrame; import org.apache.spark.sql.Row; import org.apache.spark.sql.hive.HiveContext; import scala.Tuple2; import java.io.Serializable; import java.util.Iterator; /* * spark-submit --queue=root.zhiliangbu_prod_datamonitor spark-join-1.0-SNAPSHOT-jar-with-dependencies.jar * */ public class Join implements Serializable { private transient JavaSparkContext javaSparkContext; private transient HiveContext hiveContext; /* * 初始化Load * 创建sparkContext, sqlContext, hiveContext * */ public Join() { initSparckContext(); initHiveContext(); } /* * 创建sparkContext * */ private void initSparckContext() { String warehouseLocation = System.getProperty("user.dir"); SparkConf sparkConf = new SparkConf() .setAppName("spark-join") .set("spark.sql.warehouse.dir", warehouseLocation) .setMaster("yarn-client"); javaSparkContext = new JavaSparkContext(sparkConf); } /* * 创建hiveContext * 用于读取Hive中的数据 * */ private void initHiveContext() { hiveContext = new HiveContext(javaSparkContext); } public void join() { /* * 生成rdd1 * */ String query1 = "select * from gulfstream_test.orders"; DataFrame rows1 = hiveContext.sql(query1).select("order_id", "driver_id"); JavaPairRDD<String, String> rdd1 = rows1.toJavaRDD().mapToPair(new PairFunction<Row, String, String>() { @Override public Tuple2<String, String> call(Row row) throws Exception { String orderId = (String)row.get(0); String driverId = (String)row.get(1); return new Tuple2<String, String>(driverId, orderId); } }); /* * 生成rdd2 * */ String query2 = "select * from gulfstream_test.drivers"; DataFrame rows2 = hiveContext.sql(query2).select("driver_id", "car_id"); JavaPairRDD<String, String> rdd2 = rows2.toJavaRDD().mapToPair(new PairFunction<Row, String, String>() { @Override public Tuple2<String, String> call(Row row) throws Exception { String driverId = (String)row.get(0); String carId = (String)row.get(1); return new Tuple2<String, String>(driverId, carId); } }); /* * join * */ System.out.println(" ****************** join *******************"); JavaPairRDD<String, Tuple2<String, String>> joinRdd = rdd1.join(rdd2); Iterator<Tuple2<String, Tuple2<String, String>>> it1 = joinRdd.collect().iterator(); while (it1.hasNext()) { Tuple2<String, Tuple2<String, String>> item = it1.next(); System.out.println("driver_id:" + item._1 + ", order_id:" + item._2._1 + ", car_id:" + item._2._2 ); } /* * leftOuterJoin * */ System.out.println(" ****************** leftOuterJoin *******************"); JavaPairRDD<String, Tuple2<String, Optional<String>>> leftOuterJoinRdd = rdd1.leftOuterJoin(rdd2); Iterator<Tuple2<String, Tuple2<String, Optional<String>>>> it2 = leftOuterJoinRdd.collect().iterator(); while (it2.hasNext()) { Tuple2<String, Tuple2<String, Optional<String>>> item = it2.next(); System.out.println("driver_id:" + item._1 + ", order_id:" + item._2._1 + ", car_id:" + item._2._2 ); } /* * rightOuterJoin * */ System.out.println(" ****************** rightOuterJoin *******************"); JavaPairRDD<String, Tuple2<Optional<String>, String>> rightOuterJoinRdd = rdd1.rightOuterJoin(rdd2); Iterator<Tuple2<String, Tuple2<Optional<String>, String>>> it3 = rightOuterJoinRdd.collect().iterator(); while (it3.hasNext()) { Tuple2<String, Tuple2<Optional<String>, String>> item = it3.next(); System.out.println("driver_id:" + item._1 + ", order_id:" + item._2._1 + ", car_id:" + item._2._2 ); } } public static void main(String[] args) { Join sj = new Join(); sj.join(); } }
pom.xml
pom依赖
这里只依赖spark-core和spark-hive两个jar。
<dependencies> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_2.10</artifactId> <version>1.6.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-hive_2.10</artifactId> <version>1.6.0</version> <scope>provided</scope> </dependency> </dependencies>
打包方式
<build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <!--这里要替换成jar包main方法所在类 --> <mainClass>com.kangaroo.studio.algorithms.join.Join</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <!-- this is used for inheritance merges --> <phase>package</phase> <!-- 指定在打包节点执行jar包合并操作 --> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build>
执行结果
其中Optional.absent()表示的就是null,可以看到和HSQL是一致的。
Application ID is application_1508228032068_2746260, trackingURL: http://10.93.21.21:4040 ****************** join ******************* driver_id:, order_id:, car_id: ****************** leftOuterJoin ******************* driver_id:, order_id:, car_id:Optional.absent() driver_id:, order_id:, car_id:Optional.absent() driver_id:, order_id:, car_id:Optional.of() ****************** rightOuterJoin ******************* driver_id:, order_id:Optional.absent(), car_id: driver_id:, order_id:Optional.of(), car_id:
spark join操作解读的更多相关文章
- 大数据计算平台Spark内核全面解读
1.Spark介绍 Spark是起源于美国加州大学伯克利分校AMPLab的大数据计算平台,在2010年开源,目前是Apache软件基金会的顶级项目.随着Spark在大数据计算领域的暂露头角,越来越多的 ...
- 大数据开发-Spark Join原理详解
数据分析中将两个数据集进行 Join 操作是很常见的场景.在 Spark 的物理计划阶段,Spark 的 Join Selection 类会根 据 Join hints 策略.Join 表的大小. J ...
- 使用MapReduce实现join操作
在关系型数据库中,要实现join操作是非常方便的,通过sql定义的join原语就可以实现.在hdfs存储的海量数据中,要实现join操作,可以通过HiveQL很方便地实现.不过HiveQL也是转化成 ...
- 使用 Linq 对多个对象进行join操作 C#
class A { public int id { get; set; } public string name { get; set; } } class B { public int id { g ...
- MapReduce 实现数据join操作
前段时间有一个业务需求,要在外网商品(TOPB2C)信息中加入 联营自营 识别的字段.但存在的一个问题是,商品信息 和 自营联营标示数据是 两份数据:商品信息较大,是存放在hbase中.他们之前唯一的 ...
- Spark RDD/Core 编程 API入门系列之动手实战和调试Spark文件操作、动手实战操作搜狗日志文件、搜狗日志文件深入实战(二)
1.动手实战和调试Spark文件操作 这里,我以指定executor-memory参数的方式,启动spark-shell. 启动hadoop集群 spark@SparkSingleNode:/usr/ ...
- 重温sql语句中的join操作
1.join语句 Sql join语句用来合并两个或多个表中的记录.ANSI标准SQL语句中有四种JOIN:INNER,OUTER,LEFTER,RIGHT,一个表或视图也可以可以和它自身做JOIN操 ...
- SQL点滴2—重温sql语句中的join操作
原文:SQL点滴2-重温sql语句中的join操作 1.join语句 Sql join语句用来合并两个或多个表中的记录.ANSI标准SQL语句中有四种JOIN:INNER,OUTER,LEFTER,R ...
- hive:join操作
hive的多表连接,都会转换成多个MR job,每一个MR job在hive中均称为Join阶段.按照join程序最后一个表应该尽量是大表,因为join前一阶段生成的数据会存在于Reducer 的bu ...
随机推荐
- git记录用户名
windows下比较比较好用的Git客户端有2种: 1. msysgit + TortoiseGit(乌龟git) 2. GitHub for Windows github的windows版也用过一段 ...
- Java学习笔记二---设置环境变量JAVA_HOME,CLASSPATH,PATH
1.环境变量包括: JAVA_HOME,CLASSPATH,PATH 2.设置环境变量的目的: 路径搜索,方便查找到jdk的安装路径.方便搜索用到的类文件.方便搜索用到的可执行文件如java,java ...
- 【轉】JS,Jquery获取各种屏幕的宽度和高度
Javascript: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网页可见区域宽: document.b ...
- 从Leetcode的Combination Sum系列谈起回溯法
在LeetCode上面有一组非常经典的题型--Combination Sum,从1到4.其实就是类似于给定一个数组和一个整数,然后求数组里面哪几个数的组合相加结果为给定的整数.在这个题型系列中,1.2 ...
- C#设计模式之四抽象工厂模式(AbstractFactory)【创建型】
一.引言 写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了 ...
- AngularJS -- HTML 编译器
点击查看AngularJS系列目录 转载请注明出处:http://www.cnblogs.com/leosx/ HTML Compiler Overview(HTML 编译器 概要) AngularJ ...
- java从命令行接收多个数字,求和程序分析
问题:编写一个程序,此程序从命令行接收多个数字,求和之后输出结果. 1.设计思想 (1)声明两个变量接收输入的字符串 (2)将字符串转换成int类型 (3)输出求和 2.程序流程图 3.源程序代码 i ...
- BGP协议
BGP属于自治系统间路由协议.BGP的主要目标是为处于不同AS中的路由器之间进行路由信息通信提供保障.BGP既不是纯粹的矢量距离协议,也不是纯粹的链路状态协议,通常被称为通路向量路由协议.这是因为BG ...
- http://codeforces.com/contest/828
哇这是我打的第一场cf,第一题都wa了无数次,然后第二题差几分钟交 ,第二天一交就AC了内心是崩溃的.果然我还是太菜l.... A. Restaurant Tables time limit per ...
- python中如何不区分大小写的判断一个元素是否在一个列表中
python中判断某一个元素是否在一个列表中,可以使用关键字in 和 not in. 示例如下: 如果需要输出相应的信息,可以搭配使用if语句,这里不赘述. --------------------- ...