Spark UDAF-使用自定义对象类型作为bufferSchema

时间:2018-10-29 20:27:58

标签: apache-spark

我创建了一个从UDAF派生的类,我的类型为bufferSchema。它编译并提交,不幸的是在运行它时抛出CompileException。在日志中,在生成的代码中找到以下行:

arrayWriter1.write(index1, element1);

这个element1是我自己的类,当然spark没有这种签名的方法。

以下是我的代码:

class AggregateLinkResponse extends UserDefinedAggregateFunction {

  override def inputSchema: StructType = StructType(
// the input fields definition
::Nil
  )

  override def bufferSchema: StructType = StructType(
    StructField("xxx", MapType(IntegerType, ObjectType(classOf[MyOwnClass])))::Nil
  )

  override def dataType: DataType = StringType

  override def deterministic: Boolean = true

  override def initialize(buffer: MutableAggregationBuffer): Unit = {
    buffer(0) = Map[Int, MyOwnClass]()
  }

  override def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
    val responses : Map[Int, MyOwnClass] = buffer.getAs[Map[Int, MyOwnClass]](0)
// Get the input field values
// The logic to merge to buffer
    buffer(0) = responses
  }

  override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
    val response1 : Map[Int, MyOwnClass] = buffer1.getAs[Map[Int, MyOwnClass]](0)
    val response2 : Map[Int, MyOwnClass] = buffer2.getAs[Map[Int, MyOwnClass]](0)

// the logic to merge

    buffer1(0) = response1
  }

  override def evaluate(buffer: Row): Any = {
    new Gson().toJson(buffer.getAs[Map[Int, MyOwnClass]](0))
  }
}

我的问题是:

  1. 如果可以在bufferSchema中使用我自己的类,怎么办?
  2. 如果不允许,我知道两个选择:

    a。我可以将缓冲区对象序列化为字节或json,然后每次将其反序列化。

    b。使用预定义的Spark类型(包括几种ArrayType)来定义复杂的bufferSchema。

哪个选项具有更好的性能,a或b?中间对象中数组的长度会改变,并且会越来越长。我从人们那里听说每次都复制ArrayType。性能损失大吗?

0 个答案:

没有答案