Apache spark 火花分离器碰撞机制?

Apache spark 火花分离器碰撞机制?,apache-spark,pyspark,Apache Spark,Pyspark,有人知道Spark HashPartitioner是否有自动冲突机制来为新分区分配密钥吗?也就是说,如果我有非常倾斜的数据,其中一个键包含许多记录 分区=哈希(键)%num\u分区 我将在同一个分区中放入许多内存无法保存的记录。在本例中,HashPartitioner是否具有类似于探测的功能来将记录分配给新分区,还是没有?如果没有,我是否需要实现一个定制的分区器来处理倾斜的键?非常感谢。我认为HashPartitioner不会在任何情况下将具有相同密钥的记录放在两个不同的分区中。for part

有人知道Spark HashPartitioner是否有自动冲突机制来为新分区分配密钥吗?也就是说,如果我有非常倾斜的数据,其中一个键包含许多记录

分区=哈希(键)%num\u分区


我将在同一个分区中放入许多内存无法保存的记录。在本例中,HashPartitioner是否具有类似于探测的功能来将记录分配给新分区,还是没有?如果没有,我是否需要实现一个定制的分区器来处理倾斜的键?非常感谢。

我认为HashPartitioner不会在任何情况下将具有相同密钥的记录放在两个不同的分区中。for partitioner明确表示:

一个对象,用于定义键-值对RDD中的元素的使用方式 按键划分的。将每个键映射到一个分区ID,从0到 数量-1

注意,partitioner必须是确定性的,即它必须返回 给定相同分区密钥的相同分区id

如果您不需要将具有相同键的记录放在同一分区中,那么您可以在不实现自定义分区器的情况下尝试以下操作

  • 假设您想将数据帧写入1000个文件
  • 向数据帧中添加一个随机整数介于0到999之间的新列。
    _num_output_files = 1000
    df = df.withColumn('rand', round(rand() * (_num_output_files-1), 0).astype(IntegerType()))
    
  • WLG,假设rand列是数据帧中的第i列。我们需要使用该列作为rdd的键,然后按该键进行分区。这将确保数据几乎均匀地分布在所有分区上。下面的代码片段将实现这一点

    tmp_rdd = df.rdd.keyBy(lambda x: x[i-1])
    tmp_rdd = tmp_rdd.partitionBy(_num_output_files, lambda x: x)
    df_rdd = spark.createDataFrame(tmp_rdd.map(lambda x: x[1]))
    
  • 注意:这是一个方便的代码片段,用于检查Pyspark中跨分区记录的当前分布:
    print('partition distrib:'+str(df_rdd.rdd.glom().map(len.collect())
    。调用前一组方法后,您应该在每个分区中看到大致相同的数字