groupByKey和combineByKey算子底层都是调用了combineByKeyWithClassTag方法,区别在于各自方法的传入的参数mapSideCombine 不同,改参数不同的区别在于是否在map端进行聚合;
groupByKey 的参数mapSideCombine = false
combineByKey的参数mapSideCombine = true
两者各自的使用不多介绍,网上可以看到很多,这里简单分享一个使用两者时遇到的问题
(1)图1所示,在使用groupByKey时,关注stage3 到stage5过程,stage3输出数据大小为:45.2M;再关注一个时间:stage3的Duration为4s;
(2)图2所示,在使用combineByKey时,同样关注stage3到stage5的过程,此时stage3的输出数据大小为:24.0M;再关注stage的Duration为3s;
简单分析:
对比两者可以发现stage3阶段输出数据量减少了21.2M,运行时间少了1s;stage5 shuffle read 耗时减少了2s,这在发生shuffle大量读取时,使用combineByKey性能会比groupByKey好;一个提前聚合,避免了shuffle 传输量,第二个是shuffle read 后可能会减少数据分析量,减少对内存的消耗;
问题:
其中在自定义combineByKey的3个函数时,第一次使用ObjectIterator作为返回对象时,stage3的shuffle write 数据大小为26.2M;第二次改用了Iterable作为返回对象时,stage3的shuffle write 数据大小为24M,减少了2.2M,俗话说fastutil的API不是优化的么,为什么shuffle write 会增加了呢?