Pysparkling 2从1重置monotonically_increasing_id

时间:2017-09-11 22:39:16

标签: python apache-spark pyspark spark-dataframe

我想将火花数据帧分成两部分,并为每个子数据帧定义行号。但是我发现函数monotonically_increasing_id仍然会定义原始数据帧中的行号。

这是我在python中所做的:

# df is the original sparkframe
splits = df.randomSplit([7.0,3.0],400) 

# add column rowid for the two subframes
set1 = splits[0].withColumn("rowid", monotonically_increasing_id())
set2 = splits[1].withColumn("rowid", monotonically_increasing_id())

# check the results
set1.select("rowid").show()
set2.select("rowid").show()

我希望两帧的rowid的前五个元素都是1到5(或0到4,不能清楚地记得):

set1: 1 2 3 4 5
set2: 1 2 3 4 5

但实际上我得到的是:

set1: 1 3 4 7 9 
set2: 2 5 6 8 10

两个子帧的行id实际上是它们在原始sparkframe df中的行id而不是新的。

作为一个新的火花,我正在寻求帮助解决为什么会发生这种情况以及如何解决它。

1 个答案:

答案 0 :(得分:0)

首先,您使用的是什么版本的Spark? monotonically_increasing_id方法实现已更改几次。我可以在Spark 2.0中重现你的问题,但似乎火花2.2中的行为是不同的。所以它可能是一个在更新的火花释放中修复的错误。

话虽如此,您应该期望monotonically_increasing_id生成的值连续增加 。在您的代码中,我相信数据帧只有一个分区。根据{{​​3}}

  

保证生成的ID单调增加   独特,但不连续目前的实施方案   高31位中的分区ID,以及每个中的记录号   低33位分区。假设是数据框架   具有少于10亿个分区,每个分区少于8个   十亿条记录。

     

例如,考虑一个带有两个分区的DataFrame,每个分区都有3个分区   记录。该表达式将返回以下ID:0,1,2,   8589934592(1L<< 33),8589934593,8589934594。

因此,如果你的代码不应该期望rowid连续增加。

此外,您还应该考虑缓存场景和失败场景。即使monotonically_increase_id按预期工作 - 连续增加值,它仍然无法工作。如果节点出现故障怎么办?故障节点上的分区将从源或最后一个缓存/检查点重新生成,这可能具有不同的顺序,因此具有不同的rowid。逐出缓存也会导致问题。假设生成数据帧后将其缓存到内存中。如果被驱逐出内存怎么办?将来的操作将尝试再次重新生成数据帧,从而给出不同的rowid。