您现在的位置: 首页 > 网站导航收录 > 百科知识百科知识
shuffle什么意思(sx是什么意思)
算子,节点,数据shuffle什么意思(sx是什么意思)
发布时间:2019-02-08加入收藏来源:互联网点击:
-
惰性计算为 Spark 执行引擎的整体优化提供了广阔的空间。关于惰性计算具体如何帮助 Spark 做全局优化 —— 说书的一张嘴表不了两家事,后文书咱们慢慢展开。
还是说回 RDD 算子,除了常见的按照 Transformations 和 Actions 分类的方法,笔者又从适用范围和用途两个维度为老铁们做了归类,毕竟人类的大脑喜欢结构化的知识,官网上一字长蛇阵的罗列总是让人看了昏昏欲睡。有了这个表格,我们就知道 *ByKey 的操作一定是作用在 Paired RDD 上的,所谓 Paired RDD 是指 Schema 明确区分(Key, Value)对的 RDD,与之相对,任意 RDD 指的是不带 Schema 或带任意 Schema 的 RDD。从用途的角度来区分 RDD 算子的归类相对比较分散,篇幅的原因,这里就不一一展开介绍,老铁们各取所需吧。
值得一提的是,对于相同的计算场景,采用不同算子实现带来的执行性能可能会有天壤之别,在后续的性能调优篇咱们再具体问题具体分析。好吧,坑越挖越多,列位看官您稍安勿躁,咱们按照 FIFO 的原则,先来说说刚刚才提到的、还热乎的 DAGScheduler。
DAGScheduler —— DAG 的向导官
DAGScheduler 是 Spark 分布式调度系统的重要组件之一,其他组件还包括 TaskScheduler、MapOutputTracker、SchedulerBackend 等。DAGScheduler 的主要职责是根据 RDD 依赖关系将 DAG 划分为 Stages,以 Stage 为粒度提交任务(TaskSet)并跟踪任务进展。如果把 DAG 看作是 Spark 作业的执行路径或“战略地形”,那么 DAGScheduler 就是这块地形的向导官,这个向导官负责从头至尾将地形摸清楚,根据地形特点排兵布阵。更形象地,回到土豆工坊的例子,DAGScheduler 要做的事情是把抽象的土豆加工 DAG 转化为工坊流水线上一个个具体的薯片加工操作任务。那么问题来了,DAGScheduler 以怎样的方式摸索“地形”?如何划分 Stages?划分 Stages 的依据是什么?更进一步,将 DAG 划分为 Stages 的收益有哪些?Spark 为什么要这么做?
DAGScheduler 的核心职责
为了回答这些问题,我们需要先对于 DAG 的“首”和“尾”进行如下定义:在一个 DAG 中,没有父 RDD 的节点称为首节点,而没有子 RDD 的节点称为尾节点。还是以土豆工坊为例,其中首节点有两个,分别是 potatosRDD 和 flavoursRDD,而尾节点是 flavouredBakedChipsRDD。
DAG 中首与尾的定义
DAGScheduler 在尝试探索 DAG“地形”时,是以首尾倒置的方式从后向前进行。具体说来,对于土豆工坊的 DAG,DAGScheduler 会从尾节点 flavouredBakedChipsRDD 开始,根据 RDD 依赖关系依次向前遍历所有父 RDD 节点,在遍历的过程中以 Shuffle 为边界划分 Stage。Shuffle 的字面意思是“洗牌”,没错,就是扑克游戏中的洗牌,在大数据领域 Shuffle 引申为“跨节点的数据分发”,指的是为了实现某些计算逻辑需要将数据在集群范围内的不同计算节点之间定向分发。在绝大多数场景中,Shuffle 都是当之无愧的“性能瓶颈担当”,毫不客气地说,有 Shuffle 的地方,就有性能优化的空间。关于 Spark Shuffle 的原理和性能优化技巧,后面我们会单独开一篇来专门探讨。在土豆工坊的 DAG 中,有两个地方发生了 Shuffle,一个是从 bakedChipsRDD 到 flavouredBakedChipsRDD 的计算,另一个是从 flavoursRDD 到 flavouredBakedChipsRDD 的计算,如下图所示。
土豆工坊 DAG 中的 Shuffle
各位看官不禁要问:DAGScheduler 如何判断 RDD 之间的转换是否会发生 Shuffle 呢?那位看官说了:“前文书说了半天算子是 RDD 之间转换的关键,莫不是根据算子来判断会不会发生 Shuffle?”您还真猜错了,算子与 Shuffle 没有对应关系。就拿 join 算子来说,在大部分场景下,join 都会引入 Shuffle;然而在 collocated join 中,左右表数据分布一致的情况下,是不会发生 Shuffle 的。所以您看,DAGScheduler 还真不能依赖算子本身来判断发生 Shuffle 与否。要回答这个问题,咱们还是得回到前文书《内存计算的由来 —— RDD》中介绍 RDD 时提到的 5 大属性。
属性名 成员类型 属性含义 dependencies 变量 生成该 RDD 所依赖的父 RDD compute 方法 生成该 RDD 的计算接口 partitions 变量 该 RDD 的所有数据分片实体 partitioner 方法 划分数据分片的规则 preferredLocations 变量 数据分片的物理位置偏好
RDD 的 5 大属性及其含义
其中第一大属性 dependencies 又可以细分为 NarrowDependency 和 ShuffleDependency,NarrowDependency 又名“窄依赖”,它表示 RDD 所依赖的数据无需分发,基于当前现有的数据分片执行 compute 属性封装的函数即可;ShuffleDependency 则不然,它表示 RDD 依赖的数据分片需要先在集群内分发,然后才能执行 RDD 的 compute 函数完成计算。因此,RDD 之间的转换是否发生 Shuffle,取决于子 RDD 的依赖类型,如果依赖类型为 ShuffleDependency,那么 DAGScheduler 判定:二者的转换会引入 Shuffle。在回溯 DAG 的过程中,一旦 DAGScheduler 发现 RDD 的依赖类型为 ShuffleDependency,便依序执行如下 3 项操作:
沿着 Shuffle 边界的子 RDD 方向创建新的 Stage 对象把新建的 Stage 注册到 DAGScheduler 的 stages 系列字典中,这些字典用于存储、记录与 Stage 有关的状态和元信息,以备后用沿着当前 RDD 的父 RDD 遵循广度优先搜索算法继续回溯 DAG拿土豆工坊来说,其尾节点 flavouredBakedChipsRDD 同时依赖 bakedChipsRDD 和 flavoursRDD 两个父 RDD,且依赖类型都是 ShuffleDependency,那么依据 DAGScheduler 的执行逻辑,此时会执行如下 3 项具体操作:
DAGScheduler 回溯 DAG 过程当中遇到 ShuffleDependency 时的主要操作流程
DAGScheduler 沿着尾节点回溯并划分出 stage0
在完成第一个 Stage(stage0)的创建和注册之后,DAGScheduler 先沿着 bakedChipsRDD 方向继续向前回溯。在沿着这条路向前跑的时候,我们的这位 DAGScheduler 向导官惊喜地发现:“我去!这一路上一马平川、风景甚好,各个驿站之间什么障碍都没有,交通甚是顺畅,真是片好地形!”—— 沿路遇到的所有 RDD(bakedChipsRDD,chipsRDD,cleanedPotatosRDD,potatosRDD)的依赖类型都是 NarrowDependency。
在回溯完毕时,DAGScheduler 同样会重复上述 3 个步骤,根据 DAGScheduler 以 Shuffle 为边界划分 Stage 的原则,沿途的所有 RDD 都划归为同一个 Stage,暂且记为 stage1。值得一提的是,Stage 对象的 rdd 属性对应的数据类型是 RDD[],而不是 List[RDD[]]。对于一个逻辑上包含多个 RDD 的 Stage 来说,其 rdd 属性存储的是路径末尾的 RDD 节点,具体到我们的案例中就是 bakedChipsRDD。
DAGScheduler 沿着 bakedChipsRDD 方向回溯并划分出 stage1
勤勤恳恳的 DAGScheduler 在成功创建 stage1 之后,依然不忘初心、牢记使命,继续奔向还未探索的路线。从上图中我们清楚地看到整块地形还剩下 flavoursRDD 方向的路径没有纳入 DAGScheduler 的视野范围。咱们的这位 DAGScheduler 向导官记性相当得好,早在划分 stage0 的时候,他就用小本子(栈)记下:“此路口有分叉,先沿着 bakedChipsRDD 方向走,然后再回过头来沿着 flavoursRDD 的方向探索。切记,切记!”此时,向导大人拿出之前的小本子,用横线把 bakedChipsRDD 方向的路径划掉 —— 表示该方向路径已探索过,然后沿着 flavoursRDD 方向大踏步地走下去。一脚下去,发现:“我去!到头儿了!”,然后紧接着执行一贯的“三招一套”流程 —— 创建 Stage、注册 Stage、继续回溯。随着 DAGScheduler 创建最后一个 Stage:stage2,地形上的所有路径都已探索完毕。
下一篇:返回列表
相关链接 |
||
网友回复(共有 0 条回复) |