1.spark的框架模块
- Spark Core
实现了 Spark 的基本功能,包含RDD、任务调度、内存管理、错误恢复、与存储系统交互等模块。数据结构:RDD
- Spark SQL
Spark 用来操作结构化数据的程序包。通过 Spark SQL,我们可以使用 SQL操作数据。数据结构:Dataset/DataFrame = RDD + Schema
- Spark Streaming
Spark 提供的对实时数据进行流式计算的组件。提供了用来操作数据流的 API。 数据结构:DStream = Seq[RDD]
- Spark MLlib
提供常见的机器学习(ML)功能的程序库。包括分类、回归、聚类、协同过滤等,还提供了模型评估、数据导入等额外的支持功能。
数据结构:RDD或者DataFrame
- Spark GraphX
Spark中用于图计算的API,性能良好,拥有丰富的功能和运算符,能在海量数据上自如地运行复杂的图算法。数据结构:RDD或者DataFrame
2.spark的运行模式
- 1、本地模式:Local Mode
spark中有两类角色,一个是Master角色,另一个是Worker角色
Local模式就是,以一个JVM进程,去模拟整个Spark的运行环境,就是将Master和Worker角色以线程的形式运行在这个进程中(模拟两个角色,
实际在本地模式中没有这两个角色)
Local模式下,不需要进行资源管理,JVM进程启动的时候,能获取多少资源,这个local模式下就能使用多少资源
Local模式下,其实就有两个线程来维持Spark的集群环境:Driver线程和Excutor线程
- 2、Standalone模式
描述:Standalone模式是Spark自带的一种集群模式,是真实地在多个机器之间搭建Spark集群的环境
两个角色:Master、Worker
1、伪分布式(测试开发用):将Master进程和Worker进程在一台机器内运行
2、完全分布式(测试开发用):将Master进程和Worker进程分开在不同的机器上运行,比如机器1运行Master进程,
机器2机器3机器4运行Worker进程
3、高可用的完全分布式模式(企业生产环境有可能用): 将Master进程和Worker进程分开在不同的机器上运行,同时,拥有多个Master做备份
- Standalone模式下各个节点作用:
- 主节点Master:
- 管理整个集群资源,接收提交应用,分配资源给每个应用,运行Task任务
- 从节点Workers:
- 管理每个机器的资源,分配对应的资源来运行Task;
- 每个从节点分配资源信息给Worker管理,资源信息包含内存Memory和CPU Cores核数
- 历史服务器HistoryServer(可选):
- Spark Application运行完成以后,保存事件日志数据至HDFS,启动HistoryServer可以查看应用运行相关信息
- 主节点Master:
- 高可用模式
Spark Standalone集群是Master-Slaves架构的集群模式,单节点情况下,它存在单点故障问题
解决单点故障的两种方案:
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没有任何的影响
加入ZooKeeper的集群整体架构如下图
-
3、spark on yarn
- spark运行在yarn上有两种模式:Client模式 Cluster模式
- Client模式:Driver运行在提交应用的主机上,如图
- Cluster模式:Driver运行在集群中(Standalone:Worker,YARN:NodeManager)
- Client模式:Driver运行在提交应用的主机上,如图
- spark运行在yarn上有两种模式:Client模式 Cluster模式
-
Client模式的运行流程
- 1、Driver在任务提交的本地机器上运行,Driver启动后会和ResourceManager通讯申请启动ApplicationMaster;
- 2、随后ResourceManager分配Container,在合适的NodeManager上启动ApplicationMaster,此时的ApplicationMaster的功能相当于一个ExecutorLaucher,只负责向ResourceManager申请Executor内存;
- 3、ResourceManager接到ApplicationMaster的资源申请后会分配Container,然后ApplicationMaster在资源分配指定的NodeManager上启动Executor进程;
- 4、Executor进程启动后会向Driver反向注册,Executor全部注册完成后Driver开始执行main函数;
- 5、之后执行到Action算子时,触发一个Job,并根据宽依赖开始划分Stage,每个Stage生成对应的TaskSet,之后将Task分发到各个Executor上执行。
-
Cluter模式流程
- 1、任务提交后会和ResourceManager通讯申请启动ApplicationMaster;
- 2、随后ResourceManager分配Container,在合适的NodeManager上启动ApplicationMaster,此时的ApplicationMaster就是Driver;
- 3、Driver启动后向ResourceManager申请Executor内存,ResourceManager接到ApplicationMaster的资源申请后会分配Container,然后在合适的NodeManager上启动Executor进程;
- 4、Executor进程启动后会向Driver反向注册;
- 5、Executor全部注册完成后Driver开始执行main函数,之后执行到Action算子时,触发一个job,并根据宽依赖开始划分stage,每个stage生成对应的taskSet,之后将task分发到各个Executor上执行;
3.spark的特点
- 1、A list of partitions
- 一组分片(Partition)/一个分区(Partition)列表,即数据集的基本组成单位
- 对于RDD来说,每个分片都会被一个计算任务处理,分片数决定并行度
- 用户可以在创建RDD时指定RDD的分片个数,如果没有指定,那么就会采用默认值
- 2、A function for computing each split
- 一个函数会被作用在每一个分区
- Spark中RDD的计算是以分片为单位的,compute函数会被作用到每个分区上
- 3、A list of dependencies on other RDDs
- 一个RDD会依赖于其他多个RDD;
- RDD的每次转换都会生成一个新的RDD,所以RDD之间就会形成类似于流水线一样的前后依赖关系。在部分分区数据丢失时,Spark可以通过这个依赖关系重新计算丢失的分区数据,而不是对RDD的所有分区进行重新计算(Spark的容错机制);
- 4、Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
- 可选项,对于KeyValue类型的RDD会有一个Partitioner,即RDD的分区函数;
- 当前Spark中实现了两种类型的分区函数,一个是基于哈希的HashPartitioner,另外一个是基于范围的RangePartitioner。
- 只有对于于key-value的RDD,才会有Partitioner,非key-value的RDD的Parititioner的值是None。
- Partitioner函数不但决定了RDD本身的分片数量,也决定了parent RDD Shuffle输出时的分片数量。
- 5、Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)
- 可选项,一个列表,存储存取每个Partition的优先位置(preferred location);
- 对于一个HDFS文件来说,这个列表保存的就是每个Partition所在的块的位置。
- 按照"移动数据不如移动计算"的理念,Spark在进行任务调度的时候,会尽可能选择那些存有数据的worker节点来进行任务计算。(数据本地性)
4.spark常用shell命令
- spark-shell
- 说明:
- 1、直接使用./spark-shell 表示使用local 模式启动,在本机启动一个SparkSubmit进程
- 2、还可指定参数 --master,如:
spark-shell --master local[N] 表示在本地模拟N个线程来运行当前任务
spark-shell --master local[*] 表示使用当前机器上所有可用的资源 - 3、不携带参数默认就是 spark-shell --master local[*]
- 4、还可以使用–master指定集群地址,表示把任务提交到集群上运行,如
./spark-shell --master spark://node01:7077,node02:7077 - 5、退出spark-shell ::quit
- 说明:
- spark-submit
SPARK_HOME=/export/server/spark
${SPARK_HOME}/bin/spark-submit \
--master spark://node1:7077,node2:7077 \
--class org.apache.spark.examples.SparkPi \
${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \
10
5.RDD概念
6.RDD创建方式
6.1 本地集合转为RDD的两种方式
1、val rdd1 = sparkContext.parallelize(List(1,2,3,4,5))
val rdd2 = sparkContext.parallelize(List(1,2,3,4,5), 5)
2、val rdd3: RDD[Int] = sc.makeRDD(List(1, 2, 3))
val rdd4: RDD[Int] = sc.makeRDD(List(1, 2, 3), 6)
不指定分区数时为默认分区数,默认为CPU核心数,指定分区数后为指定数
6.2 获取文件转为RDD的三种方式
1、将指定文件转为RDD
val rdd5: RDD[String] = sc.textFile("data/input/words.txt")
textFile 如果不设定分区数, 默认是2个分区读取数据
val rdd6: RDD[String] = sc.textFile("data/input/words.txt", 100)
textFile支持设定分区数,但是设定的过大无效.
2、读取指定文件夹下数据,转为RDD
val rdd7: RDD[String] = sc.textFile("data/input/ratings10")
从文件夹中读取数据,RDD默认分区数为文件数量
val rdd8: RDD[String] = sc.textFile("data/input/ratings10", 100)
设定了分区数量后,不一定等于设置的数量,可能大于,但能保证不低于设置的数量
3、从文件夹中读取,主要针对操作小文件
val rdd10: RDD[(String, String)] = sc.wholeTextFiles("data/input/words.txt")
不设置分区数,默认是2
val rdd11: RDD[(String, String)] = sc.wholeTextFiles("data/input/ratings10", 100)
最大分区数是文件数量,小于文件数量可以正常设置