spark shuffle算子

MapReduce

基于MapReduce编程思想的spark运行程序,仍然是以先运行map端程序,将map程序处理的结果溢写到磁盘,然后执行reduce端程序进行shuffle操作,对map端处理结果进行处理,得到最终结果。
spark driver端将程序创建成job后,通过DAGSchduler将其转换为DAG,然后根据shuffle算子,将其切分为多个stage,stage保证多个任务,形成taskset,然后spark dirver将其提交spark集群进行处理。
故spark以shuflle接下来为大家介绍溢写shuffle算子,如果遇到遇到这些算子,就一定会切分出新的stage,这些地方往往出现数据倾斜现象,如果遇到程序运行缓慢,可以从这个方法入手。

spark shuffule算子

分区

repartition():执行时需要进行shuffle操作
coalesce(numPartitions,shuffle=false):默认不需要shuffle
使用场景:将设RDD/DataFrame/DataSet有N个分区,若重新划分M个分区
1.N<M:一般情况下N个分区有数据分布不均匀的情况,利用HashPartitioner函数将数据重新划分M个,此时将shuffule设置true.
**重分区前后相当于宽依赖,会发生shuffle过程**,此时可以使用coalesce(shuffle=true),或reparation
2.N>M:N,M相差不多(如N是1000,M是100),那么就可以将N个分区中的若干个分区合并成一个新分区,最终为M个分区,前后是**窄依赖关系**
可以使用coalesce(shuffle=false)
3.N>M:N,M相差悬殊,此时将shuffule设置false,父子RDD是窄依赖关系,他们痛处一个stage中,就可能造成spark并行度不够,从而影响性能
如果M为1的时候,为了是coalesce之前操作有更好的并行度,可以将shuffle设置为true
注:如果传入分区数大于当前分区数,需要将shuffle设置为true,才能使RDD分区数改变。

去重

distinct():使用spark默认并行度(分区数)对筛选数据进行去重
distinct([numPartitions])):手动指定spark并行度(分区数)对筛选数据进行去重

排序

def sortByKey(ascending: Boolean = true, numPartitions: Int = self.partitions.length): RDD[(K, V)]: 对key,value类型RDD,根据key进行排序,指定是否升序排列,分区数来进行排序
def sortBy[K](f: (T) => K, ascending: Boolean = true, numPartitions: Int = this.partitions.length):RDD[(k,v)]:指定是否升序排列,分区数,排序函数进行排序

聚合

def reduceByKey(func: (V, V) => V, numPartitions: Int): RDD[(K, V)] :指定spark并行度,使用在map预聚合,减少reduce端数据shuffle量级,进行高效处理
def reduceByKey(partitioner: Partitioner, func: (V, V) => V): RDD[(K, V)]:指定spark分区类(可以是默认hashPartitioner,RangePartioner,也可以根据业务自己继承Partitioner自己实现分区规则),使用在map预聚合,减少reduce端数据shuffle量级,进行高效处理
def groupBy[K](f: T => K, p: Partitioner):RDD[(K, Iterable[V])]:根据业务方法和指定分区类对key,value对的rdd进行分组,进而得到新的RDD
def groupByKey(partitioner: Partitioner):RDD[(K, Iterable[V])]:指定分区类进行RDD数据分组,得到新的RDD
def aggregateByKey[U: ClassTag](zeroValue: U, partitioner: Partitioner): RDD[(K, U)]:根据传入参数zeroValue,分区类对数据进行聚合
def aggregateByKey[U: ClassTag](zeroValue: U, numPartitions: Int): RDD[(K, U)]:根据传入参数zeroValue,分区数量对数据进行聚合
def combineByKey[C](createCombiner: V => C, mergeValue: (C, V) => C, mergeCombiners: (C, C) => C): RDD[(K, C)]:使用预聚合函数,在map端进行预聚合,减少在reduce时shuffle时的数据量

集合操作

def intersection(other: RDD[T]): RDD[T]:与其他RDD去交集
def intersection(other: RDD[T], partitioner: Partitioner)(implicit ord: Ordering[T] = null): RDD[T] :指定取交集时的分区类,与其他RDD去交集
def intersection(other: RDD[T], numPartitions: Int): RDD[T] :指定取交集时的分区数量,与其他RDD取交集
def subtract(other: RDD[T], numPartitions: Int): RDD[T] :指定取差集时的分区数量,与其他RDD取差集
def subtract(other: RDD[T], p: Partitioner)(implicit ord: Ordering[T] = null): RDD[T]:指定取差集时的分区类,与其他RDD取差集
def subtractByKey[W: ClassTag](other: RDD[(K, W)]): RDD[(K, V)] :指定key,vaule pair的key作为取差集差的依据,与其他RDD取差集
def subtractByKey[W: ClassTag](other: RDD[(K, W)], numPartitions: Int): RDD[(K, V)]:指定key,vaule pair的key作为取差集差的依据,并设置分区数,与其他RDD取差集
def subtractByKey[W: ClassTag](other: RDD[(K, W)], p: Partitioner): RDD[(K, V)]:指定key,vaule pair的key作为取差集差的依据,并设置分区类,与其他RDD取差集
def join[W](other: RDD[(K, W)], partitioner: Partitioner): RDD[(K, (V, W))]:设置分区类,当前RDD与其他RDD取差集
def join[W](other: RDD[(K, W)]): RDD[(K, (V, W))]:设置分区类,当前RDD与其他RDD取差集
def join[W](other: RDD[(K, W)], numPartitions: Int): RDD[(K, (V, W))]:设置分区数,当前RDD与其他RDD取并集
def leftOuterJoin[W](other: RDD[(K, W)]): RDD[(K, (V, Option[W]))]:以左侧RDD依据,与其他RDD取并集,保留左侧RDD元素,将右侧RDD不在左侧RDD元素与左侧并在一起作为并集

发布了150 篇原创文章 · 获赞 15 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/dymkkj/article/details/104487948
今日推荐