作业:
1.map与mapPartitions的区别
(1)map是对rdd中的每一个元素进行操作;mapPartitions则是对rdd中的每个分区的迭代器进行操作
(2)如果是普通的map,比如一个partition中有1万条数据。ok,那么你的function要执行和计算1万次。使用MapPartitions操作之后,一个task仅仅会执行一次function,function一次接收所有的partition数据。只要执行一次就可以了,性能比较高。SparkSql或DataFrame默认会对程序进行mapPartition的优化。
(3)普通的map操作通常不会导致内存的OOM异常,因为可以将已经处理完的1千条数据从内存里面垃圾回收掉。 但是MapPartitions操作,对于大量数据来说,将一个partition的数据一次传入一个function以后,那么可能一下子内存不够,但是又没有办法去腾出内存空间来,可能就OOM,内存溢出。
2.coalesce与repartition两个算子的作用以及区别与联系
作用: 重新分区。
区别:repartition一定会发生shuffle,coalesce根据传入的参数来判断是否发生shuffle
一般情况下增大rdd的partition数量使用repartition,减少partition数量时使用coalesce
联系: repartition底层调用的就是coalesce,但是shuffle参数设置的是true,表示执行shuffle的重新分区。
3.使用zip算子时需要注意的是什么(即哪些情况不能使用)
在scala集合中,zip函数即使两个集合元素数量不相同, 也可以进行zip操作,但是多余的元素不会被返回。
但是在Spark RDD算子中,zip算子只能操作两个分区数和元素数量都一致的RDD。
4.reduceBykey跟groupBykey之间的区别
reduceByKey:按照key进行聚合,在shuffle之前, 会对分区内数据进行预聚合操作,返回的结果是k-v类型的RDD (RDD[K,V])
groupByKey:按照key进行分组,直接进行shuffle。返回的结果是k-迭代器类型的RDD(RDD[K,Iterable[V])
在不影响业务逻辑的情况下,优先使用reduceByKey。 求和操作不影响业务逻辑,求平均值的操作影响业务逻辑。
5.使用RDD实现Join的多种方式
rdd1.join(rdd2):将相同的key对应的value关联到-起。如果key只是某个RDD存在,那么不返回。
rdd1.leftOuterJoin(rdd2):返回rdd1中的全部key-value和关联后的key-value。
rdd1.rightOuterJoin(rdd2):返回rdd2中的全部key-value和关联后的key-value。
rdd1.cogroup(rdd2):每个rdd中先关联自己的key形成集合,然后合并。
6.aggregateBykey与aggregate之间的区别与联系
联系:两者都是对分区内和分区间的元素做聚合操作,而且都有初始值。
区别:
(1)aggregateByKey是转换算子,是对k-v类型的RDD进行操作,初始值参与分区内和分区间的计算,初始值会和RDD中每一个元素进行迭代并运算 。
(2)aggregate是行动算子,初始值参与分区内和分区间的计算,分区内计算时,初始值和RDD每个分区中的一个元素按照指定规则运算,分区间计算时,初始值只会参与一次运算。
7.reduceBykey跟aggregateBykey之间的区别与联系
联系:都是按照key做聚合操作,都会在shuffle之 前对数据做预聚合操作。
区别:reduceByKey:没有初始值,分区内和分区间的计算规则一致。
aggregateByKey:有初始值,初始值参与分区内和分区间的计算,分区内和分区间规则可以不一致。
foldByKey:有初始值,初始值 参与分区内的计算,分区内和分区间计算规则相同。