2017-01-21 8 views
2

Я использую HashPartioner, но получаю неожиданный результат. Я использую 3 разных строки в качестве ключей и даю параметр раздела как 3, поэтому я ожидаю 3 раздела.Spark HashPartitioner Неожиданное разбиение на разделы

val cars = Array("Honda", "Toyota", "Kia") 

val carnamePrice = sc.parallelize(for { 
x <- cars 
y <- Array(100,200,300) 
} yield (x, y), 8) 
val rddEachCar = carnamePrice.partitionBy(new HashPartitioner(3)) 
val mapped = rddEachCar.mapPartitionsWithIndex{ 
       (index, iterator) => { 
        println("Called in Partition -> " + index) 
        val myList = iterator.toList 

        myList.map(x => x + " -> " + index).iterator 
       } 
      } 
mapped.take(10) 

Результат приведен ниже. Он дает только 2 раздела. Я проверил хэш-коды для строки (69909220 75427 -1783892706). Что может быть проблемой здесь? Возможно, я неправильно понял алгоритм разбиения.

Array[String] = Array((Toyota,100) -> 0, (Toyota,200) -> 0, (Toyota,300) -> 0, (Honda,100) -> 1, (Honda,200) -> 1, (Honda,300) -> 1, (Kia,100) -> 1, (Kia,200) -> 1, (Kia,300) -> 1) 

ответ

2

Здесь нет ничего странного. Utils.nonNegativeMod, который используется HashPartitioner реализуется следующим образом:

def nonNegativeMod(x: Int, mod: Int): Int = { 
    val rawMod = x % mod 
    rawMod + (if (rawMod < 0) mod else 0) 
} 

С 3 разделов ключ распределения определяется как показано ниже:

for { car <- Seq("Honda", "Toyota", "Kia") } 
    yield (car -> nonNegativeMod(car.hashCode, 3)) 
Seq[(String, Int)] = List((Honda,1), (Toyota,0), (Kia,1)) 

это именно то, что вы получаете в вашем случае , Другими словами, отсутствие прямого столкновения хешей не гарантирует отсутствие столкновения по модулю произвольного числа.

 Смежные вопросы

  • Нет связанных вопросов^_^