Spark学习笔记(5) —— 调度算法
应用程序之间
ClusterManager提供了资源的分配和管理,而在独立运行模式中Master提供了资源管理调度功能。在调度过程中,Master先启动等待列表中应用程序的Driver,这些Driver尽可能分散在集群的Worker节点上,然后根据集群的内存和CPU使用情况,对等待的应用程序进行资源分配,在分配算法上根据先来先分配,先分配的应用程序会尽可能地获取满足条件的资源,后分配的应用程序只能在剩余资源中再次筛选。如果没有合适资源的应用程序只能等待,知道其他应用程序释放。该侧率可以认为是有条件的FIFO策略。
作业与调度阶段之间
Spark应用程序提交执行时,会根据RDD依赖关系形成有向无环图(DAG),然后交给DAGScheduler进行划分作业和调度阶段。这些作业之间可以没有任何依赖关系,对于多个作业之间的调度,Spark目前提供了两种调度策略:一种是FIFO模式,这也是目前默认的模式;另一种是FAIR模式,该模式的调度可以通过两个参数的配置来决定Job执行的邮箱模式。
在FAIR算法中,现货区两个调度的饥饿成都,饥饿程度为正在运行的任务是否小于最小任务,如果是,则表示该调度处于饥饿成都。获取饥饿程度后进行如下比较:
- 如果某个调度处于饥饿状态另外一个非饥饿状态,则先满足处于饥饿状态的调度;
- 如果两个调度都处于饥饿状态,则比较资源比,先满足资源比小的调度;
- 如果两个调度都出与非饥饿状态,则比较权重比,先满足权重比小的调度;
- 以上情况均相同的情况,根据调度的名称排序。
任务之间
数据本地性
数据的计算尽可能在数据所在节点上进行,这样可以减少数据在网络上传输。在Spark中数据本地性优先级从高到底为PROCESS_LOCAL>NONE_LOCAL>NO_PREF>RACK_LOCAL>ANY,即最好的是任务运行的节点内存中存在数据、次好的是同一个Node(同一机器)上的,再次是同机架上,最后是任意位置。其中任务数据本地性通过以上情况来确定:
- 如果任务处于作业开始的调度阶段内,这些任务对应的RDD分区都有首选运行位置,该位置也是任务运行首选位置,数据本地性为NODE_LOCAL。
- 如果任务处于非作业开头的调度阶段,可以根据父调度阶段运行的位置得到任务的首选位置,这种情况下,如果Executor处于活动状态,则数据本地性为PROCESS_LOCAL;如果Executor不处于活动状态,但存在父调度阶段运行结果,则数据本地性为NODE_LOCAL。
- 如果没有首选位置,则数据本地性为NO_PREF。
延迟执行
在任务分配运行节点时,先判断任务最佳运行节点是否空闲,如果该节点没有足够的资源运行该任务,在这种情况下任务会等待一定时间;如果在等待内该节点释放出足够的资源,则任务在该节点运行,如果还是不足会找出次佳的节点进行运行。通过这样的方式进行能地让任务运行在更高级别数据本地性的节点,从而减少磁盘I/O和网络传输。一般来说只对PROCESS_LOCAL和NODE_LOCAL两个数据本地级别进行等待。
Spark任务分配的原则就是让任务运行在数据本地性优先级高的节点上,甚至可以为此等待一定的时间。