繁体   English   中英

在 spark 中均匀划分一个 rdd

[英]uniformly partition a rdd in spark

我在 HDFS 中有一个文本文件,它有大约 1000 万条记录。 我正在尝试读取文件对该数据进行一些转换。 我试图在对数据进行处理之前对数据进行统一分区。 这是示例代码

var myRDD = sc.textFile("input file location")

myRDD = myRDD.repartition(10000)

当我对这个重新分区的数据进行转换时,我看到一个分区的记录数量异常多,而其他分区的数据很少。 分布图

因此,只有一个执行器的负载很高,我也尝试过并得到了相同的结果

myRDD.coalesce(10000, shuffle = true)

有没有办法在分区之间均匀分布记录。

附件是特定执行程序上的随机读取大小/记录数,圈出的执行程序比其他执行程序要处理的记录多得多

感谢您提供任何帮助。

为了处理偏差,您可以使用分发方式(或使用您使用的重新分区)重新分区您的数据。 对于要分区的表达式,请选择您知道将均匀分布数据的内容。

您甚至可以使用 DataFrame(RDD) 的主键。

即使这种方法也不能保证数据将在分区之间均匀分布。 这完全取决于我们分发的表达式的哈希值 Spark:如何在所有分区中均匀分布我的记录

可以使用加盐,其中包括添加新的“假”密钥并与当前密钥一起使用以更好地分布数据。 这里是腌制的链接

对于小数据,我发现我需要自己强制执行统一分区。 在 pyspark 中,差异很容易重现。 在这个简单的示例中,我只是尝试将 100 个元素的列表并行化为 10 个偶数分区。 我希望每个分区可以容纳 10 个元素。 相反,我得到一个不均匀的分布,分区大小从 4 到 22:

my_list = list(range(100))
rdd = spark.sparkContext.parallelize(my_list).repartition(10)
rdd.glom().map(len).collect()

# Outputs: [10, 4, 14, 6, 22, 6, 8, 10, 4, 16]

这是我使用的解决方法,即自己索引数据,然后修改索引以查找将行放入的分区:

my_list = list(range(100))
number_of_partitions = 10
rdd = (
    spark.sparkContext
    .parallelize(zip(range(len(my_list)), my_list))
    .partitionBy(number_of_partitions, lambda idx: idx % number_of_partitions)
)
rdd.glom().map(len).collect()

# Outputs: [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM