写在前面

说明

Spark可以独立安装试使用,也可以和Hadoop一起安装使用。本文为配合Hadoop使用,这样就可以让Spark使用HDFS存取数据。

组件版本

  • CentOS 7.9.2009
  • Hadoop 2.10.1
  • JDK 1.8
  • Spark 3.1.1

相关组件安装

下面贴出上述组件安装博客,方便有需要的读者。

  • VMware安装Centos7并联网使用
  • 分布式处理框架Hadoop的安装与使用

本例中,我们不再赘述其他组件的安装。在开始安装Spark前,我们使用安装Hadoop时创建的hadoop用户。

Spark安装

访问Spark官方下载地址,由于我们自己安装过hadoop,所以直接下载无Hadoop的Spark即可。

spark打包pom插件配置 spark pop3_大数据

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打包pom插件配置 spark pop3_spark打包pom插件配置_02

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[*]。即为采用本地模式运行,并且使用本地所有核心。

spark打包pom插件配置 spark pop3_分布式_03

现在就可以输入scala代码进行调试了。

举一个最简单的例子,输入3+2-5*0,然后回车,就会立即得到结果:

spark打包pom插件配置 spark pop3_分布式_04

最后,可以使用命令:quit退出Spark Shell。

spark打包pom插件配置 spark pop3_大数据_05

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打包pom插件配置 spark pop3_spark_06

编写主类

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文件

spark打包pom插件配置 spark pop3_hadoop_07

传输文件

在centos hadoop用户的家目录中,创建一个sparkapp文件夹

cd ~
mkdir sparkapp

再用xftp或者其他工具将jar文件复制到centos服务器上,放在/home/hadoop/sparkapp/下

spark打包pom插件配置 spark pop3_分布式_08

运行程序

通过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"

spark打包pom插件配置 spark pop3_spark打包pom插件配置_09

最后得到的结果:

Lines with a: 64, lines with b: 32