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();
}


阅读更多
想对作者说点什么? 我来说一句

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