2016-09-28 3 views
1

Я хочу использовать Array [Byte] как ключ от RDD. Например:Как использовать массив байтов в качестве ключа в RDD?

val rdd1:RDD[((Array[Byte]), (String, Int)] = from src rdd 
val rdd2:RDD[((Array[Byte]), (String, Int)] = from dest rdd 

val resultRdd = rdd1.join(rdd2) 

Я хочу, чтобы выполнить операцию соединения на rdd1 и rdd2 с помощью Array [Byte] как Key но всегда получать resultRdd.count() = 0.

Так что я попытался сериализовать массив [Byte] и работает отлично, как я хочу видеть, только для небольшого набора данных.

val serRdd1= rdd1.map { case (k,v) => (new SerByteArr(k), v) } 
val serRdd2= rdd2.map { case (k,v) => (new SerByteArr(k), v) } 

class SerByteArr(val bytes: Array[Byte]) extends Serializable { 
    override val hashCode = bytes.deep.hashCode 
    override def equals(obj:Any) = obj.isInstanceOf[SerByteArr] && obj.asInstanceOf[SerByteArr].bytes.deep == this.bytes.deep 
} 

Для большого набора данных, получение java.lang.OutOfMemoryError: GC предела накладных превышен, Проблемы является встречающейся в создании объекта (новый SerByteArr (к)).

Как избежать предела GC превышают ошибку. Кто-нибудь мне помогает?

+1

Насколько велики ваши массивы? Было бы разумно заменить их хешем? – maasg

ответ

1

Вы можете использовать встроенную оболочку scala для массивов, WrappedArray[Byte]. Массив может быть преобразован в WrappedArray с помощью метода toSeq. WrappedArray правильно выполнил equals и hashCode, поэтому два разных массива с одинаковыми элементами считаются равными.

scala> val a = Array(1,2,3,4,5) 
a: Array[Int] = Array(1, 2, 3, 4, 5) 

scala> val b = Array(1,2,3,4,5) 
b: Array[Int] = Array(1, 2, 3, 4, 5) 

scala> a == b 
res0: Boolean = false 

scala> a.toSeq 
res1: Seq[Int] = WrappedArray(1, 2, 3, 4, 5) 

scala> a.toSeq == b.toSeq 
res2: Boolean = true 
Смежные вопросы