【问题标题】:In what scenarios hash partitioning is preferred over range partitioning in Spark?在什么情况下,哈希分区比 Spark 中的范围分区更受欢迎?
【发布时间】:2018-12-25 12:13:34
【问题描述】:

我浏览过各种关于哈希分区的文章。但是我仍然不明白在什么情况下它比范围分区更有利。使用 sortByKey 后跟范围分区允许数据在集群中均匀分布。但在散列分区中可能并非如此。考虑以下示例:

考虑一个键为 [8, 96, 240, 400, 401, 800] 的 RDD 对,并且所需的分区数是 4。

在这种情况下,哈希分区在 分区:

partition 0: [8, 96, 240, 400, 800]
partition 1: [ 401 ]
partition 2: []
partition 3: [] 

(计算分区:p = key.hashCode() % numPartitions)

上述分区导致性能不佳,因为密钥未均匀分布在所有节点上。既然范围分区可以在集群中平均分配键,那么在什么情况下哈希分区被证明是最适合范围分区的呢?

【问题讨论】:

  • 当你用来散列的键接近均匀分布时,散列分区是好的,即伪随机值会去你。

标签: performance apache-spark rdd partitioning


【解决方案1】:

虽然hashCode 的弱点令人担忧,尤其是在处理小整数时,但通常可以通过基于特定领域知识调整分区数量来解决。也可以使用更合适的散列函数将默认的HashPartitioner 替换为自定义的Partitioner。只要没有数据倾斜,散列分区在规模上的平均表现就足够好。

数据倾斜是完全不同的问题。如果密钥分布明显偏斜,则无论使用什么Partitioner,分区数据的分布都可能偏斜。例如,考虑以下 RDD:

sc.range(0, 1000).map(i => if(i < 9000) 1 else i).map((_, None))

根本无法统一划分。

为什么不默认使用RangePartitioner

  • 它不如HashPartioner 通用。虽然HashPartitioner 只需要对K 正确实现##==,但RangePartitioner 需要Ordering[K]
  • HashPartitioner不同,它必须近似数据分布,因此它是requires additional data scan
  • 由于拆分是根据特定分布计算的,因此在跨数据集重复使用时可能会不稳定。考虑以下示例:

    val rdd1 = sc.range(0, 1000).map((_, None))
    val rdd2 = sc.range(1000, 2000).map((_, None))
    
    val rangePartitioner = new RangePartitioner(11, rdd1)
    
    rdd1.partitionBy(rangePartitioner).glom.map(_.length).collect
    
    Array[Int] = Array(88, 91, 99, 91, 87, 92, 83, 93, 91, 86, 99)
    
    rdd2.partitionBy(rangePartitioner).glom.map(_.length).collect
    
    Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000)
    

    您可以想象,这对joins 等操作具有严重影响。同时

    val hashPartitioner = new HashPartitioner(11)
    
    rdd1.partitionBy(hashPartitioner).glom.map(_.length).collect
    
    Array[Int] = Array(91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90)
    
    rdd2.partitionBy(hashPartitioner).glom.map(_.length).collect
    
    Array[Int] = Array(91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 91)
    

这让我们回到您的问题:

在什么情况下它比范围分区更有利。

哈希分区是许多系统中的默认方法,因为它相对不可知,通常表现得相当好,并且不需要有关数据分布的其他信息。这些属性使它更可取,因为缺乏关于数据的任何先验知识。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 2022-07-20
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-11
    相关资源
    最近更新 更多