皮皮网
皮皮网

【小度农庄源码】【源码安装httped】【vb源码战】reducebykey源码解析

来源:物流抢单源码 发表时间:2024-12-22 16:35:57

1.reduceByKey与groupByKey的区别
2.宽依赖和窄依赖的区别
3.groupByKey、reduceByKey、aggregateByKey区别
4.reducebykey和groupbykey的区别
5.RDD(二):RDD算子

reducebykey源码解析

reduceByKey与groupByKey的区别

       reduceByKey:按照key进行聚合,在shuffle之前有个聚合操作,返回结果是RDD【k,码解v】

        groupByKey:按照key进行分组,直接进行shuffle

        开发指导:建议使用reduceByKey,但需要注意是否会影响业务逻辑

宽依赖和窄依赖的区别

       1. 窄依赖与宽依赖

       é’ˆå¯¹ä¸åŒçš„转换函数,RDD之间的依赖关系分为窄依赖(narrow dependency)和宽依赖(wide dependency,也成shuffle dependency)。

       1.1 窄依赖

       çª„依赖是指1个父RDD分区对应1个子RDD的分区。换句话说,一个父RDD的分区对应于一个子RDD的分区,或者多个父RDD的分区对应于一个子RDD的分区。所以窄依赖又可以分为两种情况:

       1个子RDD的分区对应于1个父RDD的分区,比如map,filter,union等算子

       1个子RDD的分区对应于N个父RDD的分区,比如co-partioned join

       1.2 宽依赖

       å®½ä¾èµ–是指1个父RDD分区对应多个子RDD分区。宽依赖有分为两种情况

       1个父RDD对应非全部多个子RDD分区,比如groupByKey,reduceByKey,sortByKey

       1个父RDD对应所有子RDD分区,比如未经协同划分的join

       çª„依赖与宽依赖.png

       æ€»ç»“:如果父RDD分区对应1个子RDD的分区就是窄依赖,否则就是宽依赖。

       2. 为什么Spark将依赖分为窄依赖和宽依赖

       2.1 窄依赖(narrow dependency)

       å¯ä»¥æ”¯æŒåœ¨åŒä¸€ä¸ªé›†ç¾¤Executor上,以pipeline管道形式顺序执行多条命令,例如在执行了map后,紧接着执行filter。分区内的计算收敛,不需要依赖所有分区的数据,可以并行地在不同节点进行计算。所以它的失败回复也更有效,因为它只需要重新计算丢失的parent partition即可

       2.2 宽依赖(shuffle dependency)

       åˆ™éœ€è¦æ‰€æœ‰çš„父分区都是可用的,必须等RDD的parent partition数据全部ready之后才能开始计算,可能还需要调用类似MapReduce之类的操作进行跨节点传递。从失败恢复的角度看,shuffle dependency牵涉RDD各级的多个parent partition。

       3. DAG

       RDD之间的依赖关系就形成了DAG(有向无环图)

       åœ¨Spark作业调度系统中,调度的前提是判断多个作业任务的依赖关系,这些作业任务之间可能存在因果的依赖关系,也就是说有些任务必须先获得执行,然后相关的依赖人物才能执行,但是任务之间显然不应出现任何直接或间接的循环依赖关系,所以本质上这种关系适合用DAG表示

       4. stage划分

       ç”±äºŽshuffle依赖必须等RDD的父RDD分区数据全部可读之后才能开始计算,因此Spark的设计是让父RDD将结果写在本地,完全写完之后,通知后面的RDD。后面的RDD则首先去读之前RDD的本地数据作为输入,然后进行运算。

       ç”±äºŽä¸Šè¿°ç‰¹æ€§ï¼Œè®²shuffle依赖就必须分为两个阶段(stage)去做:

       ï¼ˆ1)第1个阶段(stage)需要把结果shuffle到本地,例如reduceByKey,首先要聚合某个key的所有记录,才能进行下一步的reduce计算,这个汇聚的过程就是shuffle。

       (2) 第二个阶段(stage)则读入数据进行处理。

       ä¸ºä»€ä¹ˆè¦å†™åœ¨æœ¬åœ°ï¼Ÿ

       åŽé¢çš„RDD多个分区都要去读这个信息,如果放到内存,假如出现数据丢失,后面所有的步骤全部不能进行,违背了之前所说的需要父RDD分区数据全部ready的原则。

       åŒä¸€ä¸ªstage里面的task是可以并发执行的,下一个stage要等前一个stage ready(和map reduce的reduce需要等map过程ready一脉相承)。

       Spark 将任务以 shuffle 依赖(宽依赖)为边界打散,划分多个 Stage. 最后的结果阶段叫做 ResultStage, 其它阶段叫 ShuffleMapStage, 从后往前推导,依将计算。

       RDD的划分.png

       1.从后往前推理,遇到宽依赖就断开,遇到窄依赖就把当前RDD加入到该Stage

       2.每个Stage里面Task的数量是由该Stage中最后一个RDD的Partition的数量所决定的。

       3.最后一个Stage里面的任务类型是ResultTask,前面其他所有的Stage的任务类型是ShuffleMapTask。

       4.代表当前Stage的算子一定是该Stage的最后一个计算步骤

       è¡¨é¢ä¸Šçœ‹æ˜¯æ•°æ®åœ¨æµåŠ¨ï¼Œå®žè´¨ä¸Šæ˜¯ç®—子在流动。

groupByKey、reduceByKey、aggregateByKey区别

       ä¸‰è€…都可以做分组操作。reduceByKey、aggregateByKey不但分组还做了聚合操作

        groupByKey直接进行shuffle操作,数据量大的时候速度较慢。

        reduceByKey、aggregateByKey在shuffle之前可能会先进行聚合,聚合后的数据再进行shuffle,这样一来进行shuffle的数据会变少,速度会快。

        reduceByKey、aggregateByKey的区别是前者不同partition以及partition之间的聚合操作是一样的,而后者可以指定两种操作来对应于partition之间和partition内部不同的聚合操作,并且aggregateByKey可以指定初始值。

        在aggregateByKey中,如果两种操作是一样的,可以使用foldByKey来代替,并且只传一个操作函数。foldBykey和reudceBykey的区别是前者可以指定一个初始值。

reducebykey和groupbykey的区别

       reduceByKey用于对每个key对应的多个value进行merge操作,最重要的是它能够在本地先进行merge操作,并且merge操作可以通过函数自定义。

       groupByKey也是对每个key进行操作,但只生成一个sequence。需要特别注意“Note”中的话,它告诉我们:如果需要对sequence进行aggregation操作(注意,groupByKey本身不能自定义操作函数),那么,选择reduceByKey 比 aggregateByKey更好。这是因为groupByKey不能自定义函数,我们需要先用groupByKey生成RDD,然后才能对此RDD通过map进行自定义函数操作。

RDD(二):RDD算子

       本文主要探讨RDD算子的概念及其应用,包括本地对象的码解API、分布式对象的码解API(Transformation和Action算子)以及各类算子的功能和特性。在RDD的码解使用中,Transformation算子和Action算子共同构成了数据处理的码解核心。

       Transformation算子用于处理数据并生成新的码解小度农庄源码RDD,如map、码解flatMap、码解reduceByKey、码解mapValues、码解groupBy等。码解这些算子在生成新RDD时,码解其逻辑基于接收的码解源码安装httped处理函数,如map算子将数据一条条处理,码解flatMap进行Map操作后解除嵌套,码解reduceByKey对KV型RDD进行自动分组并完成组内聚合操作。

       Action算子则与Transformation算子不同,其返回值非RDD,如countByKey、vb源码战collect、reduce、fold、first、take、top、商城的源码count、takeSample、takeOrdered、foreach、saveAsTextFile。Action算子用于执行指令,快手 android 源码如计算统计信息或输出结果至本地文件。collect算子特别需要注意,它将所有分区数据收集至Driver中,若数据量过大,可能会导致内存溢出。

       分区操作算子包括MapPartition和ForEachPartition,前者一条条处理数据,后者一次传递整个分区数据。PartitionBy用于对KV型RDD进行自定义分区,而Repartition&Coalesce用于对RDD分区进行重新分区,但需谨慎操作以避免增加分区数量导致的Shuffle。

       在面试中,常常会问到groupByKey和reduceByKey的区别。groupByKey在进行分组之前对数据进行预聚合,从而在Shuffle分组节点减少被Shuffle的数据量,降低网络I/O开销,显著提升性能。因此,对于涉及分组+聚合的场景,推荐优先使用reduceByKey。

       本文总结了RDD算子的基本分类和特性,以及在实际应用中的注意事项,希望对理解和使用RDD提供有益的指导。

相关栏目:休闲