|NO.Z.00095|——————————|BigDataEnd|——|Hadoop&Spark.V11|——|Spark.v11|Spark 原理 源码|作业执行原理&本地化调度&返回结果&失败重试与黑名单机制|
一、本地化调度
### --- 本地化调度
~~~ DAGScheduler切割Job,划分Stage。
~~~ 调用submitStage来提交一个Stage对应的tasks,submitStage会调用submitMissingTasks,
~~~ submitMissingTasks 确定每个需要计算的 task 的 preferred Locations
~~~ 通过调用 getPreferrdeLocations 得到分区的优先位置,
~~~ 一个partition对应一个task,此分区的优先位置就是task的优先位置
~~~ 从调度队列中拿到 TaskSetManager 后,
~~~ 那么接下来的工作就是 TaskSetManager 按照一定的规则一个个取出task 给 TaskScheduler,
~~~ TaskScheduler 再交给 SchedulerBackend 发送到 Executor 上执行
### --- 根据每个 task 的优先位置,确定 task 的 Locality 级别,Locality一共有五种,优先级由高到低顺序
PROCESS_LOCAL data is in the same JVM as the running code. This is the best locality possible
NODE_LOCAL data is on the same node. Examples might be in HDFS on the same node, or in
another executor on the same node. This is a little slower than PROCESS_LOCAL because the data has to travel between processes
NO_PREF data is accessed equally quickly from anywhere and has no locality preference
RACK_LOCAL data is on the same rack of servers. Data is on a different server on the same rack so needs to be sent over the network, typically through a single switch
ANY data is elsewhere on the network and not in the same rack
### --- 本地化调度
~~~ 在调度执行时,Spark总是会尽量让每个 Task 以最高的本地性级别来启动;
~~~ 当某个 Task 以某个本地性级别启动,但是该本地性级别对应的所有节点都没有空闲资源而启动失败,
~~~ 此时并不会马上降低本地性级别启动,而是在某个时间长度内再次以X本地性级别来启动该task,
~~~ 若超过限时时间则降级启动,去尝试下一个本地性级别,依次类推;
~~~ 通过调整每个类别的最大容忍延迟时间,
~~~ 在等待阶段对应的 Executor 可能就会有相应的资源去执行此 Task,
~~~ 这样有可能在一定程度上提到运行性能;
二、返回结果
### --- 返回结果
~~~ 对于Executor的计算结果,会根据结果的大小使用不同的处理策略:

### --- 计算结果在(0,200KB-128MB)区间内:通过Netty直接发送给Driver终端
~~~ Netty的预留空间reservedSizeBytes,200KB
~~~ spark.rpc.message.maxSize,默认值是128MB
~~~ 计算结果在[128MB, 1GB]区间内:将结果以 taskId 为编号存入到 BlockManager 中,
~~~ 然后通过 Netty 把编号发送给 Driver;阈值可通过 Netty 框架传输参数设置
~~~ spark.driver.maxResultSize,默认值 1G
~~~ 计算结果在(1GB,∞)区间内:直接丢弃,可通过spark.driver.maxResultSize配置
三、失败重试与黑名单机制
### --- 失败重试与黑名单机制
~~~ Task被提交到Executor启动执行后,
~~~ Executor会将执行状态上报给SchedulerBackend(DriverEndpoint);
~~~ SchedulerBackend 则告诉 TaskScheduler,TaskScheduler 找到该 Task 对应的 TaskSetManager,
~~~ 并通知到该TaskSetManager,这样 TaskSetManager 就知道 Task 的失败与成功状态;
~~~ 即 SchedulerBackend(DriverEndPoint) => TaskScheduler => TaskSetManager
~~~ 对于失败的Task,会记录它失败的次数,如果失败次数还没有超过最大重试次数,
~~~ 那么就把它放回待调度的Task池子中,否则整个Application失败;
~~~ 在记录 Task 失败次数过程中,会记录它上一次失败所在的Executor Id和Host。
~~~ 下次再调度这个Task时,会使用黑名
~~~ 单机制,避免它被调度到上一次失败的节点上,起到一定的容错作用;
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
分类:
bdv018-spark.v03
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」