Spark的部署与使用

1 相关概念

Spark 是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。

1.1 与Hadoop区别

Spark与Hadoop中的MapReduce相似,都是用于进行并行计算的框架,二者根本差异是多个作业之间的数据通信问题 : Spark 的多个作业之间数据通信是基于内存,而 Hadoop 是基于磁盘,因此Spark作为MapReduce的升级改进,计算速度会更快。MapReduce 由于其设计初衷并不是为了满足循环迭代式数据流处理,因此在多并行运行的数据可复用场景下效率较低,而spark可以快速在内存中对数据集进行多次迭代,来支持复杂的数据挖掘算法和图形计算算法。此外Spark 采用 fork 线程的方式启动Task,速度更快。

但是 Spark 是基于内存的,所以在实际的生产环境中,由于内存的限制,可能会由于内存资源不够导致 Job 执行失败,此时,MapReduce 其实是一个更好的选择,所以 Spark并不能完全替代 MR。

1.2 组成结构

框架结构

从整体上看,Spark框架由如下几个主要组成部分
在这里插入图片描述

  • Spark Core 中提供了 Spark 最基础与最核心的功能,其他的组成模块都是在 Spark Core 的基础上进行扩展的
  • Spark SQL 是 Spark 用来操作结构化数据的组件。通过 Spark SQL,用户可以使用 SQL或者 Apache Hive SQL 来查询数据。
  • Spark Streaming 是 Spark 平台上针对实时数据进行流式计算的组件,提供了丰富的处理数据流的 API。
  • MLlib 是 Spark 提供的一个机器学习算法库。MLlib 不仅提供了模型评估、数据导入等额外的功能,还提供了一些更底层的机器学习原语
  • GraphX 是 Spark 面向图计算提供的框架与算法库。
核心组件

在这里插入图片描述

Spark 框架的核心是一个计算引擎,从计算的角度,spark可以分为Driver和Executor

  • Driver 是驱使整个应用运行起来的程序,也称之为Driver 类。负责将用户程序转化为作业(job),将任务分配调度给Executor执行,同时跟踪任务执行情况,并将结果通过UI实时反馈给用户。如果有 Executor 节点发生了故障或崩溃,Driver会将出错节点上的任务调度到其他 Executor 节点上继续运行。
  • Executor 是集群中工作节点(Worker)中的一个 JVM 进程,负责在 Spark 作业中运行具体任务(Task),并将结果返回给Driver。另一方面它通过自身的块管理器(Block Manager)为用户程序中要求缓存的 RDD 提供内存式存储

Spark可以单独作为集群进行运行,因此从资源分配的角度,spark可以分为Master和Worker

  • Master 主要负责资源的调度和分配,并进行集群的监控等职责,类似于 Yarn 环境中的 ResourceManager
  • Worker 是数据计算和处理的单元,一个 Worker 运行在集群中的一台服务器上,类似于 Yarn 环境中 NodeManager

ApplicationMaster是任务计算和资源分配之间的连接器,负责向资源调度器申请执行任务的资源容器 Container,运行计算任务 job,监控整个任务的执行,处理任务失败等异常情况。

并行度(Parallelism)

并发是指在一段时间内多个任务同时存在,它们可能在交替执行;而并行是指在某一时刻多个任务在同时执行。由于分布式框架中任务分布在不同的计算节点进行计算,所以能够真正地实现多任务并行执行,将整个集群并行执行任务的数量称之为并行度。

1.3 部署模式

Spark 应用程序提交到 Yarn 环境中执行的时候,一般会有两种部署执行的方式:Client和 Cluster。两种模式主要区别在于:Driver 程序的运行节点位置。

  • Client 模式下将用于监控和调度的 Driver 模块在客户端执行,而不是在 Yarn 中,所以一般用于测试。
  • Cluster 模式将用于监控和调度的 Driver 模块启动在 Yarn 集群资源中执行。一般应用于实际生产环境。

Spark再Yarn上的运行不走如下所示

在这里插入图片描述

  1. 任务提交后会和 ResourceManager 通讯申请启动ApplicationMaster,
  2. 随后 ResourceManager 调度一个 NodeManager 上启动 ApplicationMaster,此时的 ApplicationMaster 就是 Driver。
  3. Driver 启动后向 ResourceManager 申请 Executor 内存,ResourceManager 接到ApplicationMaster 的资源申请后会分配 container,然后在合适的 NodeManager 上启动Executor 进程
  4. Executor 进程启动后会向 Driver 反向注册,Executor 全部注册完成后 Driver 开始执行main 函数,
  5. 之后执行到 Action 算子时,触发一个 Job,并根据宽依赖开始划分 stage,每个 stage 生成对应的 TaskSet,之后将 task 分发到各个 Executor 上执行。

1.4 WordCount

如下是一个经典的wordcount案例。

在Windows本地运行spark需要Hadoop客户端的支持,客户端环境配置如下
https://blog.csdn.net/theVicTory/article/details/124267672#t6

使用IDEA新建一个maven项目,在IDEA中添加Scala插件
在这里插入图片描述
在maven中引入spark插件,这里使用的是Scala版本2.12,spark版本3.0。详细信息可以查看Spark官网https://spark.apache.org/downloads.html

        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.12</artifactId>
            <version>3.0.0</version>
        </dependency>

如下所示读取输入文件word.txt中的内容进行Map 、Reduce操作后将单词统计结果打印出来

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object WordCount {
  def main(args: Array[String]): Unit = {
    // 创建 Spark 运行配置对象,在本地运行
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("WordCount")
    // 创建 Spark 上下文环境对象(连接对象)
    val sc: SparkContext = new SparkContext(sparkConf)
    // 读取文件数据
    val fileRDD: RDD[String] = sc.textFile("/input/word.txt")
    // 将文件中的单词按照空格进行拆分
    val wordRDD: RDD[String] = fileRDD.flatMap(_.split(" "))
    // 将单词转化为键值对 word => (word, 1)
    val word2OneRDD: RDD[(String, Int)] = wordRDD.map((_, 1))
    // 将键值对按照相同的key值进行分组,然后将value值累加
    val word2CountRDD: RDD[(String, Int)] = word2OneRDD.reduceByKey(_ + _)
    // 将数据聚合结果采集到内存中
    val word2Count: Array[(String, Int)] = word2CountRDD.collect()
    // 打印结果
    word2Count.foreach(println)
    //关闭 Spark 连接
    sc.stop()
  }
}

2 运行模式

2.1 单节点模式

单节点Local 模式,就是不需要其他任何节点资源就可以在本地执行 Spark 代码的环境,一般用于调试,演示等。

在spark官网选择和Hadoop、Scala版本相对应的安装包进行下载
在这里插入图片描述
将下载好的安装包解压到/opt/module目录,并在解压后的bin目录下启动spark shell脚本

tar -zxvf spark-3.0.0-bin-hadoop3.2.tgz -C /opt/module
cd /opt/module/spark-3.0.0-bin-hadoop3.2
./bin/spark-shell

之后可以看到spark命令行启动,并且在4040端口可以看到UI交互界面
在这里插入图片描述
通过spark-submit提交jar包任务运行如下所示,其中--class指定执行程序的主类,--master指定部署模式,数字代表分配虚拟CPU核数

./bin/spark-submit /home/tory/wordcount.jar --class com.tory.spark.WordCount --master local[2]

2.2 独立集群模式

Spark独立组建集群模式(Standalone),即将应用提交到对应的集群中去执行。这里使用三台主机当作Worker,其中一台主机当作master来组建集群。

集群配置

将spark文件解压后先修改spark的节点配置文件,将conf/slaves.template重命名为slaves,然后在其中添加work节点的主机位置。这里的主机名已经作了IP映射,所以可以直接写主机名

hadoop102
hadoop103
hadoop104

之后修改spark环境配置文件,将conf/spark-env.sh.template 重命名为 spark-env.sh,并在文件末尾添加如下内容,设置Java路径、master节点和spark端口号。这里已经为每个节点安装好了Java环境,命令行通过echo $JAVA_HOME可以看到其安装路径。

export JAVA_HOME=/opt/module/jdk1.8.0_144
SPARK_MASTER_HOST=hadoop102
SPARK_MASTER_PORT=7077

通过sync命令将配置好的spark文件分发到其他节点。为了便于在节点之间进行文件同步,可以将该命令封装为一个脚本mysync,过程记录在:https://blog.csdn.net/theVicTory/article/details/124095680?spm=1001.2014.3001.5501#t10

mysync /opt/module/spark

启动集群

sbin/start-all.sh

在Master节点的8080端口可以看到集群运行情况
在这里插入图片描述

提交任务

通过spark-submit向集群提交任务。这里运行的是spark/examples目录下的样例文件spark-examples中的求PI任务SparkPi。通过参数--class指定任务的主类,通过--master指定任务提交到主机hadoop102的7077端口。最后10是程序入口参数。

bin/spark-submit
 --class org.apache.spark.examples.SparkPi 
 --master spark://hadoop102:7077 
 ./examples/jars/spark-examples_2.12-3.0.0.jar 
 10

提交任务时,还可以通过参数指定Executor 的内存大小和使用的虚拟 CPU 核(Core)数量

参数说明
–num-executors配置 Executor 的数量
–executor-memory配置每个 Executor 的内存大小
–executor-cores配置每个 Executor 的虚拟 CPU core 数量
历史服务

通过配置历史服务器可以记录任务运行情况

首先将spark/conf下的配置文件spark-defaults.conf.template修改为spark-defaults.conf,在其中开启日志服务并配置日志存储位置为hdfs文件系统的/directory目录(这里hdfs地址在hadoop102节点的8020端口),因此需要启动Hadoop集群并创建该目录

spark.eventLog.enabled true
spark.eventLog.dir hdfs://hadoop102:8020/directory

之后在spark-env.sh文件中添加日志的配置,将UI端口设为18080,并设置日志位置,最后设置最大日志记录个数为30

export SPARK_HISTORY_OPTS="
-Dspark.history.ui.port=18080 
-Dspark.history.fs.logDirectory=hdfs://hadoop102:8020/directory 
-Dspark.history.retainedApplications=30"

分发修改后的配置文件并重启集群

cd /opt/module/spark
mysync conf

sbin/stop-all.sh
sbin/start-all.sh
sbin/start-history-server.sh

此时,执行任务后就可以在18080端口看到历史日志了:http://hadoop102:18080/
在这里插入图片描述

Master备用节点

为了防止Master节点挂掉后集群异常,通过Zookeeper来配置备用Master节点来提高集群的可用性

首先停止spark集群并启动集群的zookeeper服务。

修改spark-env.sh,在其中首先注释掉之前spark master相关设置;修改WEBUI端口防止和zookeeper冲突;最后配置zookeeper高可用

#SPARK_MASTER_HOST=hadoop102
#SPARK_MASTER_PORT=7077

# 修改监控页面默认访问端口,防止冲突,所以改成 8989
SPARK_MASTER_WEBUI_PORT=8989

# 配置Zookeeper高可用
export SPARK_DAEMON_JAVA_OPTS="
-Dspark.deploy.recoveryMode=ZOOKEEPER 
-Dspark.deploy.zookeeper.url=hadoop102,hadoop103,hadoop104
-Dspark.deploy.zookeeper.dir=/spark"

将上面的配置文件同步到其他几点。

在当前节点启动集群,则当前节点hadoop103就会被当作master

[tory@hadoop103 spark]$ sbin/start-all.sh

在这里插入图片描述

再在hadoop104上单独启动一个Master节点,可以看到这个节点处于备用状态STANDBY,当我们手动杀死当前Master节点后,备用节点的状态就会变为ALIVE,从而保证了集群的高可用。

[root@linux2 spark-standalone]# sbin/start-master.sh

在这里插入图片描述

2.3 Yarn集群

独立部署(Standalone)模式由 Spark 自身提供计算资源,无需其他框架独立运行。这种方式降低了和其他第三方资源框架的耦合性,独立性非常强。但是Spark 主要是计算框架,本身提供的资源调度并不是它的强项,所以一般会和资源调度框架YARN集成使用。

由于yarn在运行中会对虚拟内存进行检查,从而关闭节点任务,导致spark运行报错如下

ERROR cluster.YarnClientSchedulerBackend: YARN application has exited unexpectedly with state UNDEFINED! Check the YARN application logs for more details.
ERROR cluster.YarnClientSchedulerBackend: Diagnostics message: Shutdown hook called before final status was reported.

为了使节点正常运行,需要在配置文件yarn-site.xml中关闭内存检查

	<!-- 关闭物理内存使用量的检查 -->
	<property>
		<name>yarn.nodemanager.pmem-check-enabled</name>
		<value>false</value>
	</property>
	<!-- 关闭虚拟内存使用量的检查 -->
	<property>
		<name>yarn.nodemanager.vmem-check-enabled</name>
		<value>false</value>
	</property>

spark-env.sh文件在Standalone模式的基础上添加YARN配置文件目录,最终效果如下

export JAVA_HOME=/opt/module/jdk1.8.0_321
# SPARK_MASTER_HOST=hadoop102
# SPARK_MASTER_PORT=7077

# 修改监控页面默认访问端口,防止冲突,所以改成 8989
SPARK_MASTER_WEBUI_PORT=8989

# 配置Zookeeper高可用
export SPARK_DAEMON_JAVA_OPTS="
-Dspark.deploy.recoveryMode=ZOOKEEPER 
-Dspark.deploy.zookeeper.url=hadoop102,hadoop103,hadoop104
-Dspark.deploy.zookeeper.dir=/spark"

# 历史服务配置
export SPARK_HISTORY_OPTS="
-Dspark.history.ui.port=18080 
-Dspark.history.fs.logDirectory=hdfs://hadoop102:8020/directory 
-Dspark.history.retainedApplications=30"

# yarn配置文件目录
YARN_CONF_DIR=/opt/module/hadoop-3.1.3/etc/hadoop

如果需要开启yarn的spark历史服务记录,修改conf/spark-default.conf文件如下。和standalone模式的历史服务配置一样,需要保证hdfs上的/directory目录存在

spark.eventLog.enabled true
spark.eventLog.dir hdfs://hadoop102:8020/directory

spark.yarn.historyServer.address=hadoop102:18080
spark.history.ui.port=18080

之后启动Hadoop集群,保证HDFS和Yarn正常运行。

启动spark的历史服务sbin/start-history-server.sh

提交任务如下,通过--master指定提交到yarn集群,--deploy-mode 指定提交的模式为客户端模式

bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode client \
./examples/jars/spark-examples_2.12-3.0.0.jar \
10

运行结束后可以在yarn集群管理页面看到任务运行结果
在这里插入图片描述点击任务的Tracking UI一栏下面的History按钮可以跳转到Spark的历史服务记录页面
在这里插入图片描述

2.4 Windows

Spark也提供了直接在Windows下运行环境

双击spark目录下的bin/spark-shell.cmd,可以看到spark命令行启动,和2.1单节点中的命令行一样
在这里插入图片描述
同样也可以进行任务提交,在spark的bin目录下打开Windows命令行工具,通过spark-submit提交任务

D:\Temp\spark-3.0.0-bin-hadoop3.2\bin>spark-submit --class org.apache.spark.examples.SparkPi --master local[2] ../examples/jars/spark-examples_2.12-3.0.0.jar 10
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值