在什么情况下,散列分区比Spark中的范围分区更受欢迎?

Ano*_*non 10 performance partitioning apache-spark rdd

我已经阅读了有关散列分区的各种文章.但我仍然不知道在什么情况下它比范围分区更有利.使用sortByKey后跟范围分区允许数据在集群中均匀分布.但在散列分区中可能不是这种情况.请考虑以下示例:

考虑一对带有键[8,96,240,400,401,800]的RDD,所需的分区数为4.

在这种情况下,散列分区在分区之间按如下方式分配密钥:

partition 0: [8, 96, 240, 400, 800]
partition 1: [ 401 ]
partition 2: []
partition 3: [] 
Run Code Online (Sandbox Code Playgroud)

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

由于密钥不是均匀分布在所有节点上,因此上述分区会导致性能下降.由于范围分区可以在集群中平均分配密钥,那么在什么情况下散列分区被证明最适合范围分区?

use*_*411 11

虽然弱点hashCode是一些问题,特别是在处理小整数时,通常可以通过根据领域特定知识调整分区数来解决.也可以使用更合适的散列函数将default替换HashPartitioner为custom Partitioner.只要没有数据偏差,散列分区在平均规模上表现得非常好.

数据偏差是完全不同的问题.如果密钥分发严重偏差,则无论使用什么,分区数据的分发都可能会发生偏差Partitioner.例如,考虑以下RDD:

sc.range(0, 1000).map(i => if(i < 9000) 1 else i).map((_, None))
Run Code Online (Sandbox Code Playgroud)

它根本无法统一分区.

为什么不RangePartitioner默认使用?

这让我们回到你的问题:

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

散列分区是许多系统中的默认方法,因为它相对不可知,通常表现得相当好,并且不需要有关数据分布的其他信息.在缺乏关于数据的任何先验知识的情况下,这些属性使其成为优选的.