第一种是local本地部署,通常就是一台机器用于测试。
第二种是standalone部署模式,就是一个master节点,控制几个work节点,其实一台机器的standalone模式就是它自己即是master,又是work。
第三种是yarn模式,就是吧spark交给yarn进行资源调度管理。
第四种就是messon模式,这种在国内很少见到。
如果是在 spark standalone集群模式下,也就是使用spark自带的集群管理模式,那么spark的master阶段管理worker的资源分配,为防止master主节点宕机导致,可以对master节点进行高可用设置。
也就是备份几个stand master节点。实现主要是通过zookeper的选择机制进行主节点的选取,其中另外一个比较关键的步骤就需要进行状态持久化,mater节点了持久化当前集群的元数据到zookeeper。
在master节点出现异常的情况下,zookeeper可以通过选取机制选取到新的主节点,然后主节点将从zookeepe获取到最新持久化的元数据;
如果是spark yarn模式的话,就按按yarn的高可用方式就可以了。
spark任务提交的方式有很多种:
1、使用spark_shell:日常做一些简单的测试,使用spark-shell命名就可以,然后通过scala语言进行查询处理
/home/hadoop/app/spark-2.2.0-bin-2.6.0-cdh5.7.0/bin/spark-shell \
> --master spark://192.168.2.111:7077 \
> --executor-memory 2G \
> --total-executor-cores 2
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
25/02/15 16:45:37 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
25/02/15 16:45:43 WARN ObjectStore: Failed to get database global_temp, returning NoSuchObjectException
Spark context Web UI available at http://192.168.2.111:4040
Spark context available as 'sc' (master = spark://192.168.2.111:7077, app id = app-20250215164538-0002).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.2.0
/_/
Using Scala version 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_144)
Type in expressions to have them evaluated.
Type :help for more information.
scala> sc.textFile("hdfs://192.168.2.102:9000//user/spark/input/word.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).saveAsTextFile("hdfs://192.168.2.102:9000//user/spark/out")
scala> sc.textFile("hdfs://192.168.2.102:9000/user/spark/out/*").collect().foreach(println)
(orange,1)
(queen,1)
(rabbit,1)
(fish,1)
(dog,1)
(apple,1)
(pig,1)
(umbrella,1)
(snake,1)
(lion,1)
(juice,1)
(cat,1)
(tiger,1)
(banana,1)
(monkey,1)
(nose,1)
(kite,1)
(elephant,1)
(ice,1)
(goat,1)
(horse,1)
2、使用spark-commit的shell脚本提交任务:这种就是涉及到jar包,我们会开发好我们的逻辑并通过maven打包好java包,通过spark-commit命令提交saprk运行任务李并且在工作中我们需要通过xx-job或者Airfloe,Azkaban,等等的调度工具进行定时调度运行。
[root@hadoop000 spark-2.2.0-bin-2.6.0-cdh5.7.0]# /home/hadoop/app/spark-2.2.0-bin-2.6.0-cdh5.7.0/bin/spark-submit \
> --class org.apache.spark.examples.SparkPi \
> --master spark://192.168.2.111:7077 \
> --executor-memory 1G \
> --total-executor-cores 2 \
> /home/hadoop/app/spark-2.2.0-bin-2.6.0-cdh5.7.0/examples/jars/spark-examples_2.11-2.2.0.jar
第一个是需要运行的主函数class:这个就是jar包里面的主函数
第二个就是每个任务执行节点的内核,默认就是1,官方建议2-5个,我们公司设置的3个
第三个就是每个执行机器的设置内存,这个根据实际的任务进行灵活调整,我们公司但是是6G或者8G
另外两个就是driver的内核和内存
Spark组件架构主要采用主从结构,分别是driver驱动器,Excutor执行器,和cluster Manager集群管理器这个三个架构组件
其中driver驱动器主要负责spark执行Excutor的任务分配。
Excutor执行器猪獒就是负责将被分配到的task任务进行处理
claster manager管理有多钟:
第一种的spark自带的的集群管理,叫做standalone。
第二种是spark on yarn,就是将任务字段给到apache yarn进行资源调度管理。
第三种是spark on meoss,meoss是一种类似于yarn的集群资源管理,在国外用的比较常见。
spark的standalone模集群模式是spark自带的一种集群模式,主要就是适用于进行测试环境的测试工作,以及一些数据小范围的测试使用,一般不用于生产环境。
standalone模式洪有 master,worker,driver,excutor,w无需依赖其它。
其中master指的就是主节点,管理对worker从节点资源的分配和管理,决定Driver和xcutor的运行位置
worker从节点主要是接受来自master主节点的指示启动Excutor
driver驱动器是负责管理任务的DAU,负责调度运行task任务,取决于standalone是那种模式,如果是clinet的就是,就是提交大客户端机器上,如果是standaone on clusetr,就是会运行在某个从节点上。
excutor执行器是负责执行task任务的。
上述讲的其实就是spark任务提交所涉及到的租金啊,那么具体的步骤就是
1、Spark-submit提交需要运行的任务,涉及大参数包括claster类,以及运行模型是master,以及执行的内存和core等;
2、master接受到任务后选择一个work启动driver驱动器没,如果选择的事cline客户端模式,俺就是master所在的客户端作为driver驱动器运行的起点;如果是cluetr模式,那么就是需要选择一个worker节点作为driver驱动器的运行接地那
3、启动driver,启动driver之后,对提交的任务内容进行解析,生成DAG和task任务。
5、Excuttor注册和进行任务计算,master根据解析的资源,选择worker节点进行分配执行器的分配。
6、最后任务分配完后,进行释放资源
spark on yarn的模式其实就是把资源管理调度交给yarn,有yarn进行统一的资源分配管理
所以spark 欧尼yarn涉及到了yarn的sourceManager和appication master及诶点和nodemannage管理及诶点
所以相比较standalone模式,就是yarn替代了master进行资源管理的集中分配
所以Saprk on yarn的任务执行步骤:
1、第一步就是saprk=commit提交spark运行任务到yarn mannager。
2、source manager管理器进行资源解析后启动aplication master节点,并且启动driver驱动器进行DAG执行计划和task任务生成。
3、启动excutor执行器,需要yarn活制定nodemannagety节点,启动excutor.
4、nodemanager咋分配的容器中执行excutor,执行task任务
5、最终driver输出结果。
Spark-on-yarn是生产环境广泛采用的一种集群模式,有如下的有点
首先是可以进行动态机制,在任务运行过程中,如果有空闲的worker节点了,那么会利用起来。
其次是同一运维,yarn不经很支持spark,还支持haddop生态,还有flink等
资源隔离:saprk on yarn是基于容器,说明可以对单个执行任务进行cpu还涉及,不影响整体的集群计算
集群规模:yarn集群可以一直吃公司级别的大规模集群。
首先Spark的shuffle是Spark分布式集群计算的核心。
Spark的shuffle可以从shuffle的阶段划分,shuffle数据存储,shuffle的数据拉取三个方面进行讲解。
首先shuffle的阶段分为shuffle的shuffle write阶段和shuffle read阶段。shuffle write的触发条件就是上游的Stage任务shuffle Map Task完成计算后,会哪找下游Stage的分区规则重新分区,shuffle的操作逻辑就每个shuffl map task将数据按目标分区写入本地磁盘,生成shuffle 中间文件。
shuffle read的出发条件就是下游的result Stage任务运行Result task任务启动的时候,需要从上游节点拉取属于自己分区的数据,拉取数据后,shuffle read可能哪找操作的指令进行reduceByKey,或者sortByKey等操作。
然后shuflle的中间文件结果的存储是通过shuffle manager管理,默认使用SortshuffleManaer,存储方式就是每个shuffle Map Task会生存一个文件,包含所有分区的数据,然后附带一个记录文件各个分区的偏移量,然后我们默认使用的SortShuffleManager会自动的对文件额索引文件进行合并处理,减少文件数量,降低磁盘的IO压力,从而提高shuffle效率。
然后第三个就是数据的拉取阶段,是通过readSuffle从各个节点去拉群。首先Driver中的MapOutputTraver记录所有ShuffelMapTak的任务,下游Task想Tractorcah查询目标数据位置,然后进行拉群,拉去后就会进行数据处理,一般都是在内存当中进行处理,如果内存不足,就会溢写出到磁盘当中。
首先是未优化过的 hashshuffle的流程:
在Map阶段会根据上游RDD的分区数生成M个task任务;
然后再reduce阶段会根据下游RDD所需的分区数据生成R个task任务
每个R任务会从M个task任务区获取各自分区的数据,最终声场的文件数就是,M 乘以 R
缺点就是会生成大量小文件,会对IO性能带来压力,以及文件管理节点带来严重压力。
因为大量爆发的小文件问题,所以已经弃用为优化的hashshuffle方式了;
因此对hashshuffle进行了文件合并的优化;
优化的点就是在于 将同一个Excutor执行器的task任务产生的文件都 共享同一个输出文件,
这样每个reduce task中就对应了一个输出文件的多个数据块,reduce task执行完后就合并文件了
这样优化之后,显著的减少了文件的数据,如果有执行器的数量 乘以 reduce task的数量
但是对于大批量的数据计算,这样的优化还是不够。
因此现在Spark默认方式就是SortShuffle方式,能有效的减少小文件的数据量
在map task任务按照分区生成M个文件后,文件会被排序并进入内存缓存区,如果内存缓存不足就会溢出到磁盘当中
在reduce拉去数据之前,所有的数据都会合并成一个有序的数据文件,和一个对应分区的索引文件
在Reduce task阶段,按照索引去拉去对应数据
这样在shuffle阶段就只生成了M 乘以 2的文件数据量
缺点就是排序会需要一定的CPU开销
因此优化出来了一个ByPass 的 sortShuffle ,就是会通过参数设置设置一个文件的阈值,默认是200,
首先是Spark宽窄依赖的定义:
简单来理解的话,窄依赖就是父RDD的每个分区最多被一个子RDD所依赖,是一对一依赖,这种情况的操作例如union,flatMap这样的操作,不会产生shuffle。
宽依赖有别名叫做shuffle依赖,就是父RDD的每个分区会被多个子RDD所依赖,例如ReduceByKey,join这样的操作,会产生shuffle
所以划分Stage的边界就是宽依赖,而窄依赖会被流水线话的合并到同一个Stage中进行处理
在Stage中,决定Task数量有两方面的task数据:
一方面是shuffle中的shuffleMapStage的task数据会根据上游EDD的分区数进行划分,有多少个分区就有多少个Task数据。
另外的resultSta的task数据则会根据下游最终那个RDD的需要所分区数据进行分区,这里我们可以进行通过参数控制task的数据,那么就会有200个task任务数,默认是200个分区数据,可以根据实际情况进行优化调参数。
首先是关于Sparks数据本地性是在任务调度将诶单的TaskScheduler确定的,巨日就是TaskSc会获取到分区的位置信息,进而确定每个task的最佳执行位置,会由有限将Task分邓培到数据所在节点,进而减少网络传输,如果首选的位置出现了故障或者繁忙,则会调整选择放宽本地性的要求。
那这里就涉及了数据本地性有哪几种,Task调度选择的有限是什么,首先选择缓存数据在同一个JVM进行的执行器,这种是默认的,如果不行,那几下里选择的就是在同一个物理节点上的执行器,然后再是选择在同一个几家上的不同及诶点,然后就收无位置偏好,然后就随意了。
首先需要阐述的就是Spark为什么要持久,就是因为我们是基于内存去做计算的,如果计算任务比较长,有些计算结果我们就可以复用,来提高我们任务完成的效率。
需要持久化的场景,比如我们某部分计算数据会被多次使用,比武我们使用贷迭代算法。
其实cache()是一种特殊的persist()持久化操作,cache()就是默认的pesist持久化侧,也就是仅在内存中作缓存,如果内存不读了,剩余的还是要从头再计算一次。但是persist还有其他几种模式,比如内存溢出了就持久化到磁盘当中去,比如就只选择持久化到磁盘,这些都可以自定义选择
血统可以理解成是Spark分布式计算的基因,血统里面存储了计算的逻辑链,spark可以根据血统存储的计算逻辑链进行数据的重新计算恢复,从而能保证Saprk任务的容错机制。
血统其实在一些比较复杂冗长的计算任中,可能性能不佳,因为血统只是存储逻辑链,如果某个RDD计算节点宕机了,那就需要从头开始恢复数据。
因此针对血统还可以做chekpoint优化,设置坚持点并将检查点数据持久化到HDFS中,实现计算优化。
广播变量,就是把变量广播到共享为止或者执行器的本地化存储起来,这样再分布式计算中可以减少大量的网络传输,在大数据场景下可以有效提高任务效率。
累加器的使用产假就是分布式聚合计算,能保证数据的容错性。