Apache spark Spark UDAF-使用自定义对象类型作为缓冲模式

Apache spark Spark UDAF-使用自定义对象类型作为缓冲模式,apache-spark,Apache Spark,我创建了一个从UDAF派生的类,我自己的类型是bufferSchema。它编译并提交,不幸的是,在运行它时抛出了CompileException。在日志中,在生成的代码中可以找到以下行: arraywrite1.write(index1,element1) 这个元素1是我自己的类,当然spark没有一个带有这个签名的方法 以下是我的代码: class AggregateLinkResponse extends UserDefinedAggregateFunction { override

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

arraywrite1.write(index1,element1)

这个元素1是我自己的类,当然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))
  }
}
我的问题是:

  • 如果可以在bufferSchema中使用我自己的类,怎么做
  • 如果不允许,我知道两种选择:

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

    b。使用预定义的Spark类型(包括多个ArrayTypes)定义复杂的bufferSchema


  • 哪个选项的性能更好,a还是b?中间对象中数组的长度变化,并且变得越来越长。我听说ArrayType每次都被复制。性能损失大吗?

    我也有同样的问题。。你设法解决了这个问题吗?