商洛市建设工程造价管理站网站,网站建设一般多少钱新闻,广告联盟网站建设,健身器材 网站模版repartition只是coalesce接口中shuffle为true的实现。不经过 shuffle#xff0c;也就是coaleasce shuffle为false#xff0c;是无法增加RDD的分区数的#xff0c;比如你源RDD 100个分区#xff0c;想要变成200个分区#xff0c;只能使用repartition#xff0c;也就是coal…repartition只是coalesce接口中shuffle为true的实现。不经过 shuffle也就是coaleasce shuffle为false是无法增加RDD的分区数的比如你源RDD 100个分区想要变成200个分区只能使用repartition也就是coaleasce shuffle为true。如果上游为Partition个数为N下游想要变成M个Partition。
N M , 比如N100 M60, 可以使用coaleasce shuffle为false。 但是如果N远大于M比如N100, M1, 分区有一个激烈的变化时此时如果用coalesce就只有一个task处理数据资源利用不够Executor空跑这时repartition是一个比较好的选择虽然有shuffle但是和只有1个Task处理任务比起来效率还是较高。N M , coaleasce shuffle为false 不能增加分区只能用repartition。
一、spark 分区 partition的理解 spark中是以vcore级别调度task 如果读取的是hdfs那么有多少个block就有多少个partition
举例来说sparksql 要读表T, 如果表T有1w个小文件那么就有1w个partition
这时候读取效率会较低。假设设置资源为 --executor-memory 2g --executor-cores 2 --num-executors 5。 步骤是 拿出1-10号10个小文件也就是10个partition 分别给5个executor读取spark调度会以vcore为单位实际就是5个executor10个task读10个partition如果5个executor执行速度相同再拿11-20号文件 依次给这5个executor读取而实际执行速度不会完全相同那就是哪个task先执行完哪个task领取下一个partition读取执行以此类推。这样往往读取文件的调度时间大于读取文件本身而且会频繁打开关闭文件句柄浪费较为宝贵的io资源执行效率也大大降低。 二、coalesce 与 repartition的区别我们下面说的coalesce都默认shuffle参数为false的情况 repartition(numPartitions:Int):RDD[T]和coalesce(numPartitions:Intshuffle:Booleanfalse):RDD[T]
repartition只是coalesce接口中shuffle为true的实现 我们还拿上面的例子说 有1w的小文件资源也为--executor-memory 2g --executor-cores 2 --num-executors 5。 repartition(4)产生shuffle。这时会启动5个executor像之前介绍的那样依次读取1w个分区的文件然后按照某个规则%4,写到4个文件中这样分区的4个文件基本毫无规律比较均匀。coalesce(4)这个coalesce不会产生shuffle。那启动5个executor在不发生shuffle的时候是如何生成4个文件呢其实会有1个或2个或3个甚至更多的executor在空跑具体几个executor空跑与spark调度有关与数据本地性有关与spark集群负载有关他并没有读取任何数据 PS 如果结果产生的文件数要比源RDD partition少用coalesce是实现不了的例如有4个小文件4个partition你要生成5个文件用coalesce实现不了也就是说不产生shuffle无法实现文件数变多。如果你只有1个executor1个core源RDD partition有5个你要用coalesce产生2个文件。那么他是预分partition到executor上的例如0-2号分区在先executor上执行完毕3-4号分区再次在同一个executor执行。其实都是同一个executor但是前后要串行读不同数据。与用repartition(2)在读partition上有较大不同串行依次读0-4号partition 做%2处理。 三、实例 T表有10G数据 有100个partition 资源也为--executor-memory 2g --executor-cores 2 --num-executors 5。我们想要结果文件只有一个 如果用coalescesql(select * from T).coalesce(1) 5个executor 有4个在空跑只有1个在真正读取数据执行这时候效率是极低的。所以coalesce要慎用而且它还用产出oom问题这个我们以后再说。 如果用repartitionsql(select * from T).repartition(1) 这样效率就会高很多并行5个executor在跑10个task,然后shuffle到同一节点最后写到一个文件中。 那么如果我不想产生一个文件了我想产生10个文件会怎样是不是coalesce 又变得比 repartition高效了呢。(因为coalesce无shuffle相当于每个executor的 task认领 10个 partition) 那么如果我又不想产生10个文件呢其实一旦要产生的文件数大于executor x vcore数coalesce效率就更高(一般是这样不绝对)。 四、总结 我们常认为coalesce不产生shuffle会比repartition 产生shuffle效率高而实际情况往往要根据具体问题具体分析coalesce效率不一定高有时还有大坑大家要慎用。 coalesce 与 repartition 他们两个都是RDD的分区进行重新划分repartition只是coalesce接口中shuffle为true的实现假设源RDD有N个分区需要重新划分成M个分区
1如果NM。一般情况下N个分区有数据分布不均匀的状况利用HashPartitioner函数将数据重新分区为M个这时需要将shuffle设置为true(repartition实现,coalesce也实现不了)。
2如果NM并且N和M相差不多(假如N是1000M是100)那么就可以将N个分区中的若干个分区合并成一个新的分区最终合并为M个分区这时可以将shuff设置为falsecoalesce实现如果MN时coalesce是无效的不进行shuffle过程父RDD和子RDD之间是窄依赖关系无法使文件数(partiton)变多。
总之如果shuffle为false时如果传入的参数大于现有的分区数目RDD的分区数不变也就是说不经过shuffle是无法将RDD的分区数变多的
3如果NM并且两者相差悬殊这时你要看executor数与要生成的partition关系如果executor数 要生成partition数coalesce效率高反之如果用coalesce会导致(executor数-要生成partiton数)个excutor空跑从而降低效率。如果在M为1的时候为了使coalesce之前的操作有更好的并行度可以将shuffle设置为true。 参考Spark repartition和coalesce的区别 - 简书