在Spark中歪斜

时间:2019-03-27 19:08:26

标签: apache-spark hive

我有一个数据集,我想按特定的键(clientID)进行分区,但是有些客户端产生的数据远远多于其他客户端。 Hive中有一个称为“ ListBucketing”的功能,称为“ skewed by”,专门用于处理这种情况。

但是,我找不到任何迹象表明Spark支持此功能,或者如何(如果确实支持)使用此功能。

是否有与之等效的Spark功能?或者,Spark是否具有其他一些功能集可以用来复制此行为?

(作为奖励-对我的实际用例的要求-您的建议方法是否可以与Amazon Athena一起使用?)

1 个答案:

答案 0 :(得分:1)

据我所知,Spark中没有开箱即用的工具。如果数据不正确,通常会添加一个人工列以进一步对数据进行存储。

假设您要按“ y”列进行分区,但是数据却像这个玩具示例中那样非常偏斜(1个分区有5行,其他分区只有1行):

val df = spark.range(8).withColumn("y", when('id < 5, 0).otherwise('id))
df.show()
+---+---+
| id|  y|
+---+---+
|  0|  0|
|  1|  0|
|  2|  0|
|  3|  0|
|  4|  0|
|  5|  5|
|  6|  6|
|  7|  7|
+-------+

现在,我们添加一个人工随机列并写入数据框。

val maxNbOfBuckets = 3
val part_df = df.withColumn("r", floor(rand() * nbOfBuckets))
part_df.show
+---+---+---+
| id|  y|  r|
+---+---+---+
|  0|  0|  2|
|  1|  0|  2|
|  2|  0|  0|
|  3|  0|  0|
|  4|  0|  1|
|  5|  5|  2|
|  6|  6|  2|
|  7|  7|  1|
+---+---+---+

// and writing. We divided the partition with 5 elements into 3 partitions.
part_df.write.partitionBy("y", "r").csv("...")