一 在 java 客户端创建 Spark 项目
1 打开 IDEA 软件 ,在工具类上 File -->New --> Project ,选择 Maven ,然后下一步将项目名字写成 spark 即可 ,然后 finish 完成项目的创建 .
2 设置 Maven settings file 的位置和 Local respository 的位置 .
3 在 pom.xml 配置文件中添加 spark 相关的依赖和插件
<!-- 定义了一些常量 -->
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<scala.version>2.12.10</scala.version>
<spark.version>3.0.1</spark.version>
<hbase.version>2.2.5</hbase.version>
<hadoop.version>3.2.1</hadoop.version>
<encoding>UTF-8</encoding>
</properties>
<dependencies>
<!-- 导入scala的依赖 -->
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
-------<!-- 编译时会引入依赖,打包是不引入依赖 -->------------
<!-- <scope>provided</scope> -->
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>${spark.version}</version>
-------<!-- 编译时会引入依赖,打包是不引入依赖 -->--------------
<!-- <scope>provided</scope> -->
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<!-- 编译scala的插件 -->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<!-- 编译java的插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>scala-test-compile</id>
<phase>process-test-resources</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 打jar插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
二 Scala 语言编写 Spark 的入门程序(Wordcount)
object ScalaWordCount {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("WordCount").setMaster("local[*]")
------创建 SparkContext
val sparkContext = new SparkContext(conf)
------通过sparkcontext 创建 RDD
------调用sparkcontext 的 textFile 方法,指定以后从哪里读取数据创建RDD
val lines = sparkContext.textFile(args(0))
------调用RDD的Transformation ,将一行行的数据切分压平
val words = lines.flatMap(_.split("\\s+"))
------将words 组装成元组(单词,1)的形式
val wordAndOne = words.map((_, 1))
------对 wordAndOne 进行分组聚合 ,通过key来分组 ,value进行聚合
val reduced = wordAndOne.reduceByKey(_ + _)
------通过value进行排序
val sorted = reduced.sortBy(_._2)
------调用 RDD 的 ACtion 方法开始执行
sorted.saveAsTextFile(args(1))
------释放资源
sparkContext.stop()
}
}
三 Java 语言编写 Spark 的入门程序(Wordcount)
public class JavaWordCount {
public static void main(String[] args) {
SparkConf sc = new SparkConf().setAppName("JavaWordCount").setMaster("local[*]");
JavaSparkContext jsc = new JavaSparkContext(sc);
--------调用source
JavaRDD<String> lines = jsc.textFile(args[0]);
--------对 line进行处理 ,遍历将其进行切割
JavaRDD<String> words = lines.flatMap(new FlatMapFunction<String, String>() {
@Override
public Iterator<String> call(String line) throws Exception {
return Arrays.stream(line.split("\\s+")).iterator();
}
});
-------将得到的单词组装成(单词,1)的形式
JavaPairRDD<String, Integer> wordAndOne = words.mapToPair(new PairFunction<String, String, Integer>() {
@Override
public Tuple2<String, Integer> call(String word) throws Exception {
return Tuple2.apply(word, 1);
}
});
-------将 wordAndOne 进行分组聚合
JavaPairRDD<String, Integer> reduce = wordAndOne.reduceByKey(new Function2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer integer1, Integer integer2) throws Exception {
return integer1 + integer2;
}
});
-----得到(单词,总数)的形式 ,因为排序需要根据次数进行排序,并且排序是按照key进行排序的,
-----所以需要将(单词,总数)转换成 (总数,单词)
JavaPairRDD<Integer, String> countAndWord = reduce.mapToPair(new PairFunction<Tuple2<String, Integer>, Integer, String>() {
@Override
public Tuple2<Integer, String> call(Tuple2<String, Integer> stringIntegerTuple2) throws Exception {
return stringIntegerTuple2.swap();
}
});
-----对 countAndWord 进行排序 ,进行降序排序
JavaPairRDD<Integer, String> sorted = countAndWord.sortByKey(false);
-----拍完序之后再讲元组调换回来,即得到最终结果
JavaPairRDD<String, Integer> result = sorted.mapToPair(new PairFunction<Tuple2<Integer, String>, String, Integer>() {
@Override
public Tuple2<String, Integer> call(Tuple2<Integer, String> integerStringTuple2) throws Exception {
return integerStringTuple2.swap();
}
});
-----将结果进行保存
result.saveAsTextFile(args[1]);
-----释放
jsc.stop();
}
}
四 JavaLambda 语言编写 Spark 的入门程序(Wordcount)
public class JavaLambdaWordCount {
public static void main(String[] args) {
SparkConf conf = new SparkConf().setAppName("JavaLambdaWordCount").setMaster("local[*]");
JavaSparkContext jsc = new JavaSparkContext(conf);
-----读取到文件内容,一行一行的数据
JavaRDD<String> lines = jsc.textFile(args[0]);
-----对读取的文件数据进行处理
JavaRDD<String> words = lines.flatMap(line -> Arrays.stream(line.split("\\s+")).iterator());
-----对单词进行组装成(单词,1)的形式
JavaPairRDD<String, Integer> wordAndOne = words.mapToPair(w -> new Tuple2<>(w, 1));
-----对元组进行聚合
JavaPairRDD<String, Integer> reduce = wordAndOne.reduceByKey((a, b) -> a + b);
-----对聚合元组进行转换 ,方便根据key进行排序
JavaPairRDD<Integer, String> countAndWord = reduce.mapToPair(tp -> tp.swap());
-----排序 ,降序
JavaPairRDD<Integer, String> sorted = countAndWord.sortByKey(false);
-----再讲排序号的元祖转换回来 ,得到最终结果
JavaPairRDD<String, Integer> result = sorted.mapToPair(tp -> tp.swap());
-----将结果进行保存
result.saveAsTextFile(args[1]);
-----释放资源
jsc.stop();
}
}
五 在IDEA上编写的 Spark 的入门程序(Wordcount)在本地运行
1 读取 windows 上的文件运行程序
val conf = new SparkConf().setAppName("WordCount").setMaster("local[*]") 在本地运行时需要加上标红的代码
pom.xml 配置文件中 :
<!-- 编译时会引入依赖,打包时不引入依赖 --> <!-- <scope>provided</scope> -->
所以在本地运行时 ,这个标签需要注释掉,打 jar 包时 ,这个标签需要解注释
在本地运行时 ,在本地获取待处理的数据 ,需要在 main 方法中设置两个参数 ,参数一是文件的输入路径,参数二是文件的输出路径
如果不设置 main 方法上的参数的话 ,会出现以下异常情况 :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at com.java.spark.JavaLambdaWordCount.main(JavaLambdaWordCount.java:18)
2 读取 HDFS 上的文件运行程序
2.1 进行以下设置
System.setProperty("HADOOP_USER_NAME","root"); ------设置权限,写输出结果时使用 root 的身份将数据写到 hdfs 上 SparkConf().setAppName("WordCount").setMaster("local[*]")-----在本地运行时需要加上标红的代码,标注程序是在本地运行
pom.xml 配置文件中 :
<!-- 编译时会引入依赖,打包时不引入依赖 --> <!-- <scope>provided</scope> -->
所以在本地运行时 ,这个标签需要注释掉,打 jar 包时 ,这个标签需要解注释
2.2 在 main 方法参数中指定的的节点上需要有指定的待处理文件 ,而且不能有与输出文件夹相同名字的文件 ,因为待处理文件在被处理完成后 ,生成结果时会自动在 hdfs 上创建跟main方法中参数设置相同名字的文件夹 ,用来装结果文件 .
六 在Linux上的 Spark Shell 交互式命令行客户端写 spark 入门程序并运行
1 将 Spark 集群启动后, 启动 Spark Shell
在 spark 安装包的 sbin 目录下 , 输入 ./start-all.sh 命令 ,启动集群 ,然后在 spark 安装包的 bin 目录下输入以下命令启动 spark shell 客户端 :
./spark-shell --master spark://linux04:7077 --executor-memory 1g --total-executor-cores 3
(spark主节点在linux04机器上)
2 在 spark shell 客户端输入以下逻辑代码 ,注意在 linux04 节点的 hdfs 上的 /wc/ 目录下 ,有待处理的文件
scala> sc.textFile("hdfs://linux03:8020/wc/").flatMap(_.split("\\s+")).map((_,1)).reduceByKey(_+_).collect
(hadoop的主节点在linux03机器上)