Spark-02: RDD编程基础

目录

1.RDD 介绍

2.RDD 分区

3.RDD 创建

4.RDD 常用转换算子

 4.1 map算子

4.2 flatMap

4.3 distinct

4.4 filter

4.5 sortBy

4.6 groupBy

4.7 groupByKey

4.8 reduceByKey

4.9 intersection

4.10 union

4.11 subtract

4.12 join

5.RDD 常用行动算子

5.1 reduce

5.2 collect

5.3 count

5.4 first

5.5 take

5.9 foreach

6.RDD save 相关算子

6.1 saveAsTextFile

6.2 saveAsObjectFile

7.RDD持久化

7.1 RDD 缓存

7.2 RDD检查点(checkpoint)


1.RDD 介绍

        RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是 Spark 中最基本的数据处理模型。代码中是一个抽象类,它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。

        RDD算子分为转换(Transformation)算子和行动( Action)算子,程序运行到转换算子时并不会马上执行转算子,只有碰到行动算子才会真正执行转换算子。

2.RDD 分区

        RDD内部的数据集在逻辑上会被划分为多个分区,而在物理上则被分配到多个任务中,以便在分布式计算中进行并行处理。分区的个数决定了计算的并行度,每一个分区内的数据都在一个单独的任务上执行。如果在计算过程中没有指定分区数,那么Spark会采用默认的分区数,默认的分区数为程序运行是分配到的CPU核心数。

3.RDD 创建

        创建RDD一般有三种方式:

  1. 通过集合创建RDD:使用SparkContext.parallelize方法将集合转成RDD。
  2. 通过文件创建RDD:使用SparkContext.textFile方法读取文件内容创建RDD,文件可以是本地文件,也可以是hdfs文件。
  3.  通过其他RDD创建RDD,RDD的内容是不可变的,通过RDD算子操作之后会生产新的RDD。

Java代码示例:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;

import java.util.Arrays;
import java.util.List;

public class RddDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("Spark Java").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2-1.通过集合创建RDD
        List<Integer> salary = Arrays.asList(1000,2000,3000,4000,4000);
        JavaRDD<Integer> salaryRDD = sc.parallelize(salary);
        //2-2.通过文件创建RDD,文件可以本地文件也可以是hdfs文件(hdfs://01.weisx.com:8020/filepath/salary.txt)
        JavaRDD<String> salaryFileRDD = sc.textFile("F:\\24\\salary.txt");
       //2-3.从其他RDD创建RDD,如下面的使用RDD的map算子操作产生新的RDD对象
        //3.对数据进行加工:全部员工工资翻倍
        JavaRDD<Integer> salaryMap = salaryRDD.map(new Function<Integer, Integer>() {
            @Override
            public Integer call(Integer s) throws Exception {
                return s * 2;
            }
        });
        //4.输出加工后的数据:直接打印到控制台
        salaryMap.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala代码示例:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("Spark Scala").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2-1.通过集合创建RDD
    val salary = Array(1000, 2000, 3000, 4000, 5000)
    val salaryRDD = sc.parallelize(salary)
    //2-2.通过文件创建RDD,文件可以本地文件也可以是hdfs文件(hdfs://01.weisx.com:8020/filepath/salary.txt)
    val salaryFileRDD = sc.textFile("F:\\24\\salary.txt")
    //2-3.从其他RDD创建RDD,如下面的使用RDD的map算子操作产生新的RDD对象
    //3.对数据进行加工:全部员工工资翻倍
    val salaryMap = salaryRDD.map(s => {
      s * 2
    })
    //4.输出加工后的数据:直接打印到控制台
    salaryMap.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()
  }
}

4.RDD 常用转换算子

 4.1 map算子

        map算子:对输入的每一元素进行处理,生成一对一的结果,有多少条数据进入,就有多少数据出来。

Java代码示例:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;

import java.util.Arrays;
import java.util.List;

public class RddMapDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddMapDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源:员工工资
        List<Integer> salary = Arrays.asList(1000,2000,3000,4000,4000);

        JavaRDD<Integer> salaryRDD = sc.parallelize(salary);
        //3.使用map算子对数据进行加工:全部员工工资翻倍
        JavaRDD<Integer> salaryMap = salaryRDD.map(new Function<Integer, Integer>() {
            @Override
            public Integer call(Integer s) throws Exception {
                return s * 2;
            }
        });
        //4.输出加工后的数据:直接打印到控制台
        salaryMap.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala代码示例:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddMapDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddMapDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源:员工工资
    val salary = Array(1000,2000,3000,4000,5000)
    val salaryRDD = sc.parallelize(salary)
    //3.使用map算子对数据进行加工:全部员工工资翻倍
    val salaryMap = salaryRDD.map(s=>{
      s*2
    })
    //4.输出加工后的数据:直接打印到控制台
    salaryMap.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()
  }
}

执行结果:

4.2 flatMap

        flatMap:对每一个数据进行处理,每一个数据生成1个或者多个结果,再将全部结果统一转换层一个集合(一维数据)。

Java示例代码:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class RddFlatMapDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddFlatMapDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源
        List<String> lines = Arrays.asList("Hello Spark","Hello Java","Hello Scala");
        JavaRDD<String> linesRDD = sc.parallelize(lines);
        //3.使用flatMap算子对数据进行加工(拆分单词)
       JavaRDD<String> wordRDD = linesRDD.flatMap(new FlatMapFunction<String, String>() {
           @Override
           public Iterator<String> call(String line) throws Exception {
               return Arrays.asList(line.split(" ")).iterator();
           }
       });
//       //使用Lambda方式
        JavaRDD<String> wordRDDLambda = linesRDD.flatMap((FlatMapFunction<String, String>) line ->
                Arrays.asList(line.split(" ")).iterator());
        //4.输出加工后的数据:直接打印到控制台
        wordRDD.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala示例代码:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddFlatMapDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddFlatMapDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源
    val lines = Array("Hello Spark","Hello Java","Hello Scala")
    val linesRDD = sc.parallelize(lines)

    //3.使用flatMap算子对数据进行加工(拆分单词)
    val wordRDD = linesRDD.flatMap(line => line.split(" "))
    //4.输出加工后的数据:直接打印到控制台
    wordRDD.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()


  }
}

执行结果:

4.3 distinct

        去重:将数据集中重复的数据过滤掉。

Java示例代码:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class RddDistinctDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddDistinctDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源
        List<String> lines = Arrays.asList("Hello Spark","Hello Java","Hello Scala");
        JavaRDD<String> linesRDD = sc.parallelize(lines);
        //3-1.使用flatMap算子对数据进行加工(拆分单词)
       JavaRDD<String> wordRDD = linesRDD.flatMap(new FlatMapFunction<String, String>() {
           @Override
           public Iterator<String> call(String line) throws Exception {
               return Arrays.asList(line.split(" ")).iterator();
           }
       });
        //3-2 对拆分后的单词去重
        JavaRDD<String> wordRDDDistinct  = wordRDD.distinct();
        //4.输出加工后的数据:直接打印到控制台
        wordRDDDistinct.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala示例代码:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddDistinctDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddDistinctDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源
    val lines = Array("Hello Spark","Hello Java","Hello Scala")
    val linesRDD = sc.parallelize(lines)

    //3.使用flatMap算子对数据进行加工(拆分单词)
    val wordRDD = linesRDD.flatMap(line => line.split(" "))
    //3-2. 对拆分后的单词去重
    val wordRDDDistinct = wordRDD.distinct()
    //4.输出加工后的数据:直接打印到控制台
    wordRDDDistinct.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()


  }
}

执行结果:

4.4 filter

        将数据根据指定的规则进行筛选过滤,符合规则的数据保留,不符合规则的数据丢弃。当数据进行筛选过滤后,分区不变,但是分区内的数据可能不均衡,生产环境下,可能会出现数据倾斜,可使用repartition或coalesce对数据进行重新分区。

Java示例代码:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class RddFilterDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddFlatMapDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源
        List<String> lines = Arrays.asList("Hello Spark","Hello Java","Hello Scala");
        JavaRDD<String> linesRDD = sc.parallelize(lines);
        //3.使用flatMap算子对数据进行加工(拆分单词)
       JavaRDD<String> wordRDD = linesRDD.flatMap(new FlatMapFunction<String, String>() {
           @Override
           public Iterator<String> call(String line) throws Exception {
               return Arrays.asList(line.split(" ")).iterator();
           }
       });
        //3-2.过滤hello这个单词
        JavaRDD<String> wordRddFilter = wordRDD.filter(new Function<String, Boolean>() {
            @Override
            public Boolean call(String s) throws Exception {
                return !s.equalsIgnoreCase("hello");
            }
        });
        //4.输出加工后的数据:直接打印到控制台
        wordRddFilter.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala示例代码:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddFilterDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddFlatMapDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源
    val lines = Array("Hello Spark","Hello Java","Hello Scala")
    val linesRDD = sc.parallelize(lines)

    //3.使用flatMap算子对数据进行加工(拆分单词)
    val wordRDD = linesRDD.flatMap(line => line.split(" "))
    //3-2.过滤hello这个单词
    val wordRddFilter = wordRDD.filter(w =>{!w.equalsIgnoreCase("hello")})
    //4.输出加工后的数据:直接打印到控制台
    wordRddFilter.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()


  }
}

执行结果:

4.5 sortBy

        对数据进行排序。在排序之前,可以将数据通过 f 函数进行处理,之后按照 f 函数处理的结果进行排序,默认为升序排列。排序后新产生的 RDD 的分区数与原 RDD 的分区数一致。中间存在 shuffle 的过程。

Java示例代码:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;

import java.util.Arrays;
import java.util.List;

public class RddSortByDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("Spark Java").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2-1.通过集合创建RDD
        List<Integer> salary = Arrays.asList(4000,2000,5000,8000,3000);
        JavaRDD<Integer> salaryRDD = sc.parallelize(salary);

        //3.对数据进行加工:排序
        JavaRDD<Integer> salaryRddSortBy = salaryRDD.sortBy(new Function<Integer, Integer>() {
            @Override
            public Integer call(Integer i) throws Exception {
                return i;
            }
        },false,2);
        //4.输出加工后的数据:直接打印到控制台
        salaryRddSortBy.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala示例代码:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddSortByDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("Spark Scala").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2-1.通过集合创建RDD
    val salary = Array(4000, 2000, 5000, 8000, 3000)
    val salaryRDD = sc.parallelize(salary)

    //3.对数据进行加工:全部员工工资翻倍
    val salarySortBy= salaryRDD.sortBy(n => n,true,2)
    //4.输出加工后的数据:直接打印到控制台
    salarySortBy.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()
  }
}

执行结果:

4.6 groupBy

        将数据按指定规则进行分组。

Java示例代码:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function;
import scala.Tuple2;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class RddGroupByDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddGroupByDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源
        List<String> lines = Arrays.asList("Hello Spark","Hello Java","Hello Scala");
        JavaRDD<String> linesRDD = sc.parallelize(lines);
        //3-1.使用flatMap算子对数据进行加工(拆分单词)
       JavaRDD<String> wordRDD = linesRDD.flatMap(new FlatMapFunction<String, String>() {
           @Override
           public Iterator<String> call(String line) throws Exception {
               return Arrays.asList(line.split(" ")).iterator();
           }
       });
        //3-2.使用groupBy算子对拆分后的单词进行分组
       JavaPairRDD<String, Iterable<String>> wordRDDGroupBy = wordRDD.groupBy((Function<String, String>) s -> s);
        //4.输出加工后的数据:直接打印到控制台
        wordRDDGroupBy.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala示例代码:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddGroupByDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddGroupByDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源
    val lines = Array("Hello Spark", "Hello Java", "Hello Scala")
    val linesRDD = sc.parallelize(lines)

    //3-1.使用flatMap算子对数据进行加工(拆分单词)
    val wordRDD = linesRDD.flatMap(line => line.split(" "))

    //3-2.使用groupBy算子对拆分后的单词进行分组
    val wordRDDGroupBy = wordRDD.groupBy(s => s)
      //.collectAsMap() 转成map对象
    //4.输出加工后的数据:直接打印到控制台
    wordRDDGroupBy.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()


  }
}

执行结果:

4.7 groupByKey

        groupByKey算子,只对数据进行分组,不做聚合。groupByKey只处理<K,V>类型的数据。

Java示例代码:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function;
import scala.Tuple2;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class RddGroupByKeyDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddGroupByKeyDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源
        List<String> lines = Arrays.asList("Hello Spark","Hello Java","Hello Scala");
        JavaRDD<String> linesRDD = sc.parallelize(lines);
        //3-1.使用flatMap算子对数据进行加工(拆分单词)
       JavaRDD<String> wordRDD = linesRDD.flatMap(new FlatMapFunction<String, String>() {
           @Override
           public Iterator<String> call(String line) throws Exception {
               return Arrays.asList(line.split(" ")).iterator();
           }
       });
        //3-2.使用groupByKey算子对拆分后的单词进行分组
        JavaPairRDD<String, Iterable<Integer>> wordRDDGroupByKey = wordRDD
                .mapToPair(s -> new Tuple2<>(s,1)).groupByKey()
                //.collectAsMap() 转换成map对象
                ;
        //4.输出加工后的数据:直接打印到控制台
        wordRDDGroupByKey.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala示例代码:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddGroupByKeyDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddGroupByDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源
    val lines = Array("Hello Spark", "Hello Java", "Hello Scala")
    val linesRDD = sc.parallelize(lines)

    //3-1.使用flatMap算子对数据进行加工(拆分单词)
    val wordRDD = linesRDD.flatMap(line => line.split(" "))

    //3-2.使用groupByKey算子对拆分后的单词进行分组
    val wordRDDGroupByKey = wordRDD.map((_,1))
      .groupByKey()
      //.collectAsMap() 转成map对象
    //4.输出加工后的数据:直接打印到控制台
    wordRDDGroupByKey.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()


  }
}

执行结果:

4.8 reduceByKey

        分组聚合:对数据按照相同key对value进行聚合。reduceByKey只处理<K,V>类型的数据。

Java代码示例:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function2;
import scala.Tuple2;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class RddReduceByKeyDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddReduceByKeyDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源
        List<String> lines = Arrays.asList("Hello Spark","Hello Java","Hello Scala");
        JavaRDD<String> linesRDD = sc.parallelize(lines);
        //3.使用flatMap算子对数据进行加工(拆分单词)
       JavaRDD<String> wordRDD = linesRDD.flatMap(new FlatMapFunction<String, String>() {
           @Override
           public Iterator<String> call(String line) throws Exception {
               return Arrays.asList(line.split(" ")).iterator();
           }
       });
        //3-2.对拆分后的单词进行分组聚合
        //mapToPair() 此函数会对一个RDD中的每个元素调用f函数,调用f函数后会进行一定的操作把每个元素都转换成一个<K,V>类型的对象
        JavaPairRDD<String, Integer> wordRDDReduceByKey = wordRDD.mapToPair(w -> new Tuple2<>(w,1))
                .reduceByKey((Function2<Integer, Integer, Integer>) (v1, v2) -> v1+v2) //等价于.reduceByKey(Integer::sum)
                ;
        //4.输出加工后的数据:直接打印到控制台
        wordRDDReduceByKey.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala代码示例:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddReduceByKeyDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddReduceByKeyDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源
    val lines = Array("Hello Spark","Hello Java","Hello Scala")
    val linesRDD = sc.parallelize(lines)

    //3.使用flatMap算子对数据进行加工(拆分单词)
    val wordRDD = linesRDD.flatMap(line => line.split(" "))
    //对拆分之后的单词进行分组聚合
    val wordRDDReduce = wordRDD.map(s =>(s,1))
      .reduceByKey((v1,v2)=>{v1+v2}) // 等价于 .reduceByKey(Integer.sum)
    //4.输出加工后的数据:直接打印到控制台
    wordRDDReduce.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()


  }
}

执行结果:

4.9 intersection

        将两个RDD求交集后返回新的RDD。

Java示例代码:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;

import java.util.Arrays;
import java.util.List;

public class RddIntersectionDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddIntersectionDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源
        List<String> str1 = Arrays.asList("我","爱");
        JavaRDD<String> oneRDD = sc.parallelize(str1);
        List<String> str2 = Arrays.asList("爱","中","国");
        JavaRDD<String> twoRDD = sc.parallelize(str2);
        //3.使用Intersection算子对数据进行加工:
        JavaRDD<String> intersectionRDD = oneRDD.intersection(twoRDD);
        //4.输出加工后的数据:直接打印到控制台
        intersectionRDD.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala示例代码:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddIntersectionDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddIntersectionDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源
    val str1 = Array("我","爱")
    val oneRDD = sc.parallelize(str1)
    val str2 = Array("爱", "中","国")
    val twoRDD = sc.parallelize(str2)
    //3.使用intersection算子对数据进行加工
    val intersectionRDD = oneRDD.intersection(twoRDD)
    //4.输出加工后的数据:直接打印到控制台
    intersectionRDD.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()
  }
}

执行结果:

4.10 union

        将两个RDD求并集后返回新的RDD。

Java示例代码:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;

import java.util.Arrays;
import java.util.List;

public class RddUnionDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddUnionDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源
        List<String> str1 = Arrays.asList("我","爱");
        JavaRDD<String> oneRDD = sc.parallelize(str1);
        List<String> str2 = Arrays.asList("爱","中","国");
        JavaRDD<String> twoRDD = sc.parallelize(str2);
        //3.使用union算子对数据进行加工:
        JavaRDD<String> unionRDD = oneRDD.union(twoRDD);
        //4.输出加工后的数据:直接打印到控制台
        unionRDD.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala示例代码:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddUnionDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddUnionDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源
    val str1 = Array("我","爱")
    val oneRDD = sc.parallelize(str1)
    val str2 = Array("爱", "中","国")
    val twoRDD = sc.parallelize(str2)
    //3.使用union算子对数据进行加工
    val unionRDD = oneRDD.union(twoRDD)
    //4.输出加工后的数据:直接打印到控制台
    unionRDD.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()
  }
}

执行结果:

4.11 subtract

        以一个 RDD 元素为主,去除两个 RDD 中重复元素,将其他元素保留下来。求差集。

Java示例代码:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;

import java.util.Arrays;
import java.util.List;

public class RddSubtractDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddSubtractDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源
        List<String> str1 = Arrays.asList("我","爱");
        JavaRDD<String> oneRDD = sc.parallelize(str1);
        List<String> str2 = Arrays.asList("爱","中","国");
        JavaRDD<String> twoRDD = sc.parallelize(str2);
        //3.使用subtract算子对数据进行加工:
        JavaRDD<String> subtractRDD = oneRDD.subtract(twoRDD);
        //4.输出加工后的数据:直接打印到控制台
        subtractRDD.collect().forEach(s->System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala示例代码:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddSubtractDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddSubtractDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源
    val str1 = Array("我","爱")
    val oneRDD = sc.parallelize(str1)
    val str2 = Array("爱", "中","国")
    val twoRDD = sc.parallelize(str2)
    //3.使用subtract算子对数据进行加工
    val subtractRDD = oneRDD.subtract(twoRDD)
    //4.输出加工后的数据:直接打印到控制台
    subtractRDD.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()
  }
}

执行结果:

4.12 join

        根据两个(K,V)类型的 RDD 通过相同 key 对应的所有元素连接在一起的 (K,(V,W))的 RDD。没有相同key的元素将过滤掉。

Java示例代码:

package com.yichenkeji.demo.sparkjava;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.PairFunction;
import scala.Tuple2;

import java.util.Arrays;
import java.util.List;

public class RddJoinDemo {
    public static void main(String[] args) {
        //1.初始化SparkContext对象
        SparkConf sparkConf = new SparkConf().setAppName("RddJoinDemo").setMaster("local[*]");
        JavaSparkContext sc = new JavaSparkContext(sparkConf);
        //2.加载数据源
        List<String> str1 = Arrays.asList("我","爱");
        JavaPairRDD<String,Integer> oneRDD = sc.parallelize(str1).mapToPair((PairFunction<String, String, Integer>) s -> new Tuple2<>(s,11));
        List<String> str2 = Arrays.asList("爱","中","国");
        JavaPairRDD<String,Integer> twoRDD = sc.parallelize(str2).mapToPair((PairFunction<String, String, Integer>) s -> new Tuple2<>(s,22));
        //3.使用union算子对数据进行加工:
        JavaPairRDD<String, Tuple2<Integer, Integer>> joinRDD = oneRDD.join(twoRDD);

        //4.输出加工后的数据:直接打印到控制台
        joinRDD.collect().forEach(s -> System.out.println(s));
        //5.停止SparkContext
        sc.stop();
    }
}

Scala示例代码:

package com.yichenkeji.demo.sparkscala

import org.apache.spark.{SparkConf, SparkContext}

object RddJoinDemo {
  def main(args: Array[String]): Unit = {
    //1.初始化SparkContext对象
    val sparkConf = new SparkConf().setAppName("RddUnionDemo").setMaster("local[*]")
    val sc = new SparkContext(sparkConf)
    //2.加载数据源
    val str1 = Array("我","爱")
    val oneRDD = sc.parallelize(str1).map(s =>(s,11))
    val str2 = Array("爱", "中","国")
    val twoRDD = sc.parallelize(str2).map(s=>(s,22))
    //3.使用join算子对数据进行加工
    val joinRDD = oneRDD.join(twoRDD)
    //4.输出加工后的数据:直接打印到控制台
    joinRDD.collect().foreach(s => println(s))
    //5.停止SparkContext
    sc.stop()
  }
}

执行结果:

5.RDD 常用行动算子

5.1 reduce

        聚集 RDD 中的所有元素,先聚合分区内数据,再聚合分区间数据

5.2 collect

        以数组 Array 的形式返回数据集的所有元素

5.3 count

        统计RDD中的所有元素个数。

5.4 first

        获取RDD第一个元素。

5.5 take

        获取RDD前n个元素。

5.9 foreach

        遍历RDD中的元素。

6.RDD save 相关算子

        save算子还是属于行动算子范畴。

6.1 saveAsTextFile

        保存成 Text 文件

6.2 saveAsObjectFile

        序列化成对象保存到文件

7.RDD持久化

7.1 RDD 缓存

        Spark应用程序可以使用cache()或persist(StorageLevel)方法将RDD数据持久化到缓存中。cache()只支持在内存中缓存数据,persist()方法则可以根据持久化级别(StorageLevel)将数据存储在内存中或者磁盘上。这两个方法被调用时不会立即缓存,而是触发后面的 action 算子时,该 RDD 计算结果将会被缓存下来。Spark缓存具有容错性,如果RDD的某个分区丢失,那么RDD会计算将自动重新执行。当其他操作需要使用RDD中的数据时,可以直接使用缓存数据,提高RDD计算效率。
        Spark会自动监视每个节点上缓存的使用情况,并以LRU策略删除旧的缓存数据,如果想手动释放RDD缓存,可以通过unpersist()方法实现。

7.2 RDD检查点(checkpoint)

        检查点是Spark提供的一种基于快照的缓存机制,将RDD结果数据存储到磁盘中。对RDD进行checkpoint操作并不会马上被执行,必须执行 Action 操作才能触发。检查点的主要目的是在分布式环境下保证数据的容错性,当某个计算节点出现故障时,Spark可以根据检查点保存的数据,重新恢复该节点的计算结果,从而避免数据丢失。

        检查点与缓存的不同之处在于,它将数据存储在磁盘上,而不是内存中;检查点主要用于保证数据的容错性,而缓存主要用于提高计算速度。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_37559973

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值