Spark Catalyst flatMapGroupsWithState:具有排序集合的组状态

时间:2018-11-05 17:18:07

标签: scala apache-spark spark-structured-streaming

我正在尝试在组状态下进行排序的集合,并且从催化剂中得到一个错误,我认为这是该集合的默认实例创建。

下面是演示错误的简化管道:

package com.example

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions._
import org.apache.spark.sql.streaming.{GroupState, GroupStateTimeout, OutputMode, Trigger}

import scala.collection.immutable.TreeMap

case class Event
(
  key: String
)

case class KeyState
(
  prop: TreeMap[Long, String]
)

object CatalystIssue {

  def updateState(k: String, vs: Iterator[Event], 
    state: GroupState[KeyState]) : Iterator[Event] = vs

  def main(args: Array[String]) {
    val spark = SparkSession.builder()
      .master("local[*]")
      .appName("CatalystIssue")
      .getOrCreate()

    import spark.implicits._

    val df = spark.readStream.format("rate")
      .load()
      .select(lit("a").as("key"))
      .as[Event]
      .groupByKey(_.key)
      .flatMapGroupsWithState(OutputMode.Append(),
         GroupStateTimeout.NoTimeout())(updateState)

    val query = df.writeStream.format("console")
      .trigger(Trigger.ProcessingTime("30 seconds")).start()

    query.awaitTermination()
  }
}

哪个会产生错误:

ERROR org.apache.spark.sql.catalyst.expressions.codegen.CodeGenerator - failed to compile: org.codehaus.commons.compiler.CompileException: File 'generated.java', Line 53, Column 106: No applicable constructor/method found for zero actual parameters; candidates are: "public scala.collection.mutable.Builder scala.collection.generic.SortedMapFactory.newBuilder(scala.math.Ordering)"

这可能是因为dataframe attribute type不支持Sorted Maps,尽管这不是我的意图,并且我本以为KeyState会不透明,因为您实际上并不像dataframe属性那样访问它

虽然不是很吸引人,但是一个选择可能是将排序后的集合序列化为一个字节数组,该数组是KeyState的属性。即

case class KeyState
(
  prop: Array[Byte]
)

如果使用Java序列化,是否可以保留TreeMap的内部树结构,以便至少不必重建该树结构?是否有其他替代序列化技术可以保留结构?

能够将某些排序的集合保持在组状态似乎很有用,尤其是因为计算应该主要在内存中进行。火花的工作方式是否有某种本质上使其不可行的方法?

0 个答案:

没有答案