写在前面
说明
Spark可以独立安装试使用,也可以和Hadoop一起安装使用。本文为配合Hadoop使用,这样就可以让Spark使用HDFS存取数据。
组件版本
- CentOS 7.9.2009
- Hadoop 2.10.1
- JDK 1.8
- Spark 3.1.1
相关组件安装
下面贴出上述组件安装博客,方便有需要的读者。
本例中,我们不再赘述其他组件的安装。在开始安装Spark前,我们使用安装Hadoop时创建的hadoop用户。
Spark安装
访问Spark官方下载地址,由于我们自己安装过hadoop,所以直接下载无Hadoop的Spark即可。
Spark部署模式主要有四种:Local模式(单机模式)、Standalone模式(使用Spark自带的简单集群管理器)、YARN模式(使用YARN作为集群管理器)和Mesos模式(使用Mesos作为集群管理器)。
本文介绍以hadoop用户进行Local模式(单机模式)的Spark安装。
# 进入到用户家目录
cd ~
# 解压到用户家目录
tar -zxf spark-3.1.1-bin-without-hadoop.tgz -C ./
# 文件重命名
mv ./spark-3.1.1-bin-without-hadoop ./spark
修改Spark的配置文件spark-env.sh
# 从模板文件复制
cp spark/conf/spark-env.sh.template spark/conf/spark-env.sh
# 编辑文件内容
vim spark/conf/spark-env.sh
在第一行添加配置(/usr/local/hadoop/bin/hadoop为你安装的hadoop目录下的bin/hadoop路径)
export SPARK_DIST_CLASSPATH=$(/usr/local/hadoop/bin/hadoop classpath)
有了上述配置之后,Spark就能从HDFS中读取和存取数据。
通过运行Spark自带的示例,测试是否安装成功。
spark/bin/run-example SparkPi
执行时会输出非常多的运行信息,输出结果不容易找到,可以通过 grep 命令进行过滤(命令中的 2>&1 可以将所有的信息都输出到 stdout 中,否则由于输出日志的性质,还是会输出到屏幕中)
spark/bin/run-example SparkPi 2>&1 | grep "Pi is"
Spark Shell
Spark shell 提供了简单的方式来学习 API,并且提供了交互的方式来分析数据。你可以输入一条语句,Spark shell会立即执行语句并返回结果,这就是我们所说的REPL(Read-Eval-Print Loop,交互式解释器),为我们提供了交互式执行环境,表达式计算完成就会输出结果,而不必等到整个程序运行完毕,因此可即时查看中间结果,并对程序进行修改,这样可以在很大程度上提升开发效率。
Spark Shell 支持 Scala 和 Python,这里使用 Scala 来进行介绍。
spark-shell命令及其常用的参数如下:
./bin/spark-shell --master <master-url>
Spark的运行模式取决于传递给SparkContext的Master URL的值。Master URL可以是以下任一种形式:
- local 使用一个Worker线程本地化运行SPARK(完全不并行)。
- local[*] 使用逻辑CPU个数数量的线程来本地化运行Spark。
- local[K] 使用K个Worker线程本地化运行Spark(理想情况下,K应该根据运行机器的CPU核数设定)。
- spark://HOST:PORT 连接到指定的Spark standalone master。默认端口是7077。
- yarn-client 以客户端模式连接YARN集群。集群的位置可以在HADOOP_CONF_DIR 环境变量中找到。
- yarn-cluster 以集群模式连接YARN集群。集群的位置可以在HADOOP_CONF_DIR 环境变量中找到。
- mesos://HOST:PORT 连接到指定的Mesos集群。默认接口是5050。
在Spark中采用本地模式启动Spark Shell的命令主要包含以下参数:
–master:这个参数表示当前的Spark Shell要连接到哪个master,如果是local[*],就是使用本地模式启动spark-shell,其中,中括号内的星号表示需要使用几个CPU核心(core);
–jars: 这个参数用于把相关的JAR包添加到CLASSPATH中;如果有多个jar包,可以使用逗号分隔符连接它们;
比如,要采用本地模式,在4个CPU核心上运行spark-shell:
spark/bin/spark-shell --master local[4]
或者,可以在CLASSPATH中添加code.jar,命令如下:
spark/bin/spark-shell --master local[4] --jars code.jar
可以执行“spark-shell –help”命令,获取完整的选项列表,具体如下:
spark/bin/spark-shell --help
启动spark-shell:
spark/bin/spark-shell
此时未携带参数,默认为spark/bin/spark-shell --master local[*]。即为采用本地模式运行,并且使用本地所有核心。
现在就可以输入scala代码进行调试了。
举一个最简单的例子,输入3+2-5*0,然后回车,就会立即得到结果:
最后,可以使用命令:quit
退出Spark Shell。
Java独立应用编程
创建项目
创建一个maven项目,引入以下依赖:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>3.1.1</version>
</dependency>
完整pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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>cn.javayuli</groupId>
<artifactId>spark-project</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>Akka repository</id>
<url>http://repo.akka.io/releases</url>
</repository>
</repositories>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.spark/spark-core -->
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>3.1.1</version>
</dependency>
</dependencies>
</project>
项目结构:
编写主类
Spark应用程序SimpleApp.java:
package cn.javayuli;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
/**
* @author 14516
*/
public class SimpleApp {
public static void main(String[] args) {
// String logFile = "file:///home/hadoop/spark/README.md";
String logFile = args[0];
JavaSparkContext sparkContext = new JavaSparkContext("local", "Simple App", "file:///home/hadoop/spark", new String[]{"sparkapp/spark-project-1.0.jar"});
JavaRDD<String> logData = sparkContext.textFile(logFile).cache();
long numAs = logData.filter((s) -> s.contains("a")).count();
long numBs = logData.filter((s) -> s.contains("b")).count();
System.out.println("Lines with a: " + numAs + ", lines with b: " + numBs);
}
}
其中logFile
是读取文件的路径,我这里是获取的传进来的参数。
将项目通过mvn package
打包成jar文件
传输文件
在centos hadoop用户的家目录中,创建一个sparkapp文件夹
cd ~
mkdir sparkapp
再用xftp或者其他工具将jar文件复制到centos服务器上,放在/home/hadoop/sparkapp/下
运行程序
通过spark-submit运行程序,该命令格式如下:
spark/bin/spark-submit
--class <main-class> //需要运行的程序的主类,应用程序的入口点
--master <master-url> //Master URL,下面会有具体解释
--deploy-mode <deploy-mode> //部署模式
... # other options //其他参数
<application-jar> //应用程序JAR包
[application-arguments] //传递给主类的主方法的参数
deploy-mode这个参数用来指定应用程序的部署模式,部署模式有两种:client和cluster,默认是client。当采用client部署模式时,就是直接在本地运行Driver Program,当采用cluster模式时,会在Worker节点上运行Driver Program。比较常用的部署策略是从网关机器提交你的应用程序,这个网关机器和你的Worker集群进行协作。在这种设置下,比较适合采用client模式,在client模式下,Driver直接在spark-submit进程中启动,这个进程直接作为集群的客户端,应用程序的输入和输出都和控制台相连接。因此,这种模式特别适合涉及REPL的应用程序。另一种选择是,如果你的应用程序从一个和Worker机器相距很远的机器上提交,那么采用cluster模式会更加合适,它可以减少Driver和Executor之间的网络迟延。
Spark的运行模式取决于传递给SparkContext的Master URL的值。Master URL可以是以下任一种形式:
- local 使用一个Worker线程本地化运行SPARK(完全不并行)
- local[*] 使用逻辑CPU个数数量的线程来本地化运行Spark
- local[K] 使用K个Worker线程本地化运行Spark(理想情况下,K应该根据运行机器的CPU核数设定)
- spark://HOST:PORT 连接到指定的Spark standalone master。默认端口是7077.
- yarn-client 以客户端模式连接YARN集群。集群的位置可以在HADOOP_CONF_DIR 环境变量中找到。
- yarn-cluster 以集群模式连接YARN集群。集群的位置可以在HADOOP_CONF_DIR 环境变量中找到。
- mesos://HOST:PORT 连接到指定的Mesos集群。默认接口是5050。
最后,针对上面编译打包得到的应用程序,可以通过将生成的jar包通过spark-submit提交到Spark中运行,如下命令:
spark/bin/spark-submit --class "cn.javayuli.SimpleApp" ./sparkapp/spark-project-1.0.jar "file:///home/hadoop/spark/README.md"
file:///home/hadoop/spark/README.md
为cn.javayuli.SimpleApp类中接收的一个参数,即目标文件位置。
使用如上命令会在控制台输出很多内容,可以简化内容输出:
spark/bin/spark-submit --class "cn.javayuli.SimpleApp" ./sparkapp/spark-project-1.0.jar "file:///home/hadoop/spark/README.md" 2>&1 | grep "Lines with a"
最后得到的结果:
Lines with a: 64, lines with b: 32