史上最简单的spark教程第六章-键值对RDD统计,JOIN连接的Java案例实践-(上集)

25 篇文章 10 订阅
24 篇文章 32 订阅

第六章:键值对RDD的操作

  • 键值对RDD的操作用途:
    • 聚合,统计,分组

史上最简单的spark教程
所有代码示例地址:https://github.com/Mydreamandreality/sparkResearch

(提前声明:文章由作者:张耀峰 结合自己生产中的使用经验整理,最终形成简单易懂的文章,写作不易,转载请注明)
(文章参考:Elasticsearch权威指南,Spark快速大数据分析文档,Elasticsearch官方文档,实际项目中的应用场景)
(帮到到您请点点关注,文章持续更新中!)
Git主页 https://github.com/Mydreamandreality

  • 键值对的数据一般需要经过ETL,最终转换成我们需要的数据
  • spark对键值对的RDD提供了一些新的接口,pairRDD
    • 提供并行操作各个键或跨节点重新进行数据分组的操作接口
    • 下面都是针对pairRDD的操作案例

现在这里列举一下pairRDD的常用函数,结合java案例代码很好理解
操作数据:(以键值对集合{(1, 2), (3, 4), (3, 6)}为例)

在这里插入图片描述

大概了解之后我们就可以直接看java代码的案例了

pair RDD(键值对)的转化操作
代码示例:
    public static void run(JavaSparkContext sparkContext) {
        JavaRDD<String> rdd = sparkContext.parallelize(Arrays.asList("test", "java", "python"));

        
        //把RDD的第一个字符当做Key
        PairFunction<String, String, String> pairFunction = new PairFunction<String, String, String>() {
            @Override
            public Tuple2<String, String> call(String s) throws Exception {
                return new Tuple2<>(s.split(" ")[0], s);
            }
        };


        //此处创建好pairRDD
        JavaPairRDD<String, String> pairRdd = rdd.mapToPair(pairFunction);

        //下层都是对pairRDD的操作演示

        /*合并含有相同键的值*/
        pairRdd.reduceByKey(new Function2<String, String, String>() {
            @Override
            public String call(String v1, String v2) throws Exception {
                return v1 + v2;
            }
        });

        /*相同key的元素进行分组*/
        pairRdd.groupByKey();

        /*对pair中的每个值进行应用*/
        pairRdd.mapValues(new Function<String, Object>() {
            @Override
            public Object call(String v1) throws Exception {
                return v1 + "sirZ";
            }
        });

        /*返回只包含键的RDD*/
        pairRdd.keys();

        /*返回只包含值的RDD*/
        pairRdd.values();

        /*返回根据键排序的RDD*/
        pairRdd.sortByKey();

    }

上面的案例是针对单个RDD元素进行操作
这里就针对两个RDD进行操作 (可以理解为MySQL表连接?我不知道是否可以这么理解)
代码示例
/**
 * Created by 張燿峰
 * pairRDD入门案例
 *
 * @author 孤
 * @date 2019/3/19
 * @Varsion 1.0
 */
public class PairRdd {

    public static void run(JavaSparkContext sparkContext) {
        JavaRDD<String> rdd = sparkContext.parallelize(Arrays.asList("test", "java", "python"));


        PairFunction<String, String, String> pairFunction = new PairFunction<String, String, String>() {
            @Override
            public Tuple2<String, String> call(String s) throws Exception {
                return new Tuple2<>(s.split(" ")[0], s);
            }
        };


        //此处创建好pairRDD
        JavaPairRDD<String, String> pairRdd = rdd.mapToPair(pairFunction);

        //下层都是对pairRDD的操作演示

        /*合并含有相同键的值*/
        pairRdd.reduceByKey(new Function2<String, String, String>() {
            @Override
            public String call(String v1, String v2) throws Exception {
                return v1 + v2;
            }
        });

        /*相同key的元素进行分组*/
        pairRdd.groupByKey();

        /*对pair中的每个值进行应用*/
        pairRdd.mapValues(new Function<String, Object>() {
            @Override
            public Object call(String v1) throws Exception {
                return v1 + "sirZ";
            }
        });

        /*返回只包含键的RDD*/
        pairRdd.keys();

        /*返回只包含值的RDD*/
        pairRdd.values();

        /*返回根据键排序的RDD*/
        pairRdd.sortByKey();

    }

    /*针对多个pairRDD元素的操作*/
    public static void runPair(JavaSparkContext sparkContext) {

        JavaRDD<String> rdd = sparkContext.parallelize(Arrays.asList("test", "java", "python"));
        JavaRDD<String> otherRDD = sparkContext.parallelize(Arrays.asList("golang", "php", "hadoop"));

        PairFunction<String, String, String> pairFunction = new PairFunction<String, String, String>() {
            @Override
            public Tuple2<String, String> call(String s) {
                return new Tuple2<>(s.split(" ")[0], s);
            }
        };
        JavaPairRDD<String, String> pairRDD = rdd.mapToPair(pairFunction);
        JavaPairRDD<String, String> pairRDDOther = otherRDD.mapToPair(pairFunction);

        //创建好两个PairRDD之后开始操作

        //删除 ==pairRDD== 中键与pairRDDOther相同的元素
        JavaPairRDD<String, String> subRDD = pairRDD.subtractByKey(pairRDDOther);

        //内连接 inner join 查询
        JavaPairRDD<String, Tuple2<String, String>> jsonRDD = pairRDD.join(pairRDDOther);

        //右连接 right join 查询   //TODO 此处我理解是可以为null的二元组
        JavaPairRDD<String, Tuple2<Optional<String>, String>> rightRDD = pairRDD.rightOuterJoin(pairRDDOther);

        //左连接 left join 查询
        JavaPairRDD<String, Tuple2<String, Optional<String>>> leftRDD = pairRDD.leftOuterJoin(pairRDDOther);

        //将两个RDD中有相同键的数据分组  //TODO 此处我理解是迭代器
        JavaPairRDD<String, Tuple2<Iterable<String>, Iterable<String>>> groupRDD = pairRDD.cogroup(pairRDDOther);


    }

以上就是spark键值对的操作简单案例
首先创建pariRDD(键值对RDD),然后对创建好的PairRDD进行操作
具体的使用看代码中注释,后续还会有更深入的案例

此处需要注意一下: PairRDD也还是RDD组,同样支持RDD所支持的函数
代码案例:
         //pairRDD也可以使用RDD的函数
        //筛选length小于20的元素
        Function<Tuple2<String,String>,Boolean> filterRDD = new Function<Tuple2<String, String>, Boolean>() {
            @Override
            public Boolean call(Tuple2<String, String> v1) {
                return (v1._2.length()<20);
            }
        };
        JavaPairRDD<String,String> filter = pairRDD.filter(filterRDD);

聚合操作
当数据集以键值对形式组织的时候,聚合具有相同键的元素进行一些统计是很常见的操作,之前说过基础 RDD上的 fold(),combine(),reduce() 等行动操作,pair RDD 上则有相应的针对键的转化操作.Spark 有一组类似的操作,可以组合具有相同键的值,这些操作返回 RDD,因此它们是转化操作而不是行动操作
代码案例
JavaRDD<String> wordCount = sparkContext.parallelize(Arrays.asList("1", "2", "3", "4", "5"));

        //返回一个可以迭代的集合
        JavaRDD<String> c = wordCount.flatMap(new FlatMapFunction<String, String>() {
            @Override
            public Iterator<String> call(String v1) throws Exception {
                return Arrays.asList(v1.split(" ")).iterator();
            }
        });

        //现在的数据是 1,2,3,4,5
        JavaPairRDD<String, Integer> result = c.mapToPair(new PairFunction<String, String, Integer>() {
            @Override
            public Tuple2<String, Integer> call(String s) throws Exception {
                return new Tuple2<>(s, 1);
                //此时的数据是 {1,1},{2,1},{3,1},{4,1}...
            }
        }).reduceByKey(new Function2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer v1, Integer v2) throws Exception {
                return v1 + v2;
            }
        });

        /*还可以通过countByValue快速实现单词计数*/
        c.countByValue();
总结
pairRDD(键值对RDD)
有很多函数可以进行基于键的数据合并,它们中的大多数都是在 combineByKey() 的基础上实现的,为用户提供了更简单的接口
combineByKey()的工作原理如下:

在这里插入图片描述

本人纯手工画的,见谅 [狗头]
下一章会写一些pairRDD的行动操作和数据分区等高级概念
左外连接(left-outer-join)是一种常见的关系型数据库操作,用于将两个表格中的数据进行合并。下面是基于SQL、MapReduce、Spark RDDSpark DataFrame以及Spark SQL的实现案例及对比: 1. SQL实现: 在SQL中,可以使用LEFT OUTER JOIN语句来实现左外连接。例如,假设有两个表格A和B,它们有一个共同的字段id,可以使用以下语句进行左外连接: SELECT A.id, A.name, B.age FROM A LEFT OUTER JOIN B ON A.id = B.id; 2. MapReduce实现: 在MapReduce中,可以使用两个MapReduce作业来实现左外连接。第一个作业将表格A中的数据进行映射,第二个作业将表格B中的数据进行映射。然后,将两个作业的输出进行合并,得到左外连接的结果。 3. Spark RDD实现: 在Spark RDD中,可以使用leftOuterJoin()方法来实现左外连接。例如,假设有两个RDDs A和B,它们有一个共同的键key,可以使用以下代码进行左外连接: val result = A.leftOuterJoin(B) 4. Spark DataFrame实现: 在Spark DataFrame中,可以使用join()方法来实现左外连接。例如,假设有两个DataFrame A和B,它们有一个共同的列id,可以使用以下代码进行左外连接: val result = A.join(B, Seq("id"), "left_outer") 5. Spark SQL实现: 在Spark SQL中,可以使用JOIN语句来实现左外连接。例如,假设有两个表格A和B,它们有一个共同的字段id,可以使用以下语句进行左外连接: SELECT A.id, A.name, B.age FROM A LEFT OUTER JOIN B ON A.id = B.id; 综上所述,左外连接可以在SQL、MapReduce、Spark RDDSpark DataFrame以及Spark SQL中进行实现。不同的实现方式有不同的优缺点,需要根据具体的情况选择合适的实现方式。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值