如何在Spark 2.0中使用用户定义的类型?

时间:2016-08-23 08:38:05

标签: scala apache-spark user-defined-types

在Spark 2.0中,我发现在Scala中创建UDT的one example似乎不再适用。 UserDefinedType类已设置为private,评论为:

  

注意:这是以前在Spark 1.x中的开发人员API。我们在Spark 2.0中将其设为私有,因为我们很可能会创建一个与数据集一起使用的新版本。

UDTRegistration的意图可能是声明UDT的新机制,但它也是private

到目前为止,我的研究告诉我,没有办法在Spark 2.0中声明自己的UDT;这个结论是否正确?

2 个答案:

答案 0 :(得分:3)

你现在是对的,Spark 2.x已经没有任何类型的UDT可以用作Spark 1.x中的API。

您可以在此故障单SPARK-14155中看到,他们让它成为创建新API的助手。我们希望将在Spark 2.2 SPARK-7768中关闭自Spark 1.5以来打开的票证。

嗯,类型现在不适合创建你的UDT但是......你可以将自定义对象设置为DataSet的技巧很少。 Here就是一个例子。

答案 1 :(得分:0)

您可以使用UDTRegistration使UDT与Spark一起使用。 这是一种实现方法:

说您要使用多态记录:

trait CustomPoly
case class FooPoly(id:Int) extends CustomPoly
case class BarPoly(value:String, secondValue:Long) extends CustomPoly

polySeq.filter(_.poly match {
  case FooPoly(value) => value == 1
  case _ => false
}).show()

您可以编写一个自定义的UDT,将所有内容编码为字节(我在这里使用Java序列化,但是最好检测Spark的Kryo上下文)。

首先定义UDT类:

class CustomPolyUDT extends UserDefinedType[CustomPoly] {
  val kryo = new Kryo()

  override def sqlType: DataType = org.apache.spark.sql.types.BinaryType
  override def serialize(obj: CustomPoly): Any = {
    val bos = new ByteArrayOutputStream()
    val oos = new ObjectOutputStream(bos)
    oos.writeObject(obj)

    bos.toByteArray
  }
  override def deserialize(datum: Any): CustomPoly = {
    val bis = new ByteArrayInputStream(datum.asInstanceOf[Array[Byte]])
    val ois = new ObjectInputStream(bis)
    val obj = ois.readObject()
    obj.asInstanceOf[CustomPoly]
  }

  override def userClass: Class[CustomPoly] = classOf[CustomPoly]
}

然后注册:

// NOTE: The file you do this in has to be inside of the org.apache.spark package!
UDTRegistration.register(classOf[CustomPoly].getName, classOf[CustomPolyUDT].getName)

那么您就可以使用它!

// As shown above:
case class UsingPoly(id:Int, poly:CustomPoly)

Seq(
  UsingPoly(1, new FooPoly(1)),
  UsingPoly(2, new BarPoly("Blah", 123)),
  UsingPoly(3, new FooPoly(1))
).toDS

polySeq.filter(_.poly match {
  case FooPoly(value) => value == 1
  case _ => false
}).show()

在这里查看我的原始帖子,其中还有一个示例: How to store custom objects in Dataset?