说明:该章节讲述spark的理论概念和简单的操作,这部分我们只需要做到明确概念就行,把学习重心放在后面的方法掌握和应用。
Spark的基本概念
定义
大规模数据处理的统一分析引擎。
基于内存的分布式计算框架
RDD是一种分布式的内存抽象,RDD的内存运算给Spark带来了非常强大的计算性能
框架
Hadoop和Spark的区别
Hadoop Spark
类型 | 基础平台,包含计算,存储,调度 | 纯计算式工具 |
场景 | 海量数据批处理(磁盘迭代计算) | 海量数据的批处理、海量数据流的计算 |
价格 | 对机器要求低 | 对内存有要求 |
编辑范式 | Map+Reduce API较为底层,算法适用性差 | RDD组成DAG有向无环图。API较为顶层,方便使用 |
数据存储结构 | MapReduce中间计算结果在hdfs磁盘上,延迟大 | RDD中间运算结果在内存中,延迟小 |
运行方式 | Task以进程方式维护,任务启动慢 | Task以线程方式维护,任务启动快,可批量创建提高并行能力 |
四大特点
运行速度快:支持多种编程语言开发(Python/Scala/SQL), 使用成本低, 学习成本低
易用:计算速度快, 内存中计算比MapReduce快100倍, 磁盘中计算比MapReduce快10倍
通用:支持多种计算方式:RDD计算 SQL计算 图计算 机器学习计算 流计算
支持多种开发方式:交互式开发 -> 进入spark终端编写代码, 程序运行代码销毁
脚本式开发 -> 永久存储程序代码
兼容性强:支持多种三方工具 HDFS/Hive/Hbase/MySQL/Kafka/
调度工具 Yarn/Standalone/Mesos
高可用工具 Zookeeper
框架模块
SparkCore:spark的核心,是Spark运行的基础,以RDD为数据抽象,提供Python,java,Scala、R语言的API。可以编程进行海量离线数据批处理计算
SparkSQL:基于SparkCore提供结构化数据的处理模块。支持对sql语言进行处理,本身针对离线计算场景,提供StructuredStreaming模块,进行数据的流式计算
SparkStreaming:以SparkCore为基础,提供数据的流式计算功能
MLlib:以SparkCore为基础,内置了大量机器学习库和Api算法,方便用户以分布式计算的模式进行机器学习计算
GraphX:以SparkCore为基础,提供大量图计算API,方便用于分布式计算模式进行图计算
运行模式
本地模式(单机):独立的进程,通过其内部的多个线程来模拟整个Spark的运行环境
Standalone模式(集群):Spark中的每个角色以独立进程的形式存在,并组成Spark集群环境
Hadoop Yarn模式(集群):各个角色运行在Yarn的容器内部,并组成Spark集群环境
Kubernetes模式(容器):各个角色运行在Kubernetes的容器内部,并组成Spark集群环境
执行框架
计算步骤
1.将RDD计算任务交给yarn的RM管理
2.RM随机找一个NM创建container执行计算任务(application master)
3.application master和RM保持通讯请求计算资源, 找到其他的NM创建container
4.其他的NM中的container执行map和reduce阶段任务
5.map阶段从hdfs上读取数据进行分布式计算
6.reduce阶段将map阶段的计算结果合并后保存到hdfs上
部署模式
本地模式: 使用单台服务器的资源执行spark任务, 测试环境下使用
测试环境下使用, 本地模式执行成功的脚步都可以在集群模式执行成功
集群模式: 使用多台服务器的资源执行spark任务, 生产环境
spark on standalone
-
使用spark自带的standalone资源调度工具管理spark集群
-
一主多从架构(单点故障问题), 可以使用zookeeper搭建高可用模式(Spark HA)
-
master: 主节点, 控制整个集群
-
worker: 从节点, 负责控制计算节点
-
driver: 进程, 管理spark计算任务
-
executor: 进程, 执行spark计算任务
spark on yarn
-
使用yarn资源调度工具管理spark集群
-
RM/NM/container
-
方式
-
yarn cluster: 生产环境
-
yarn client: 测试环境, 交互模式, pycharm
-
spark on mesos
-
使用mesos资源调度工具管理spark集群
-
spark是使用HDFS存储数据, 优先使用yarn管理spark集群(兼容性更好)
Spark开发方式
交互式开发
首先需要启动hadoop服务(如果没有配置映射,则切换至hadoop的安装路径启动,如果配置过映射,只需要在命令行start-all.sh即可)
启动后使用jps命令,当所展示的进程数如图所示就说明已经启动成功了
1.Scala交互式开发
输入指令spark-shell进入即可
退出的话: 输入quit或者ctrl+d即可
2.python交互式开发
配置相应环境后,输入指令pyspark进入即可
不同部署模式的Spark的使用操作
local本地模式
交互式
# 进入base虚拟环境
conda activate base
# 启动hadoop集群
start-all.sh
# 启动历史服务
/export/server/spark/sbin/start-history-server.sh
# 启动spark本地模式
# 没有任何指定,采用是local模式,调用的是本机资源无法使用集群资源,相当于是单机计算
pyspark
脚本式
# 导入模块
from pyspark import SparkContext
# 创建SparkContext对象
# 没有指定任何参数,使用本地local模式
sc = SparkContext()
# 创建python列表数据
a = [1, 2, 3, 4]
# 转换成RDD
rdd = sc.parallelize(a)
# 对rdd数据进行计算
res = rdd.reduce(lambda a, b: a + b)
print(res)
Standalone模式
standalone是spark自带的资源调度管理服务,master 类似 yarn中的ResourceManger 负责管理资源服务,worker 类似 yarn中的NodeManager 负责将每台机器上的资源给到计算任务。
交互式
# 因为配置了高可用模式, 三台虚拟机要先启动ZooKeeper服务
zkServer.sh start
# 在node1虚拟机上启动standalone服务
/export/server/spark/sbin/start-all.sh
# 启动pyspark, 使用standalone资源调度
(base) [root@node1 ~]# pyspark --master spark://node1:7077
脚本式
# 导入模块
from pyspark import SparkContext
# 创建SparkContext对象
# master参数可以指定调用的资源服务
# 使用standalone资源调度
sc = SparkContext(master='spark://node1:7077')
# 创建python列表数据
a = [1, 2, 3, 4]
# 转换成RDD
rdd = sc.parallelize(a)
# 对rdd数据进行计算
res = rdd.reduce(lambda a, b: a + b)
print(res)
Standalone 高可用集群模式
交互式
# 因为配置了高可用模式, 三台虚拟机要先启动ZooKeeper服务
zkServer.sh start
# 在node1虚拟机上启动standalone服务
(base) [root@node1 ~]# /export/server/spark/sbin/start-all.sh
# 在node2虚拟机上启动standalone服务
(base) [root@node2 ~]# /export/server/spark/sbin/start-master.sh
# 启动pyspark, 使用standalone高可用资源调度
(base) [root@node1 ~]# pyspark --master spark://node1:7077,node2:7077
脚本式
# 导入模块
from pyspark import SparkContext
# 创建SparkContext对象
# master参数可以指定调用的资源服务
# 使用standalone高可用资源调度
sc = SparkContext(master='spark://node1:7077,node2:7077')
# 创建python列表数据
a = [1, 2, 3, 4]
# 转换成RDD
rdd = sc.parallelize(a)
# 对rdd数据进行计算
res = rdd.reduce(lambda a, b: a + b)
print(res)
Yarn集群模式
交互式
# 启动yarn集群服务
(base) [root@node1 ~]# start-all.sh
# 启动pyspark, yarn资源调度
(base) [root@node1 ~]# pyspark --master yarn
脚本式
# 导入模块
from pyspark import SparkContext
# 创建SparkContext对象
# master参数可以指定调用的资源服务
# 使用yarn资源调度
sc = SparkContext(master='yarn')
# 创建python列表数据
a = [1, 2, 3, 4]
# 转换成RDD
rdd = sc.parallelize(a)
# 对rdd数据进行计算
res = rdd.reduce(lambda a, b: a + b)
print(res)
Spark指令参数
概念:指令:在linux终端输入的spark命令,类似于Linux shell指令
参数:指令后可以携带各种参数,可以对指令增加一些设置 例如:--master 运行模式
参数在交互式开发模式下都生效,在脚本式模式下一般参数不会生效
# 表示引用运行的模式,要么是本地local要么是集群(Standalone、YARN、Mesos)了
--master MASTER_URL
# 本地模式∶local[2] 数字表示可以使用到本地的cpu核心数, loacl[*] *表示自动判断
# Standalone集群∶spark∶//xxx∶7077,yyy∶7077
# YARN 集群∶ yarn
# 表示的是应用运行的名称,通常在应用开发的时候指定
--name NAME
# 表示应用运行时指定的某些参数配置,http∶//spark.apache.org/docs/2.2.0/configuration.html
# 当value中的值有空格组成的时候,使用双引号将key=value引起来
# 可以不用在bashrc写配置可以通过conf配置,每次运行都要指定很麻烦
--conf "PROP=VALUE"
# 第一种方式∶属性的值中没有空格
--conf spark.eventLog.enabled=false
# 第二种方式∶属性的值中有空格,将属性和值统一使用双引号引起来
--conf "spark.executor.extraJavaOptions=-XX:+PrintGCDetails -XX:+PrintGCTimestamps"
# Driver相关配置 对driver一般不用配置
# 指定Driver Program JVM进程内存大小,默认值为1g
--driver-memory MEM
# 表示Driver 运行CLASS PATH路径,使用不多
--driver-class-path
# Spark standalone with cluster deploy mode∶运行在standalone 中cluster Deploy Mode 默认值为1 cpu核心数量
# 运行在YARN in cluster mode,默认值是1
--driver-cores NUM
# 运行在standalone的 中cluster Deploy Mode下,表示当Driver运行异常失败,可以自己重启
--supervise
# Executor运行所需内存大小
--executor-memory MEM
# Executor 运行的CPU Cores,默认的情况下,在Standalone集群上为worker节点所有可用的Cpu Cores,在YARN集群下为1
--executor-cores NUM
# 表示运行在Standalone集群下,所有Executor的CPU Cores,结合--executor-cores计算出Executor个数
--total-executor-cores
# 表示在YARN集群下,Executor的个数,默认值为2
--num-executors
# 表示Driver Program运行的地方,也叫做应用部署模式,默认值为client,通常在生产环境中使用cluster
--deploy-mode DEPLOY_MODE
spark指令使用参数举例
# 指定的参数中,主要是资源调度模式, 应用程序名称, python解析器配置
pyspark --master yarn --name yarn_demo --conf "PYSPARK_PYTHON=/export/server/anaconda3/bin/python3"
spark脚本使用参数举例
# 导入模块
from pyspark import SparkContext
# 创建SparkContext对象
# 参数master: 指定应用运行的模式
# 参数appName: 指定应用运行的名称
sc = SparkContext(master='yarn', appName='yarn_demo')
# 创建python列表数据
a = [1, 2, 3, 4]
# 转换成RDD
rdd = sc.parallelize(a)
# 对rdd数据进行计算
res = rdd.reduce(lambda a, b: a + b)
print(res)
Spark-submit提交方式
注:必须在yarn集群模式下提交
spark-submit指令语法
spark-submit --参数名 参数值 Python文件
格式:
cluster模式提交
spark-submit --master yarn --name cluster_demo --deploy-mode cluster b.py
client模式提交
spark-submit --master yarn --name client_demo --deploy-mode client b.py