簡體   English   中英

Spark Kryo編碼器ArrayIndexOutOfBoundsException

[英]Spark kryo encoder ArrayIndexOutOfBoundsException

我正在嘗試使用spark和esri創建包含一些地理數據的數據集。 如果Foo僅具有Point字段,它將起作用,但是如果我在Point之外添加其他字段,則會得到ArrayIndexOutOfBoundsException。

import com.esri.core.geometry.Point
import org.apache.spark.sql.{Encoder, Encoders, SQLContext}
import org.apache.spark.{SparkConf, SparkContext}

object Main {

  case class Foo(position: Point, name: String)

  object MyEncoders {
    implicit def PointEncoder: Encoder[Point] = Encoders.kryo[Point]

    implicit def FooEncoder: Encoder[Foo] = Encoders.kryo[Foo]
  }

  def main(args: Array[String]): Unit = {
    val sc = new SparkContext(new SparkConf().setAppName("app").setMaster("local"))
    val sqlContext = new SQLContext(sc)
    import MyEncoders.{FooEncoder, PointEncoder}
    import sqlContext.implicits._
    Seq(new Foo(new Point(0, 0), "bar")).toDS.show
  }
}

線程“主”中的異常java.lang.ArrayIndexOutOfBoundsException:org.apache.spark.sql.execution.Queryable $$ anonfun $ formatString $ 1 $$ anonfun $ apply $ 2.apply(Queryable.scala:71)處為1 .spark.sql.execution.Queryable $$ anonfun $ formatString $ 1 $$ anonfun $ apply $ 2.apply(Queryable.scala:70)在scala.collection.TraversableLike $ WithFilter $$ anonfun $ foreach $ 1.apply(TraversableLike.scala: 772)在scala.collection.mutable.ResizableArray $ class.foreach(ResizableArray.scala:59)在scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47)在scala.collection.TraversableLike $ WithFilter.foreach(TraversableLike .scala:771)at org.apache.spark.sql.execution.Queryable $$ anonfun $ formatString $ 1.apply(Queryable.scala:70)at org.apache.spark.sql.execution.Queryable $$ anonfun $ formatString $ 1 .apply(Queryable.scala:69)在scala.collection.mutable.ArraySeq.foreach(ArraySeq.scala:73)在org.apache.spark.sql.execution.Queryable $ class.formatString(Queryable.scala:69)在org.apache.spark.sql.Dataset.formatS 在org.apache.spark.sql.Dataset.showString(Dataset.scala:263)處tring(Dataset.scala:65)在org.apache的org.apache.spark.sql.Dataset.show(Dataset.scala:230)處位於org.apache.spark.sql.Dataset.show(Dataset.scala:201)的.spark.sql.Dataset.show(Dataset.scala:193)位於Main.main的Main $ .main(Main.scala:24) (Main.scala)

Kryo基於Spark SQL數據類型為復雜數據類型創建編碼器。 因此,請檢查kryo創建的架構的結果:

val enc: Encoder[Foo] = Encoders.kryo[Foo]
println(enc.schema)  // StructType(StructField(value,BinaryType,true))
val numCols = schema.fieldNames.length // 1

因此,您在數據集中擁有一列數據,並且它是二進制格式。 但是奇怪的是,為什么Spark試圖在多列中顯示數據集(並發生該錯誤)。 要解決此問題,請將Spark版本升級到2.0.0。

通過使用Spark 2.0.0,您仍然對列數據類型有疑問。 我希望如果您可以為esri Point類編寫StructType,則可以編寫手動模式進行工作:

val schema = StructType(
   Seq(
     StructField("point", StructType(...), true), 
     StructField("name", StringType, true)
   )
)

val rdd = sc.parallelize(Seq(Row(new Point(0,0), "bar")))

sqlContext.createDataFrame(rdd, schema).toDS

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM