spark基础的action操作

本文章主要通过java代码实现spark常用的action操作

本文主要通过java代码实现常用的spark的action操作

1 reduce

private static void reduce() {
   // 创建SparkConf和JavaSparkContext
   SparkConf conf = new SparkConf()
         .setAppName("reduce")
         .setMaster("local");  
   JavaSparkContext sc = new JavaSparkContext(conf);
   
   // 有一个集合,里面有1到10,10个数字,现在要对10个数字进行累加
   List<Integer> numberList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
   JavaRDD<Integer> numbers = sc.parallelize(numberList);
   
   // 使用reduce操作对集合中的数字进行累加
   // reduce操作的原理:
      // 首先将第一个和第二个元素,传入call()方法,进行计算,会获取一个结果,比如1 + 2 = 3
      // 接着将该结果与下一个元素传入call()方法,进行计算,比如3 + 3 = 6
      // 以此类推
   // 所以reduce操作的本质,就是聚合,将多个元素聚合成一个元素
   int sum = numbers.reduce(new Function2<Integer, Integer, Integer>() {
      
      private static final long serialVersionUID = 1L;

      @Override
      public Integer call(Integer v1, Integer v2) throws Exception {
         return v1 + v2;
      }
      
   });
   
   System.out.println(sum);  
   
   // 关闭JavaSparkContext
   sc.close();
}

2 collect

private static void collect() {
   // 创建SparkConf和JavaSparkContext
   SparkConf conf = new SparkConf()
         .setAppName("collect")
         .setMaster("local");  
   JavaSparkContext sc = new JavaSparkContext(conf);
   
   // 有一个集合,里面有1到10,10个数字,现在要对10个数字进行累加
   List<Integer> numberList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
   JavaRDD<Integer> numbers = sc.parallelize(numberList);
   
   // 使用map操作将集合中所有数字乘以2
   JavaRDD<Integer> doubleNumbers = numbers.map(
         
         new Function<Integer, Integer>() {

            private static final long serialVersionUID = 1L;
   
            @Override
            public Integer call(Integer v1) throws Exception {
               return v1 * 2;
            }
            
         });
   
   // 不用foreach action操作,在远程集群上遍历rdd中的元素
   // 而使用collect操作,将分布在远程集群上的doubleNumbers RDD的数据拉取到本地
   // 这种方式,一般不建议使用,因为如果rdd中的数据量比较大的话,比如超过1万条
      // 那么性能会比较差,因为要从远程走大量的网络传输,将数据获取到本地
      // 此外,除了性能差,还可能在rdd中数据量特别大的情况下,发生oom异常,内存溢出
   // 因此,通常,还是推荐使用foreach action操作,来对最终的rdd元素进行处理
   List<Integer> doubleNumberList = doubleNumbers.collect();
   for(Integer num : doubleNumberList) {
      System.out.println(num);  
   }
   
   // 关闭JavaSparkContext
   sc.close();
}

3 count

private static void count() {
   // 创建SparkConf和JavaSparkContext
   SparkConf conf = new SparkConf()
         .setAppName("count")
         .setMaster("local");  
   JavaSparkContext sc = new JavaSparkContext(conf);
   
   // 有一个集合,里面有1到10,10个数字,现在要对10个数字进行累加
   List<Integer> numberList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
   JavaRDD<Integer> numbers = sc.parallelize(numberList);
   
   // 对rdd使用count操作,统计它有多少个元素
   long count = numbers.count();
   System.out.println(count);  
   
   // 关闭JavaSparkContext
   sc.close();
}

4 take 

private static void take() {
   // 创建SparkConf和JavaSparkContext
   SparkConf conf = new SparkConf()
         .setAppName("take")
         .setMaster("local");  
   JavaSparkContext sc = new JavaSparkContext(conf);
   
   // 有一个集合,里面有1到10,10个数字,现在要对10个数字进行累加
   List<Integer> numberList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
   JavaRDD<Integer> numbers = sc.parallelize(numberList);
   
   // 对rdd使用count操作,统计它有多少个元素
   // take操作,与collect类似,也是从远程集群上,获取rdd的数据
   // 但是collect是获取rdd的所有数据,take只是获取前n个数据
   List<Integer> top3Numbers = numbers.take(3);
   
   for(Integer num : top3Numbers) {
      System.out.println(num);  
   }
   
   // 关闭JavaSparkContext
   sc.close();
}

5 saveastextfile

private static void saveAsTextFile() {
   // 创建SparkConf和JavaSparkContext
   SparkConf conf = new SparkConf()
         .setAppName("saveAsTextFile");  
   JavaSparkContext sc = new JavaSparkContext(conf);
   
   // 有一个集合,里面有1到10,10个数字,现在要对10个数字进行累加
   List<Integer> numberList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
   JavaRDD<Integer> numbers = sc.parallelize(numberList);
   
   // 使用map操作将集合中所有数字乘以2
   JavaRDD<Integer> doubleNumbers = numbers.map(
         
         new Function<Integer, Integer>() {

            private static final long serialVersionUID = 1L;
   
            @Override
            public Integer call(Integer v1) throws Exception {
               return v1 * 2;
            }
            
         });
   
   // 直接将rdd中的数据,保存在HFDS文件中
   // 但是要注意,我们这里只能指定文件夹,也就是目录
   // 那么实际上,会保存为目录中的/double_number.txt/part-00000文件
   doubleNumbers.saveAsTextFile("hdfs://spark1:9000/double_number.txt");   
   
   // 关闭JavaSparkContext
   sc.close();
}

6 countbykey

private static void countByKey() {
   // 创建SparkConf
   SparkConf conf = new SparkConf()
         .setAppName("countByKey")  
         .setMaster("local");
   // 创建JavaSparkContext
   JavaSparkContext sc = new JavaSparkContext(conf);
   
   // 模拟集合
   List<Tuple2<String, String>> scoreList = Arrays.asList(
         new Tuple2<String, String>("class1", "leo"),
         new Tuple2<String, String>("class2", "jack"),
         new Tuple2<String, String>("class1", "marry"),
         new Tuple2<String, String>("class2", "tom"),
         new Tuple2<String, String>("class2", "david"));  
   
   // 并行化集合,创建JavaPairRDD
   JavaPairRDD<String, String> students = sc.parallelizePairs(scoreList);
   
   // 对rdd应用countByKey操作,统计每个班级的学生人数,也就是统计每个key对应的元素个数
   // 这就是countByKey的作用
   // countByKey返回的类型,直接就是Map<String, Object>
   Map<String, Object> studentCounts = students.countByKey();
   
   for(Map.Entry<String, Object> studentCount : studentCounts.entrySet()) {
      System.out.println(studentCount.getKey() + ": " + studentCount.getValue());  
   }
   
   // 关闭JavaSparkContext
   sc.close();
}

7 groupbykey

/**
 * groupByKey案例:按照班级对成绩进行分组
 */
private static void groupByKey() {
   // 创建SparkConf
   SparkConf conf = new SparkConf()
         .setAppName("groupByKey")
         .setMaster("local");
   // 创建JavaSparkContext
   JavaSparkContext sc = new JavaSparkContext(conf);

   // 模拟集合
   List<Tuple2<String, Integer>> scoreList = Arrays.asList(
         new Tuple2<String, Integer>("class1", 80),
         new Tuple2<String, Integer>("class2", 75),
         new Tuple2<String, Integer>("class1", 90),
         new Tuple2<String, Integer>("class2", 65));

   // 并行化集合,创建JavaPairRDD
   JavaPairRDD<String, Integer> scores = sc.parallelizePairs(scoreList);

   // 针对scores RDD,执行groupByKey算子,对每个班级的成绩进行分组
   // groupByKey算子,返回的还是JavaPairRDD
   // 但是,JavaPairRDD的第一个泛型类型不变,第二个泛型类型变成Iterable这种集合类型
   // 也就是说,按照了key进行分组,那么每个key可能都会有多个value,此时多个value聚合成了Iterable
   // 那么接下来,我们是不是就可以通过groupedScores这种JavaPairRDD,很方便地处理某个分组内的数据
   JavaPairRDD<String, Iterable<Integer>> groupedScores = scores.groupByKey();

   // 打印groupedScores RDD
   groupedScores.foreach(new VoidFunction<Tuple2<String,Iterable<Integer>>>() {

      private static final long serialVersionUID = 1L;

      @Override
      public void call(Tuple2<String, Iterable<Integer>> t)
            throws Exception {
         System.out.println("class: " + t._1);
         Iterator<Integer> ite = t._2.iterator();
         while(ite.hasNext()) {
            System.out.println(ite.next());
         }
         System.out.println("==============================");
      }

   });

   // 关闭JavaSparkContext
   sc.close();
}

8 reducebykey

private static void reduceByKey() {
   // 创建SparkConf
   SparkConf conf = new SparkConf()
         .setAppName("reduceByKey")
         .setMaster("local");
   // 创建JavaSparkContext
   JavaSparkContext sc = new JavaSparkContext(conf);

   // 模拟集合
   List<Tuple2<String, Integer>> scoreList = Arrays.asList(
         new Tuple2<String, Integer>("class1", 80),
         new Tuple2<String, Integer>("class2", 75),
         new Tuple2<String, Integer>("class1", 90),
         new Tuple2<String, Integer>("class2", 65));

   // 并行化集合,创建JavaPairRDD
   JavaPairRDD<String, Integer> scores = sc.parallelizePairs(scoreList);

   // 针对scores RDD,执行reduceByKey算子
   // reduceByKey,接收的参数是Function2类型,它有三个泛型参数,实际上代表了三个值
   // 第一个泛型类型和第二个泛型类型,代表了原始RDD中的元素的value的类型
   // 因此对每个key进行reduce,都会依次将第一个、第二个value传入,将值再与第三个value传入
   // 因此此处,会自动定义两个泛型类型,代表call()方法的两个传入参数的类型
   // 第三个泛型类型,代表了每次reduce操作返回的值的类型,默认也是与原始RDD的value类型相同的
   // reduceByKey算法返回的RDD,还是JavaPairRDD<key, value>
   JavaPairRDD<String, Integer> totalScores = scores.reduceByKey(

         new Function2<Integer, Integer, Integer>() {

            private static final long serialVersionUID = 1L;

            // 对每个key,都会将其value,依次传入call方法
            // 从而聚合出每个key对应的一个value
            // 然后,将每个key对应的一个value,组合成一个Tuple2,作为新RDD的元素
            @Override
            public Integer call(Integer v1, Integer v2) throws Exception {
               return v1 + v2;
            }

         });

   // 打印totalScores RDD
   totalScores.foreach(new VoidFunction<Tuple2<String,Integer>>() {

      private static final long serialVersionUID = 1L;

      @Override
      public void call(Tuple2<String, Integer> t) throws Exception {
         System.out.println(t._1 + ": " + t._2);
      }

   });

   // 关闭JavaSparkContext
   sc.close();
}


阅读更多
上一篇spark基础transformation
下一篇spark 单词统计
想对作者说点什么? 我来说一句

Spark In Action.pdf

2018年07月03日 8.31MB 下载

Spark In Action

2018年06月06日 2.77MB 下载

Spark_in_Action_Maning英文原版

2017年12月12日 13.92MB 下载

Spark In Action, 2nd Edition

2018年04月21日 9.45MB 下载

Spark 实战 In Action.pdf

2018年05月17日 10.24MB 下载

Spark GraphX in Action 无水印pdf

2017年09月29日 14.74MB 下载

spark DataFrame 操作管理

2018年02月14日 267KB 下载

SparkSQL的jdbc操作及java的api操作

2018年03月19日 98KB 下载

Manning经典教材 Spark in Action

2018年04月19日 10.96MB 下载

Spark Graphx in Action

2016年12月26日 17.19MB 下载

没有更多推荐了,返回首页

关闭
关闭