Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 如何在reduceByKey之后不扭曲数据?_Apache Spark - Fatal编程技术网

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