前提
具备java,spark基本知识
安装,配置要自己能搞定
第一步,加入依赖
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>spark</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.4.5</version>
<!-- 开发编译期间提供,不会打进jar包,节省空间和带宽,运行时环境提供-->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.59</version>
</dependency>
</dependencies>
<!--打包,把依赖包打在一起,俗称胖jar包 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<!-- put your configurations here -->
<mainClass>com.spark.JavaWordCount</mainClass>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
第二步,统计单词功能实现
可以本地直接调试,注意,conf.setMaster("local[2]"); //本地2个工作线程
package com.spark;
import java.util.Arrays;
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 com.alibaba.fastjson.JSON;
import scala.Tuple2;
public class JavaWordCount {
// 统计输入文件单词,并按大小排序
public static void main(String[] args) {
SparkConf conf = new SparkConf();
conf.setAppName("JavaWordCount");
//idea中调试 local 运行在本地计算机
conf.setMaster("local[2]");
JavaSparkContext jsc = new JavaSparkContext(conf);
// 输入文件的路径
JavaRDD<String> lines = jsc.textFile(args[0]);
JavaRDD<String> words = lines.flatMap(line -> Arrays.asList(line.split(" ")).iterator());
JavaPairRDD<String, Integer> tup = words.mapToPair(word -> new Tuple2<>(word, 1));
JavaPairRDD<String, Integer> reduced = tup.reduceByKey((x, y) -> x + y);
JavaPairRDD<Integer, String> swap = reduced.mapToPair(tup2 -> tup2.swap());
JavaPairRDD<Integer, String> sort = swap.sortByKey();
JavaPairRDD<String, Integer> res = sort.mapToPair(tup3 -> tup3.swap());
String json = JSON.toJSONString(res.collect());
System.out.println(json);
// 输出数据的目录,必须是不存在的,程序自动创建
res.saveAsTextFile(args[1]);
jsc.close();
}
}
第三步 打包,集群运行
首先注释掉conf.setMaster("local[2]"); 这一行,准备在集群上运行
以下是运行命令--deploy-mode cluster 不加,就是client模式,
[root@ spark-2.4.5-bin-hadoop2.7]# ./bin/spark-submit \
--class com.spark.JavaWordCount \
--master spark://192.168.8.3:7077 \
--deploy-mode cluster \
--verbose \
/home/app/spark-1.0-SNAPSHOT.jar \
/home/aaa.log \
/home/bbb
问题一,没有信息输出
一定要开启 $SPARK_HOME/conf下面的log4j,复制log4j.properties.template 为log4j.properties,不然错误信息看不到
问题二 class not found
检查打包是否正常 胖jar包
检查--class 是否写了正确的包名和类名
问题三 ERROR executor.CoarseGrainedExecutorBackend: RECEIVED SIGNAL TERM
在web ui控制台可以看日志,有输出此错误信息,但是在application看状态是正常FINISHED
问题原因:
由于使能动态资源分配executors数(spark.dynamicAllocation.enabled=true),因此当executor空闲时间达到 spark.dynamicAllocation.executorIdleTimeout=60s的时间后,executor会被移除掉。
解决办法:
spark.dynamicAllocation.enabled=false,关闭动态分配executors数
或者不用理会这个错误,知道是spark正常的机制即可。