我有一个独特的案例,其中一个spark应用程序正在从源读取,对源数据应用一些转换,并生成2个文件到S3,每行1 JSON,格式如下:

file 1 - {"key": "x", "value1": "y"}

file 2 - {"key": "x", "value2": "z"}

除了在每个输出中过滤掉空值之外,上面的应用程序不进行任何连接/重新分区,因此我的期望是两者的每个分区应该具有非常相似的客户(除了为空值过滤掉的那些) .

在不同的应用程序中,我必须将两个文件一起加入密钥并将其输出到S3 . 所以最终输出看起来应该是 -

file 3 - {"key": "x", "value1": "y", "value2": "z"}

但是,在进行连接时,我认为数据将被合并(因为它们都是由上面的相同作业输出)并且不会导致完全混乱 . 但是,我看到相反的情况,因为在火花UI中有洗牌溢出,需要1.5小时才能完成 . 以下是我所知道的/正在发生的事情:

1)当我在第二个作业中读取2个文件时,因为我没有't specify a partitioner, both RDDs don' t有任何分区器 . 因此,当我反序列化每一行并将其转换为 [K,V] 元组格式时,spark将最终对数据执行shuffle散列连接 . 因此,即使它可能是 copartitioned ,数据最终也会被洗牌,因为火花不知道同样的情况 .

2)即使我为2个RDD指定了一个分区器,它仍然会在partitionBy阶段触发shuffle . 所以,我不应该看到整个应用程序的任何性能改进,即使连接应该非常快(如果错误,请纠正我) .

因此,我的问题是,是否有可能利用数据进行协作的事实(不会在整个应用程序中触发混乱)?我不知道任何Spark API也会这样做 .