Spark简介
Apache Spark是用于大规模数据(large-scala data)处理的统一(unified)分析引擎,其特点就是对任意类型的数据进行自定义计算。
Spark VS Hadoop
尽管Spark相对于Hadoop而言具有较大优势,但Spark并不能完全替代Hadoop
- 在计算层面,Spark相比较MR(MapReduce)有巨大的性能优势,但至今仍有许多计算工具基于MR构架,比如非常成熟的Hive
- Spark仅做计算,而Hadoop生态圈不仅有计算(MR)也有存储(HDFS)和资源管理调度(YARN),HDFS和YARN仍是许多大数据体系的核心架构
面试题:Hadoop的基于进程的计算和Spark基于线程方式优缺点?
答案:Hadoop中的MR中每个map/reduce task都是一个java进程方式运行,好处在于进程之间是互相独立的,每个task独享进程资源,没有互相干扰,监控方便,但是问题在于task之间不方便共享数据,执行效率比较低。比如多个map task读取不同数据源文件需要将数据源加载到每个map task中,造成重复加载和浪费内存。而基于线程的方式计算是为了数据共享和提高执行效率,Spark采用了线程的最小的执行单位,但缺点是线程之间会有资源竞争
Spark四大优点
- 速度快
Spark处理数据与MapReduce处理数据相比,有如下两个不同点:
- 其一、Spark处理数据时,可以将中间处理结果数据存储到内存中;
- 其二、Spark提供了非常丰富的算子(API), 可以做到复杂任务在一个Spark 程序中完成.
- 易于使用
Spark 的版本已经更新到 Spark 3.2.0(截止日期2021.10.13),支持了包括 Java、Scala、Python 、R和SQL语言在内的多种语言。为了兼容Spark2.x企业级应用场景,Spark仍然持续更新Spark2版本。
- 通用性强
在 Spark 的基础上,Spark 还提供了包括Spark SQL、Spark Streaming、MLib 及GraphX在内的多个工具库,我们可以在一个应用中无缝地使用这些工具库。
- 运行方式
Spark 支持多种运行方式,包括在 Hadoop 和 Mesos 上,也支持 Standalone的独立运行模式,同时也可以运行在云Kubernetes(Spark 2.3开始支持)上。
Spark框架模块
整个Spark 框架模块包含:Spark Core、 Spark SQL、 Spark Streaming、 Spark GraphX、 Spark MLlib,而后四项的能力都是建立在核心引擎之上
Spark Core:Spark的核心,Spark核心功能均由Spark Core模块提供,是Spark运行的基础。Spark Core以RDD为数据抽象,提供Python、Java、Scala、R语言的API,可以编程进行海量离线数据批处理计算。
SparkSQL:基于SparkCore之上,提供结构化数据的处理模块。SparkSQL支持以SQL语言对数据进行处理,SparkSQL本身针对离线计算场景。同时基于SparkSQL,Spark提供了StructuredStreaming模块,可以以SparkSQL为基础,进行数据的流式计算。
SparkStreaming:以SparkCore为基础,提供数据的流式计算功能。
MLlib:以SparkCore为基础,进行机器学习计算,内置了大量的机器学习库和API算法等。方便用户以分布式计算的模式进行机器学习计算。
GraphX:以SparkCore为基础,进行图计算,提供了大量的图计算API,方便用于以分布式计算模式进行图计算
Spark的结构角色
Spark运行角色
Spark中由4类角色组成整个Spark的运行时环境
. Master角色,管理整个集群的资源 类比与YARN的ResouceManager
. Worker角色,管理单个服务器的资源 类比于YARN的NodeManager
. Driver角色,管理单个Spark任务在运行的时候的工作 类比于YARN的ApplicationMaster
. Executor角色,单个任务运行的时候的一堆工作者,干活的.类比于YARN的容器内运行的TASK
从2个层面划分:
资源管理层面:
管理者: Spark是Master角色,YARN是ResourceManager。
工作中: Spark是Worker角色,YARN是NodeManager
从任务执行层面:
·某任务管理者: Spark是Driver角色,YARN是ApplicationMaster
·某任务执行者: Spark是Executor角色,YARN是容器中运行的具体工作进程。
Spark的运行模式
- 本地模式(单机)
本地模式就是以一个独立的进程,通过其内部的多个线程来模拟整个Spark运行时环境
- Standalone模式(集群)
Spark中的各个角色以独立进程的形式存在,并组成Spark集群环境
- Hadoop YARN模式(集群)
Spark中的各个角色运行在YARN的容器内部,并组成Spark集群环境
- - Kubernetes模式(容器集群)
Spark中的各个角色运行在Kubernetes的容器内部,并组成Spark集群环境
- -云服务模式(运行在云平台上)
本地模式
本质:启动一个JVM Process进程(一个进程里面有多个线程),执行任务Task
- Local模式可以限制模拟Spark集群环境的线程数量, 即Local[N] 或 Local[*]
- 其中N代表可以使用N个线程,每个线程拥有一个cpu core。如果不指定N,则默认是1个线程(该线程有1个core)。通常Cpu有几个Core,就指定几个线程,最大化利用计算能力.
- 如果是local[*],则代表 Run Spark locally with as many worker threads as logical cores on your machine.按照Cpu最多的Cores设置线程数
Local 下的角色分布:
资源管理:
Master:Local进程本身
Worker:Local进程本身
任务执行:
Driver:Local进程本身
Executor:不存在,没有独立的Executor角色, 由Local进程(也就是Driver)内的线程提供计算能力
Standalone模式
Standalone模式是Spark自带的一种集群模式,不同于前面本地模式启动多个进程来模拟集群的环境,Standalone模式是真实地在多个机器之间搭建Spark集群的环境,完全可以利用该模式搭建多机器集群,用于实际的大数据处理。
StandAlone 是完整的Spark运行环境,其中:
Master角色以Master进程存在, Worker角色以Worker进程存在
Driver和Executor运行于Worker进程内, 由Worker提供资源供给它们运行
StandAlone集群在进程上主要有3类进程:
主节点Master进程:
Master角色, 管理整个集群资源,并托管运行各个任务的Driver
从节点Workers:
Worker角色, 管理每个机器的资源,分配对应的资源来运行Executor(Task);
每个从节点分配资源信息给Worker管理,资源信息包含内存Memory和CPU Cores核数
历史服务器HistoryServer(可选):
Spark Application运行完成以后,保存事件日志数据至HDFS,启动HistoryServer可以查看应用运行相关信息。
搭配环境
Spark基础入门-第三章-3.5-总结_哔哩哔哩_bilibili
启动历史服务器
sbin/start-history-server.sh
启动Spark的Master和Worker进程
# 启动全部master和worker
sbin/start-all.sh
# 或者可以一个个启动:
# 启动当前机器的master
sbin/start-master.sh
# 启动当前机器的worker
sbin/start-worker.sh
# 停止全部
sbin/stop-all.sh
# 停止当前机器的master
sbin/stop-master.sh
# 停止当前机器的worker
sbin/stop-worker.sh
Standalone HA 模式
Spark Standalone集群是Master-Slaves架构的集群模式,和大部分的Master-Slaves结构集群一样,存在着Master 单点故障(SPOF)的问题。
如何解决这个单点故障的问题,Spark提供了两种方案:
1.基于文件系统的单点恢复(Single-Node Recovery with Local File System)--只能用于开发或测试环境。
2.基于zookeeper的Standby Masters(Standby Masters with ZooKeeper)--可以用于生产环境。
ZooKeeper提供了一个Leader Election机制,利用这个机制可以保证虽然集群存在多个Master,但是只有一个是Active的,其他的都是Standby。当Active的Master出现故障时,另外的一个Standby Master会被选举出来。由于集群的信息,包括Worker, Driver和Application的信息都已经持久化到文件系统,因此在切换的过程中只会影响新Job的提交,对于正在进行的Job没有任何的影响。
Spark on Yarn (重点)
Master角色由YARN的ResourceManager担任.
Worker角色由YARN的NodeManager担任.
Driver角色运行在YARN容器内或提交任务的客户端进程中
真正干活的Executor运行在YARN提供的容器内
部署模式DeployMode
Spark On YARN是有两种运行模式的,一种是Cluster模式一种是Client模式. 这两种模式的区别就是Driver运行的位置.
Cluster模式即:Driver运行在YARN容器内部, 和ApplicationMaster在同一个容器内
Client模式即:Driver运行在客户端进程中, 比如Driver运行在spark-submit程序的进程中
Cluster模式:
Client模式:
二者主要区别:
Cluster模式 | Client模式 | |
Driver运行位置 | YARN容器内 | 客户端进程内 |
通讯效率 | 高 | 低于Cluster模式 |
日志查看 | 日志输出在容器内,查看不方便 | 日志输出在客户端的标准输出流中,方便查看 |
生产可用 | 推荐 | 不推荐 |
稳定性 | 稳定 | 基于客户端进程,受到客户端进程影响 |
bin/pyspark --master yarn --deploy-mode client|cluster #
--deploy-mode 选项是指定部署模式, 默认是 客户端模式 # client就是客户端模式 # cluster就是集群模式 # --deploy-mode 仅可以用在YARN模式下
也可以直接运行文件:
bin/spark-submit --master yarn --deploy-mode cluster examples/src/main/python/pi.py 100
此处 --depoly-mode client 用于指定模型,可以不写,默认为client
PySpark
PySpark是一个Python的类库, 提供Spark的操作API
而之前使用的 bin/pyspark 是一个交互式的程序,可以提供交互式编程并执行Spark计算,注意区分
环境配置:
Spark基础入门-第七章-7.1-本机配置Python环境_哔哩哔哩_bilibili
初体验
Spark Application程序入口为:SparkContext,任何一个应用首先需要构建SparkContext对象,如下两步构建:
第一步、创建SparkConf对象
设置Spark Application基本信息,比如应用的名称AppName和应用运行Master
第二步、基于SparkConf对象,创建SparkContext对象
下面是一个demo:
#coding:utf8
from pyspark import SparkConf,SparkContext
if __name__ == '__main__':
conf = SparkConf().setMaster('local[*]').setAppName('LMX')
sc = SparkContext(conf = conf)
file_rdd = sc.textFile("data/input/words.txt")
words_rdd = file_rdd.flatMap(lambda line: line.split(" "))
words_one_rdd = words_rdd.map(lambda x: (x,1))
result_rdd = words_one_rdd.reduceByKey(lambda a,b:a+b)
print(result_rdd.collect())
下面这两句由 driver 运行,然后将虚拟化发送到Executor
conf = SparkConf().setMaster('local[*]').setAppName('LMX')
sc = SparkContext(conf = conf)
Executor读取文件,完成计算,在这个过程中Executor之间可能还会存在shuffle交互
file_rdd = sc.textFile("data/input/words.txt")
words_rdd = file_rdd.flatMap(lambda line: line.split(" "))
words_one_rdd = words_rdd.map(lambda x: (x,1))
result_rdd = words_one_rdd.reduceByKey(lambda a,b:a+b)
最后Executor将结果汇总到driver,print输出
print(result_rdd.collect())
Python on Spark原理
PySpark宗旨是在不破坏Spark已有的运行时架构,在Spark架构外层包装一层Python API,借助Py4j实现Python和 Java的交互,进而实现通过Python编写Spark应用程序,其运行时架构如下图所示
在driver中,会使用 py4j 将python代码转换为java代码,然后由JVM执行Driver程序(因为driver部分的代码很少,是可以做到python和jvm的完全转换的)
在executor中,无法做到完全转换,于是由driver中的JVM向executor中的JVM传到指令,再通过python守护进程调用python程序完成executor程序
所以其实在这个过程中,是由JVM运行Driver程序,而通过python运行executor的。