spark07
spark07
spark运行原理:
RDD Object
driver提交代码,spark-submit运行main方法。但是没有真正执行,初始化driver端得组件DAGScheduler TaskScheduler SchedulerBackEnd.saveAsTextFile出发,DAGScheduler提交任务,解析代码生DAG有向无环图,真正得遇见action算子。
DAGScheduler进行DAG图的切分stage,从最后一个rdd入手,先前推进,看看dependency得依赖关系,如果是窄依赖则将本阶段rdd得数量加一,如果是shuffle算子那么将阶段加一,得到所有得阶段后,匹配阶段得类型,如果是shuffleMapStage就创建一个TaskSet装入得都是ShuffleMapTask,这个阶段得最后一个rdd得分区数量就是Task任务得数量,这个阶段完毕后,获得得时候一个Seq[TaskSet],将这个任务提交给TaskScheduler
TaskScheduler是接口,和executor进行交互,心跳机制,其实TaskScheduler就是driver
和Executor通信得组件,找到SchedulerBackEnd这个组件通信
CoarseGrainedExecutorBackEnd local 实现类进行任务得提交通信,将每一个task任务进行序列化,executor拿到任务以后要用到一个线程池进行运行,这个线程池没有能力运行一个普通的类,将task任务进行包装,组成一个taskRunner,放入到executor中进行执行。
调用taskRunner中的run方法执行代码逻辑,每个task中的runTask方法执行逻辑
spark的高级特性(持久化)
rdd1-rdd2-rdd3 ..... rdd20 ----消费记录分析 / 快递情况分析
持久化(缓存)他的意义在于频繁使用的rdd进行存储,不需要再次重新计算
缓存数据,cache()方法 == persist,将rdd缓存起来,下次使用的时候可以直接从缓存中读取数据
rdd.cache = rdd.persist() == rdd.persist(Memory_Only)
rdd.persist(StorageLevel.xxxx)
默认提供了12种存储级别
通过构造器和构造器种的值不一样,产生了12种级别
userDisk?是不是使用磁盘
userMemory?是不是使用内存
userOffHeap?是不是使用堆外内存
deserialized?是不是不序列化
replication?缓存rdd的时候缓存几个备份数
使用方式rdd.persist rdd.cache() rdd.persisit(StorageLevel.xxxx)但是不能自定义存储方式,因为构造器是私有化的不能重载
rdd.cache是一个懒加载形式,不遇见action算子不会执行,缓存的数据在监控页面种可以查看,能够分别查看每个分区数据的大小和存储的位置
缓存的数据分别存储到不同的executor种,每个executor种存在一个blockManager的工具管理本地缓存数据
缓存种的数据量远远大于实际数据量?
因为是rdd的数据
缓存的rdd变成了绿色
数据流向不会发生任何改变,读取数据直接从缓存种读取,不是从dhfs种读取,前面的过程直接跳过,但是流程还要走一遍
去除缓存的方式
rdd.unpersit
如果当前应用停止,则executor进程消失,那么缓存的数据也消失
总结:
- 常用的算子cache() persist() 也就是仅仅使用内存的方式比较常用
- 持久化的算子是懒加载的,必须使用行动类算子进行执行才能缓存
- 持久化算子在使用的时候依赖关系不会发生任何改变,但是计算过的内容不会重新计算
- 如果使用仅内存的方式,可能只缓存一部分的数据
以上的缓存只是针对于一个应用的,如果 应用停止,则缓存数据消失
checkPoint持久化数据(跨应用的)
缓存数据的时候是将数据放入到hdfs中,所以必须设定存储的文件目录
存储的时候有几个分区就会存储几份数据,这些数据的目录
/rddCkpt/54c48611-7771-45d4-9ad0-f3ad427c6858/rdd-6
这个目录的路径和应用的id还有rdd有关,是绑定关系
在checkpoint缓存的算子上继续执行任务的时候,这个依赖关系发生了改变,任务的开头从checkpoint开始。
rdd.checkpoint
rdd.collect
在使用checkpoint进行rdd缓存的时候,一个action算子产生了两个任务
在使用checkpoint的时候,是将数据存储到hdfs中,collect算子在执行的时候,自己会生成一个job。还会产生一个job专门来处理checkpoint将数据放入到hdfs中
- 如果使用checkpoint就可以跨应用使用了
- 如果执行checkpoint会产生两个应用
scala> sc.textFile("hdfs://master:9000/aaa.txt") res23: org.apache.spark.rdd.RDD[String] = hdfs://master:9000/aaa.txt MapPartitionsRDD[20] at textFile at <console>:25
scala> res23.cache() res24: res23.type = hdfs://master:9000/aaa.txt MapPartitionsRDD[20] at textFile at <console>:25
scala> res23.checkpoint
scala> res23.collect res26: Array[String] = Array(hello tom, hello jerry, hello rose, hello jack, jack rose)
|
在做checkpoint的时候可以先将这个rdd进行cache缓存,在执行checkpoint的时候可以从缓存中读取数据
以上的缓存都要使用内存,这个内存是spark集群中的内存
spark集群中的内存管理方案
object IpTest { |