Spark-java版

SparkContext初始化

相关知识
  • SparkConf 是SparkContext的构造参数,储存着Spark相关的配置信息,且必须指定Master(比如Local)和AppName(应用名称),否则会抛出异常;
  • SparkContext 是程序执行的入口,一个SparkContext代表一个 Application
初始化过程的主要核心:
  1. 依据SparkConf创建一个Spark执行环境SparkEnv
  2. 创建并初始化Spark UI,方便用户监控,默认端口为 4040
  3. 设置Hadoop相关配置及Executor环境变量;
  4. 创建和启动TaskSchedulerDAGScheduler
初始化方式:
  1. SparkConf conf = new SparkConf().setAppName(appName).setMaster(master)
  2. JavaSparkContext sc=new JavaSparkContext(conf)

程序运行完后需使用sc.stop()关闭SparkContext
 

import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.SparkConf;
import java.util.Arrays;
import java.util.List;

public class Edu {
    public static void main(String[] args) {
        /********** Begin **********/
        //第一步:设置SparkConf
        SparkConf conf = new SparkConf().setAppName("educoder").setMaster("local");
        //第二步:初始化SparkContext
       JavaSparkContext sc = new JavaSparkContext(conf);
        /********** End **********/
        
        List<String> data = Arrays.asList("hello");
        JavaRDD<String> r1 = sc.parallelize(data);
        System.out.print(r1.collect());
        
		/********** Begin **********/
        //第三步:关闭SparkContext
       sc.stop();
        /********** End **********/

    }
}

集合并行化创建RDD

任务描述

本关任务:计算并输出各个学生的总成绩。

相关知识

为了完成本关任务,你需要掌握:1.集合并行化创建RDD,2.reduceByKey

集合创建RDD

Spark会将集合中的数据拷贝到集群上去,形成一个分布式的数据集合,也就是一个RDD。相当于是,集合中的部分数据会到一个节点上,而另一部分数据会到其他节点上。然后就可以用并行的方式来操作这个分布式数据集合,即RDD
 

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
  1. JavaRDD<Integer> rdd = sc.parallelize(list,3);//参数1:Seq集合,必须。参数2:分区数,默认为该Application分配到的资源的CPU核数
  2. Integer sum = rdd.reduce((a, b) -> a + b);
  3. System.out.print(sum);

输出:6

reduceByKey()

对元素为RDD[K,V]对的RDDKey相同的元素的Value进行聚合。

List<Tuple2<String,Integer>> list = Arrays.asList(new Tuple2("hive",2),new Tuple2("spark",4),new Tuple2("hive",1));
JavaPairRDD<String, Integer> listRDD = sc.parallelizePairs(list);
List<Tuple2<String, Integer>> result = listRDD.reduceByKey((x, y) -> x + y).collect();

输出: (spark,4) (hive,3)

collect() :以数组的形式返回RDD中的所有元素,收集分布在各个worker的数据到driver节点。

编程要求

根据提示,在右侧编辑器begin-end处补充代码,计算并输出各个学生的总成绩。

  • ("bj",88): bj指学生姓名,88指学生成绩。
测试说明

平台会对你编写的代码进行测试:

预期输出: (bj,254) (sh,221) (gz,285)
 

package step1;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaSparkContext;
import scala.Tuple2;
import java.util.*;
public class JStudent {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf().setMaster("local").setAppName("JStudent");
        JavaSparkContext sc = new JavaSparkContext(conf);
        List<Tuple2<String,Integer>> list = Arrays.asList(
             new Tuple2("bj",88),new Tuple2("sh",67),
             new Tuple2("gz",92),new Tuple2("bj",94),
             new Tuple2("sh",85),new Tuple2("gz",95),
             new Tuple2("bj",72),new Tuple2("sh",69),
             new Tuple2("gz",98));
        //第一步:创建RDD
        JavaPairRDD<String, Integer> listRDD = sc.parallelizePairs(list);
        //第二步:把相同key的进行聚合
        JavaPairRDD<String, Integer> result = listRDD.reduceByKey((x, y) -> x + y);
        //第三步:收集
        List<Tuple2<String, Integer>> collect = result.collect();
        //第四步:输出
        for (Tuple2 c:collect){
            System.out.println(c);
        }
        sc.stop();
    }
}

读取外部数据集创建RDD
 

任务描述

本关任务:读取文本文件,按照文本中数据,输出老师及其出现次数。

相关知识

为了完成本关任务,你需要掌握:1.读取文件创建RDD,2.本关所需算子。

读取文件

textFile()

JavaRDD<String> rdd = sc.textFile("/home/student.txt")//文件路径
算子

(1)mapToPair:此函数会对一个RDD中的每个元素调用f函数,其中原来RDD中的每一个元素都是T类型的,调用f函数后会进行一定的操作把每个元素都转换成一个<K2,V2>类型的对象

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
JavaRDD<Integer> rdd = sc.parallelize(list);
JavaPairRDD<Integer,String> result = rdd.mapToPair(x -> new Tuple2(x,1)

输出:(1,1)(2,1)(3,1)

(2) reduceByKey() :对元素为RDD[K,V]对的RDDKey相同的元素的Value进行聚合

List<Tuple2<String,Integer>> list = Arrays.asList(new Tuple2("hive",2),new Tuple2("spark",4),new Tuple2("hive",1));
JavaPairRDD<String, Integer> listRDD = sc.parallelizePairs(list);
List<Tuple2<String, Integer>> result = listRDD.reduceByKey((x, y) -> x + y).collect();

输出: (spark,5) (hive,3)

编程要求

根据提示,在右侧编辑器begin-end处补充代码,输出老师姓名和出现次数。

  • 输入文件样例:

bigdata,laozhang bigdata,laoduan javaee,xiaoxu

bigdata指科目,laozhang指老师名称。

预期输出: (laoliu,1) (laoli,3) (laoduan,5) (laozhang,2) (laozhao,15) (laoyang,9) (xiaoxu,4)
 

package step2;

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 scala.Tuple2;

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

public class JTeachers {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf().setMaster("local").setAppName("JTeachers");
        JavaSparkContext sc = new JavaSparkContext(conf);
        String dataFile = "file:///root/step2_files";
              //第一步:以外部文件方式创建RDD
        JavaRDD<String> teaRDD = sc.textFile(dataFile);
        //String name = line.split(",")[1];
        //第二步:将文件中每行的数据切分,得到自己想要的返回值
        Integer one = 1;
        JavaPairRDD<String, Integer> teacher = teaRDD.mapToPair(line ->{
            String names = line.split(",")[1];
            Tuple2<String, Integer> t2 = new Tuple2<>(names, one);
            return t2;
        });
        //第三步:将相同的key进行聚合
        JavaPairRDD<String, Integer> tea = teacher.reduceByKey((x, y) -> x + y);
        //第四步:将结果收集起来
        List<Tuple2<String, Integer>> result = tea.collect();
        //第五步:输出
        for (Tuple2 t:result){
            System.out.println(t);
        }
        sc.stop();
    }
}

map算子完成转换操作

相关知识

为了完成本关任务,你需要掌握:如何使用map算子。

map

将原来RDD的每个数据项通过map中的用户自定义函数f映射转变为一个新的元素。

图中每个方框表示一个RDD分区,左侧的分区经过自定义函数f:T->U映射为右侧的新RDD分区。但是,实际只有等到Action算子触发后,这个f函数才会和其他函数在一个Stage中对数据进行运算。

map 案例
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
System.out.println("init:" + list);
JavaRDD<Integer> rdd = sc.parallelize(list);
JavaRDD<Integer> map = rdd.map(x -> x * 2);
System.out.println("result :" + map.collect());

输出:

init :[1, 2, 3, 4, 5, 6] result :[2, 4, 6, 8, 10, 12]

说明:rdd1的元素(1 , 2 , 3 , 4 , 5 , 6)经过map算子(x -> x*2)转换成了rdd2(2 , 4 , 6 , 8 , 10)

编程要求

根据提示,在右侧编辑器begin-end处补充代码,完成以下需求:

需求1:使用map算子,将rdd的数据(1, 2, 3, 4, 5)按照下面的规则进行转换操作,规则如下:

  • 偶数转换成该数的平方;

  • 奇数转换成该数的立方。

需求2:使用map算子,将rdd的数据("dog", "salmon", "salmon", "rat", "elephant")按照下面的规则进行转换操作,规则如下:

  • 将字符串与该字符串的长度组合成一个元组,例如
  1. dog --> (dog,3)
  2. salmon --> (salmon,6)
    package net.educoder;
    import org.apache.spark.SparkConf;
    import org.apache.spark.api.java.JavaRDD;
    import org.apache.spark.api.java.JavaSparkContext;
    import scala.Tuple2;
    import java.util.Arrays;
    import java.util.List;
    public class Step1 {
        private static SparkConf conf;
        private static JavaSparkContext sc;
        static {
            conf = new SparkConf().setAppName("Step1").setMaster("local");
            sc = new JavaSparkContext(conf);
        }
        /**
         * 返回JavaRDD
         *
         * @return JavaRDD
         */
        public static JavaRDD<Integer> MapRdd() {
            List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
            JavaRDD<Integer> rdd = sc.parallelize(list);
            /**
             *
             * 需求:使用map算子,将rdd的数据进行转换操作
             * 规则如下:
             *      偶数转换成该数的平方
             *      奇数转换成该数的立方
             *
             */
            /********** begin ***********/
            JavaRDD<Integer> map = rdd.map(num -> {
                if (num % 2 == 0) {
                    return num * num;
                } else {
                    return num * num * num;
                }
            });
            return map;
            /********** end ***********/
        }
        /**
         * 返回JavaRDD
         *
         * @return JavaRDD
         */
        public static JavaRDD<Tuple2> MapRdd2() {
            List<String> list = Arrays.asList("dog", "salmon", "salmon", "rat", "elephant");
            JavaRDD<String> rdd = sc.parallelize(list);
            /**
             *
             * 需求:使用map算子,将rdd的数据进行转换操作
             * 规则如下:
             *      将字符串与该字符串的长度组合成一个元组,例如:dog  -->  (dog,3),salmon   -->  (salmon,6)
             *
             */
           /********** begin ***********/
            JavaRDD<Tuple2> map = rdd.map(str -> {
                int i = str.length();
                return new Tuple2(str, i);
            });
            return map;
           /********** end ***********/
        }
    }

### Spark算子在JAVA命令行中的使用方法及相关示例 以下是关于如何在 Java 命令行环境中使用 Spark 算子的相关说明以及具体示例: #### 1. 配置开发环境 为了能够在命令行中运行基于 JavaSpark 应用程序,首先需要完成以下准备工作: - 安装 JDK 和 Maven 工具。 - 创建一个 Maven 项目并引入必要的依赖项。 Maven `pom.xml` 文件应包含如下依赖项以支持 Spark 功能[^1]: ```xml <dependencies> <!-- Apache Spark Core --> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_2.12</artifactId> <version>3.0.0</version> </dependency> <!-- Logging Dependencies (Optional but recommended) --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.30</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.30</version> </dependency> </dependencies> ``` #### 2. 编写 Java 程序 下面是一个简单的 WordCount 示例,展示如何通过 Java 使用 Spark 提供的算子来处理数据集[^2]: ```java 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 java.util.Arrays; import java.util.List; import scala.Tuple2; public class SparkWordCount { public static void main(String[] args) { // 初始化 Spark 配置和上下文 SparkConf conf = new SparkConf() .setAppName("JavaWordCountExample") .setMaster("local"); // 设置本地模式运行 try (JavaSparkContext sc = new JavaSparkContext(conf)) { // 准备输入数据 List<String> data = Arrays.asList( "hello spark", "hello world", "word count example" ); JavaRDD<String> lines = sc.parallelize(data); // 执行 map-reduce 流程 JavaRDD<String> words = lines.flatMap(line -> Arrays.asList(line.split("\\s+")).iterator()); JavaPairRDD<String, Integer> wordPairs = words.mapToPair(word -> new Tuple2<>(word, 1)); JavaPairRDD<String, Integer> wordCounts = wordPairs.reduceByKey((a, b) -> a + b); // 输出结果到控制台 System.out.println("Word counts:"); wordCounts.foreach(tuple -> System.out.println(tuple._1() + ": " + tuple._2())); } } } ``` 此代码片段展示了如何利用 Spark 中的核心算子(如 `flatMap`, `mapToPair`, 和 `reduceByKey`),从而实现单词计数功能。它还演示了如何初始化 Spark 上下文,并将字符串列表作为输入源进行分布式计算[^2]。 #### 3. 构建与执行应用程序 构建该应用可以借助 Maven 来完成编译打包操作,在项目的根目录下运行以下命令即可生成可执行 JAR 文件[^1]: ```bash mvn clean package -DskipTests=true ``` 随后可以通过提交脚本启动 Spark Job,例如在本地测试环境下可以直接调用 `spark-submit` 命令[^3]: ```bash spark-submit --class com.example.SparkWordCount \ --master local \ target/your-application-name.jar ``` 这里需要注意的是替换路径参数为实际生成 jar 包的位置信息。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qq_58647543

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

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

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

打赏作者

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

抵扣说明:

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

余额充值