Apache spark 如何在reduceByKey之后不扭曲数据?
我们的Apache spark 如何在reduceByKey之后不扭曲数据?,apache-spark,Apache Spark,我们的reduceByKey操作的结果会导致一个非常扭曲的RDD,在一个或两个分区中有大量数据。为了在reduceByKey之后增加处理的并行性,我们进行了重新分区,这将强制执行洗牌 rdd.reduceByKey(_+_).repartition(64) 我知道可以将分区程序传递到reduceByKey操作中。但是(除了创建自定义分区之外),我认为选项是hashpartitioner和RangePartitioner。我认为这两种方法都会导致数据在分区后发生倾斜,因为键是唯一的 是否可以在一
reduceByKey
操作的结果会导致一个非常扭曲的RDD
,在一个或两个分区中有大量数据。为了在reduceByKey
之后增加处理的并行性,我们进行了重新分区
,这将强制执行洗牌
rdd.reduceByKey(_+_).repartition(64)
我知道可以将分区程序传递到reduceByKey
操作中。但是(除了创建自定义分区之外),我认为选项是hashpartitioner
和RangePartitioner
。我认为这两种方法都会导致数据在分区后发生倾斜,因为键是唯一的
是否可以在一个reduceByKey
中均匀地洗牌输出RDD
,而不需要额外的重新分区调用
我不知道你是否有权访问Spark用户界面。但是,如果您需要对RDD进行重新分区,我建议您使用numPartitions
这一次你可以“免费”重新调整你的rdd
如果您可以检查您的Spark UI,如果您像您所展示的那样使用:
rdd.reduceByKey(_+_).repartition(64)
您将看到reduce将完成的执行图,然后将开始重新分区过程
如果您使用:
rdd.reduceByKey(_+_, numPartitions=64)
您将看到执行将在没有任何额外作业的情况下进行
以下是使用方法:我假设您在某些区域的reduceByKey聚类后拥有密钥。例如,1,2,3,4,5,45,46,47,48,49,356,789
因此,在使用rangePartitioner时,会出现倾斜数据。但是HashPartitioner依赖于用于计算密钥散列的散列函数
(Scala RDD可以使用哈希代码,数据集使用哈希3、PySpark、portable_哈希)
现在,如果默认的hashPartitioner也给您提供了数据倾斜,那么您必须使用自定义分区器,并使用一些好的hash分区器应用hash,这些分区器肯定会生成稀疏hash,例如md5
要在spark中实现自定义分区器,您必须扩展分区器并实现3种方法:
数量
相等于
getPartition
在getPartition方法中,您可以计算密钥的md5散列,并根据numPartitions参数进行分配
您还可以查看的答案了解更多信息。您的假设:
“我认为选项是HashPartitioner和RangePartitioner。我认为这两个选项都会导致数据在分区后发生倾斜,因为键是唯一的。”
不一定正确
标准的RangePartitioner
试图通过抽样来均匀地分布数据,在我们的例子中,对于非常倾斜的数据(这取决于人的地理分布),它工作得非常好,并且均匀地分布数据
另请参见此处的说明:
因此,我建议在ReduceByKey中使用标准的RangePartitioner
编写一个小测试或日志输出,检查分区的大小。
您可以使用mapPartitionsWithIndex
收集有关分区的一些统计信息,并为日志输出提供一个Id