我正在解决数据偏差问题,因此我的最小分区低于64MB,而我最大的分区可能大于1GB。我一直在考虑将一些小分区映射到同一分区键的策略,从而创建一个由分区组成的分区。这一切都是为了减少任务大小的差异以及磁盘上存储的文件数量。
在我的Spark应用程序的某一点上,我需要对(未分组的)原始分区进行操作,并且需要按原始密钥重新分区。这让我想到了我的问题:
假设我有两个数据集,如下所示。每行都是(partition_key,(original_key,data))形式的元组。在 data0 中,您可以看到original_key = 0在其自己的节点上,而original_key = 4和original_key = 5在包含partition_key = 3的节点上。在 data1 中事情并没有那么有条理。
如果 data0 由partition_key分区,然后由original_key分区,是否会发生随机播放?换句话说,在第二个分区中是否重要?通过调用 data0 比 data1 更有条理?
data0 = [
(0, (0, 'a')),
(0, (0, 'b')),
(0, (0, 'c')),
(1, (1, 'd')),
(1, (1, 'e')),
(1, (2, 'f')),
(1, (2, 'g')),
(2, (3, 'h')),
(2, (3, 'i')),
(2, (3, 'j')),
(3, (4, 'k')),
(3, (4, 'l')),
(3, (5, 'm')),
(3, (5, 'n')),
(3, (5, 'o')),
]
data1 = [
(0, (0, 'a')),
(1, (0, 'b')),
(0, (0, 'c')),
(1, (1, 'd')),
(2, (1, 'e')),
(1, (2, 'f')),
(3, (2, 'g')),
(2, (3, 'h')),
(0, (3, 'i')),
(3, (3, 'j')),
(3, (4, 'k')),
(3, (4, 'l')),
(1, (5, 'm')),
(2, (5, 'n')),
(3, (5, 'o')),
]
rdd0 = sc.parallelize(data0, 3).cache()
partitioned0 = rdd0.partitionBy(4)
partitioned0.map(lambda row: (row[1][0], row[1])).partitionBy(6).collect()
rdd1 = sc.parallelize(data1, 3).cache()
partitioned1 = rdd1.partitionBy(4)
partitioned1.map(lambda row: (row[1][0], row[1])).partitionBy(6).collect()
答案 0 :(得分:0)
当你打电话给重新分区shuffle踢。 有多少数据被洗牌是基于原始RDD。
作为旁注:当你做sc.parallelize(data0,3)
时,3仅仅是指引。如果默认分区是< = 3,那么你的rdd0将有3个分区。如果您的data0在更多HDFS块上,则提供分区号无效。