Scala HashPartitioner是如何工作的?

Scala HashPartitioner是如何工作的?,scala,apache-spark,rdd,partitioning,Scala,Apache Spark,Rdd,Partitioning,我仔细阅读了他的文件。不幸的是,除了API调用之外,没有什么解释。我假设HashPartitioner基于密钥的散列对分布式集进行分区。例如,如果我的数据是 (1,1), (1,2), (1,3), (2,1), (2,2), (2,3) 所以分区程序会把它放在不同的分区中,相同的键落在相同的分区中。但是,我不理解构造函数参数的意义 new HashPartitoner(numPartitions) //What does numPartitions do? 对于上述数据集,如果我这样做,结

我仔细阅读了他的文件。不幸的是,除了API调用之外,没有什么解释。我假设
HashPartitioner
基于密钥的散列对分布式集进行分区。例如,如果我的数据是

(1,1), (1,2), (1,3), (2,1), (2,2), (2,3)
所以分区程序会把它放在不同的分区中,相同的键落在相同的分区中。但是,我不理解构造函数参数的意义

new HashPartitoner(numPartitions) //What does numPartitions do?
对于上述数据集,如果我这样做,结果会有什么不同

new HashPartitoner(1)
new HashPartitoner(2)
new HashPartitoner(10)

那么,
HashPartitioner
实际上是如何工作的呢?

RDD
是分布式的,这意味着它被分成若干部分。每个分区可能位于不同的计算机上。带参数的散列分区器
numPartitions
以以下方式选择放置对
(键、值)
的分区:

  • 准确地创建
    numPartitions
    分区
  • (键,值)
    放在带有数字
    哈希(键)%numPartitions的分区中

  • 好吧,让我们稍微让您的数据集更有趣一些:

    val rdd=sc.parallelize(用于{
    
    xHashPartitioner.getPartition
    方法将键作为其参数,并返回该键所属分区的索引。分区器必须知道有效索引是什么,因此它返回正确范围内的数字。分区数通过
    numPartitions
    构造函数参数指定


    实现返回了大约
    key.hashCode()%numPartitions
    。有关更多详细信息,请参阅。

    写得很好,谢谢。但是,我注意到在图像中,您有
    (1,无)
    hash(2)%p
    其中p是分区。它不应该是
    hash(1)%P
    ?我使用spark 2.2,rdd中没有
    partitionBy
    api。dataframe.write下有一个partitionBy,但它不使用Partitioner作为参数。有人回答说…shuffle是基于Partitioner的,一个好的Partitioner可以减少被洗牌的数据量。很棒的@dsk,如果你不指定一个键,我相信重新分区会使用Round机器人划分。一些讨论。