文章目录
- 介绍
- 核心模块
- Spark Core
- Spark SQL
- Spark Streaming
- Spark MLlib
- Spark GraphX
- 部署
- 命令行
- Web UI
- 提交应用
- Local 模式
- Standalone
- 配置文件
- 添加 JAVA_HOME 环境变量和集群对应的 master 节点
- 启动集群
- 配置历史服务
- 添加日志存储路径
- 添加日志配置
- webui
- 配置高可用
- Yarn模式
- 配置文件
- 配置历史服务器
- 启动历史服务
- webUI
- K8S & Mesos 模式
- windows模式
- 提交任务
- 架构
- Driver
- Executor
- Master & Worker
- ApplicationMaster
- Executor与Core
- 提交流程
- 快速入门
- 来源
介绍
Spark 是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。
Spark 和Hadoop 的根本差异是多个作业之间的数据通信问题 : Spark 多个作业之间数据通信是基于内存,而 Hadoop 是基于磁盘。
核心模块
Spark Core
Spark Core 中提供了 Spark 最基础与最核心的功能,Spark 其他的功能如:Spark SQL,Spark Streaming,GraphX, MLlib 都是在 Spark Core 的基础上进行扩展的
Spark SQL
Spark SQL 是 Spark 用来操作结构化数据的组件。通过 Spark SQL,用户可以使用 SQL或者 Apache Hive 版本的 SQL 方言(HQL)来查询数据。
Spark Streaming
Spark Streaming 是 Spark 平台上针对实时数据进行流式计算的组件,提供了丰富的处理数据流的 API。
Spark MLlib
MLlib 是 Spark 提供的一个机器学习算法库。MLlib 不仅提供了模型评估、数据导入等额外的功能,还提供了一些更底层的机器学习原语。
Spark GraphX
GraphX 是 Spark 面向图计算提供的框架与算法库。
部署
命令行
bin/spark-shell
Web UI
http://虚拟机地址:4040
提交应用
bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master local[2] \
./examples/jars/spark-examples_2.12-3.0.0.jar \
10
-
–class 表示要执行程序的主类,此处可以更换为咱们自己写的应用程序
-
–master local[2] 部署模式,默认为本地模式,数字表示分配的虚拟 CPU 核数量
-
spark-examples_2.12-3.0.0.jar 运行的应用类所在的 jar 包,实际使用时,可以设定为咱们自己打的 jar 包
-
数字 10 表示程序的入口参数,用于设定当前应用的任务数量
Local 模式
直接解压
Standalone
经典的 master-slave 模式
配置文件
添加 work 节点
cd conf
mv slaves.template slaves
vim slaves
linux1
linux2
linux3
添加 JAVA_HOME 环境变量和集群对应的 master 节点
mv spark-env.sh.template spark-env.sh
vim spark-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_144
SPARK_MASTER_HOST=linux1
SPARK_MASTER_PORT=7077
7077 端口,相当于 hadoop3 内部通信的 8020 端口,此处的端口需要确认自己的 Hadoop配置
分发
启动集群
sbin/start-all.sh
配置历史服务
由于 spark-shell 停止掉后,集群监控 linux1:4040 页面就看不到历史任务的运行情况,所以
开发时都配置历史服务器记录任务运行情况。
添加日志存储路径
mv spark-defaults.conf.template spark-defaults.conf
spark.eventLog.enabled true
spark.eventLog.dir hdfs://linux1:8020/directory
需要启动 hadoop 集群,HDFS 上的 directory 目录需要提前存在。
sbin/start-dfs.sh
hadoop fs -mkdir /directory
添加日志配置
vim spark-env.sh
export SPARK_HISTORY_OPTS="
-Dspark.history.ui.port=18080
-Dspark.history.fs.logDirectory=hdfs://linux1:8020/directory
-Dspark.history.retainedApplications=30"
参数 1 含义:WEB UI 访问的端口号为 18080
参数 2 含义:指定历史服务器日志存储路径
参数 3 含义:指定保存 Application 历史记录的个数,如果超过这个值,旧的应用程序
信息将被删除,这个是内存中的应用数,而不是页面上显示的应用数。
分发
重启
webui
http://linux1:18080
配置高可用
所谓的高可用是因为当前集群中的 Master 节点只有一个,所以会存在单点故障问题。所以为了解决单点故障问题,需要在集群中配置多个 Master 节点,一旦处于活动状态的 Master发生故障时,由备用 Master 提供服务,保证作业可以继续执行。这里的高可用一般采用Zookeeper 设置
集群规划
vim spark-env.sh
注释如下内容:
#SPARK_MASTER_HOST=linux1
#SPARK_MASTER_PORT=7077
添加如下内容:
#Master 监控页面默认访问端口为 8080,但是可能会和 Zookeeper 冲突,所以改成 8989,也可以自
定义,访问 UI 监控页面时请注意
SPARK_MASTER_WEBUI_PORT=8989
export SPARK_DAEMON_JAVA_OPTS="
-Dspark.deploy.recoveryMode=ZOOKEEPER
-Dspark.deploy.zookeeper.url=linux1,linux2,linux3
-Dspark.deploy.zookeeper.dir=/spark"
分发
启动zk
启动集群
bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://linux1:7077,linux2:7077 \
./examples/jars/spark-examples_2.12-3.0.0.jar \
10
Yarn模式
配置文件
vim yarn-site.xml
<!--是否启动一个线程检查每个任务正使用的物理内存量,如果任务超出分配值,则直接将其杀掉,默认
是 true -->
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<!--是否启动一个线程检查每个任务正使用的虚拟内存量,如果任务超出分配值,则直接将其杀掉,默认
是 true -->
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
vim spark-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_144
YARN_CONF_DIR=/opt/module/hadoop/etc/hadoop
配置历史服务器
mv spark-defaults.conf.template spark-defaults.conf
vim spark-defaults.conf
spark.eventLog.enabled true
spark.eventLog.dir hdfs://linux1:8020/directory
sbin/start-dfs.sh
hadoop fs -mkdir /directory
vim spark-env.sh
export SPARK_HISTORY_OPTS="
-Dspark.history.ui.port=18080
-Dspark.history.fs.logDirectory=hdfs://linux1:8020/directory
-Dspark.history.retainedApplications=30"
参数 1 含义:WEB UI 访问的端口号为 18080
参数 2 含义:指定历史服务器日志存储路径
参数 3 含义:指定保存 Application 历史记录的个数,如果超过这个值,旧的应用程序
信息将被删除,这个是内存中的应用数,而不是页面上显示的应用数
vim spark-defaults.conf
spark.yarn.historyServer.address=linux1:18080
spark.history.ui.port=18080
启动历史服务
sbin/start-history-server.sh
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
webUI
http://linux2:8088
K8S & Mesos 模式
https://spark.apache.org/docs/latest/running-on-kubernetes.html
windows模式
直接解压
部署模式对比
端口号
Spark 查看当前 Spark-shell 运行任务情况端口号:4040(计算)
➢ Spark Master 内部通信服务端口号:7077
➢ Standalone 模式下,Spark Master Web 端口号:8080(资源)
➢ Spark 历史服务器端口号:18080
➢ Hadoop YARN 任务运行情况查看端口号:8088
提交任务
jps
bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://linux1:7077 \
./examples/jars/spark-examples_2.12-3.0.0.jar \
10
- –class 表示要执行程序的主类
- –master spark://linux1:7077 独立部署模式,连接到 Spark 集群
- spark-examples_2.12-3.0.0.jar 运行类所在的 jar 包
- 数字 10 表示程序的入口参数,用于设定当前应用的任务数量
bin/spark-submit \
--class <main-class>
--master <master-url> \
... # other options
<application-jar> \
[application-arguments]
参数 | 解释 | 可选值举例 |
---|---|---|
–class | Spark 程序中包含主函数的类 | |
–master | Spark 程序运行的模式(环境) | 模式:local[*]、spark://linux1:7077、Yarn |
–total-executor-cores 2 | 指定所有executor使用的cpu核数为 2 个 | 符合集群内存配置即可,具体情况具体分析。 |
–executor-cores | 指定每个executor使用的cpu核数 | |
application-jar | 打包好的应用 jar,包含依赖。这个 URL 在集群中全局可见。 比如 hdfs:// 共享存储系统,如果是file:// path,那么所有的节点的path 都包含同样的 jar | |
application-arguments | 传给 main()方法的参数 |
架构
Driver
master
Spark 驱动器节点,用于执行 Spark 任务中的 main 方法,负责实际代码的执行工作。
Driver 在 Spark 作业执行时主要负责:
➢ 将用户程序转化为作业(job)
➢ 在 Executor 之间调度任务(task)
➢ 跟踪 Executor 的执行情况
➢ 通过 UI 展示查询运行情况
Executor
slave
Spark Executor 是集群中工作节点(Worker)中的一个 JVM 进程,负责在 Spark 作业中运行具体任务(Task),任务彼此之间相互独立。
Spark 应用启动时,Executor 节点被同时启动,并且始终伴随着整个 Spark 应用的生命周期而存在。如果有 Executor 节点发生了
故障或崩溃,Spark 应用也可以继续执行,会将出错节点上的任务调度到其他 Executor 节点
上继续运行。
功能:
➢ 负责运行组成 Spark 应用的任务,并将结果返回给驱动器进程
➢ 它们通过自身的块管理器(Block Manager)为用户程序中要求缓存的 RDD 提供内存
式存储。RDD 是直接缓存在 Executor 进程内的,因此任务可以在运行时充分利用缓存
数据加速运算
Master & Worker
资源调度的功能
Master 是一个进程,主要负责资源的调度和分配,并进行集群的监控等职责,类似于 Yarn 环境中的 RM
Worker 运行在集群中的一台服务器上,由 Master 分配资源对数据进行并行的处理和计算,类似于 Yarn 环境中 NM
ApplicationMaster
Hadoop 用户向 YARN 集群提交应用程序时,提交程序中应该包含 ApplicationMaster,用于向资源调度器申请执行任务的资源容器 Container,运行用户自己的程序任务 job,监控整个任务的执行,跟踪整个任务的状态,处理任务失败等异常情况。
ResourceManager(资源)和 Driver(计算)之间的解耦合靠的就是ApplicationMaster。
Executor与Core
Spark Executor 是集群中运行在工作节点(Worker)中的一个 JVM 进程,是整个集群中
的专门用于计算的节点。在提交应用中,可以提供参数指定计算节点的个数,以及对应的资
源。这里的资源一般指的是工作节点 Executor 的内存大小和使用的虚拟 CPU 核(Core)数
量。
提交流程
Spark 应用程序提交到 Yarn 环境中执行的时候,一般会有两种部署执行的方式:Client(外)
和 Cluster(里面)。两种模式主要区别在于:Driver 程序的运行节点位置。
Yarn Client 模式
快速入门
创建Maven项目
添加Scala插件
scala-maven-plugin 用于在 maven 中编译/测试/运行/记录 scala 代码。
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 该插件用于将 Scala 代码编译成 class 文件 -->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<!-- 声明绑定到 maven 的 compile 阶段 -->
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
WordCount案例
package com.qihang.bigdata.spark.core.wc
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
object WordCount {
def main(args: Array[String]): Unit = {
//Application
//Spark 框架
//TODO 建立和Spark框架连接
val sparConf = new SparkConf().setMaster("local").setAppName("WordCount")
val sc = new SparkContext(sparConf)
//TODO 执行业务逻辑
//读取文件,获取一行一行的数据
//Hello world
//Hello Spark
val lines = sc.textFile("datas")
//拆分成一个一个的单词 扁平化
//hello world hello,world,hello,world
val words = lines.flatMap(_.split(" "))
//按照word分组
//(hello, hello, hello)
val wordGroup: RDD[(String, Iterable[String])] = words.groupBy(word => word)
//转换
//(hello,3)
// val wordToCount: RDD[(String, Int)] = wordGroup.map(
// tuple => (tuple._1, tuple._2.size)
// )
val wordToCount: RDD[(String, Int)] = wordGroup.map{
case ( word, list ) => {
(word, list.size)
}
}
//打印
val array = wordToCount.collect()
array.foreach(println(_))
//TODO 关闭连接
sc.stop()
}
}
执行过程中,会产生大量的执行日志,如果为了能够更好的查看程序的执行结果,可以在项
目的 resources 目录中创建 log4j.properties 文件,并添加日志配置信息:
log4j.rootCategory=ERROR, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd
HH:mm:ss} %p %c{1}: %m%n
# Set the default spark-shell log level to ERROR. When running the spark-shell,
the
# log level for this class is used to overwrite the root logger's log level, so
that
# the user can have different defaults for the shell and regular Spark apps.
log4j.logger.org.apache.spark.repl.Main=ERROR
# Settings to quiet third party logs that are too verbose
log4j.logger.org.spark_project.jetty=ERROR
log4j.logger.org.spark_project.jetty.util.component.AbstractLifeCycle=ERROR
log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=ERROR
log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=ERROR
log4j.logger.org.apache.parquet=ERROR
log4j.logger.parquet=ERROR
# SPARK-9183: Settings to avoid annoying messages when looking up nonexistent
UDFs in SparkSQL with Hive support
log4j.logger.org.apache.hadoop.hive.metastore.RetryingHMSHandler=FATAL
log4j.logger.org.apache.hadoop.hive.ql.exec.FunctionRegistry=ERROR
来源
尚硅谷