本文主要介绍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操作解读的更多相关文章

  1. 大数据计算平台Spark内核全面解读

    1.Spark介绍 Spark是起源于美国加州大学伯克利分校AMPLab的大数据计算平台,在2010年开源,目前是Apache软件基金会的顶级项目.随着Spark在大数据计算领域的暂露头角,越来越多的 ...

  2. 大数据开发-Spark Join原理详解

    数据分析中将两个数据集进行 Join 操作是很常见的场景.在 Spark 的物理计划阶段,Spark 的 Join Selection 类会根 据 Join hints 策略.Join 表的大小. J ...

  3. 使用MapReduce实现join操作

     在关系型数据库中,要实现join操作是非常方便的,通过sql定义的join原语就可以实现.在hdfs存储的海量数据中,要实现join操作,可以通过HiveQL很方便地实现.不过HiveQL也是转化成 ...

  4. 使用 Linq 对多个对象进行join操作 C#

    class A { public int id { get; set; } public string name { get; set; } } class B { public int id { g ...

  5. MapReduce 实现数据join操作

    前段时间有一个业务需求,要在外网商品(TOPB2C)信息中加入 联营自营 识别的字段.但存在的一个问题是,商品信息 和 自营联营标示数据是 两份数据:商品信息较大,是存放在hbase中.他们之前唯一的 ...

  6. Spark RDD/Core 编程 API入门系列之动手实战和调试Spark文件操作、动手实战操作搜狗日志文件、搜狗日志文件深入实战(二)

    1.动手实战和调试Spark文件操作 这里,我以指定executor-memory参数的方式,启动spark-shell. 启动hadoop集群 spark@SparkSingleNode:/usr/ ...

  7. 重温sql语句中的join操作

    1.join语句 Sql join语句用来合并两个或多个表中的记录.ANSI标准SQL语句中有四种JOIN:INNER,OUTER,LEFTER,RIGHT,一个表或视图也可以可以和它自身做JOIN操 ...

  8. SQL点滴2—重温sql语句中的join操作

    原文:SQL点滴2-重温sql语句中的join操作 1.join语句 Sql join语句用来合并两个或多个表中的记录.ANSI标准SQL语句中有四种JOIN:INNER,OUTER,LEFTER,R ...

  9. hive:join操作

    hive的多表连接,都会转换成多个MR job,每一个MR job在hive中均称为Join阶段.按照join程序最后一个表应该尽量是大表,因为join前一阶段生成的数据会存在于Reducer 的bu ...

随机推荐

  1. git记录用户名

    windows下比较比较好用的Git客户端有2种: 1. msysgit + TortoiseGit(乌龟git) 2. GitHub for Windows github的windows版也用过一段 ...

  2. Java学习笔记二---设置环境变量JAVA_HOME,CLASSPATH,PATH

    1.环境变量包括: JAVA_HOME,CLASSPATH,PATH 2.设置环境变量的目的: 路径搜索,方便查找到jdk的安装路径.方便搜索用到的类文件.方便搜索用到的可执行文件如java,java ...

  3. 【轉】JS,Jquery获取各种屏幕的宽度和高度

    Javascript: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网页可见区域宽: document.b ...

  4. 从Leetcode的Combination Sum系列谈起回溯法

    在LeetCode上面有一组非常经典的题型--Combination Sum,从1到4.其实就是类似于给定一个数组和一个整数,然后求数组里面哪几个数的组合相加结果为给定的整数.在这个题型系列中,1.2 ...

  5. C#设计模式之四抽象工厂模式(AbstractFactory)【创建型】

    一.引言     写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了 ...

  6. AngularJS -- HTML 编译器

    点击查看AngularJS系列目录 转载请注明出处:http://www.cnblogs.com/leosx/ HTML Compiler Overview(HTML 编译器 概要) AngularJ ...

  7. java从命令行接收多个数字,求和程序分析

    问题:编写一个程序,此程序从命令行接收多个数字,求和之后输出结果. 1.设计思想 (1)声明两个变量接收输入的字符串 (2)将字符串转换成int类型 (3)输出求和 2.程序流程图 3.源程序代码 i ...

  8. BGP协议

    BGP属于自治系统间路由协议.BGP的主要目标是为处于不同AS中的路由器之间进行路由信息通信提供保障.BGP既不是纯粹的矢量距离协议,也不是纯粹的链路状态协议,通常被称为通路向量路由协议.这是因为BG ...

  9. http://codeforces.com/contest/828

    哇这是我打的第一场cf,第一题都wa了无数次,然后第二题差几分钟交 ,第二天一交就AC了内心是崩溃的.果然我还是太菜l.... A. Restaurant Tables time limit per ...

  10. python中如何不区分大小写的判断一个元素是否在一个列表中

    python中判断某一个元素是否在一个列表中,可以使用关键字in 和 not in. 示例如下: 如果需要输出相应的信息,可以搭配使用if语句,这里不赘述. --------------------- ...