将Spark SQL批处理源转换为结构化流接收器

时间:2018-08-06 21:07:41

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

仅通过实现调用A的{​​{1}}尝试将org.apache.spark.sql.sources.CreatableRelationProvider转换为org.apache.spark.sql.execution.streaming.Sink,但是{{1}中有addBatch(...) },导致以下错误:

createRelation(...)

在尝试研究如何df.rdd的同时还需要从流作业的数据帧中获取Rdd的过程中,似乎起到了使用createRelation(...)生成RDD而不是调用{{1 }}。

但是事情似乎并不那么简单:

  1. 似乎需要注意输出排序-https://github.com/apache/spark/blob/branch-2.3/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/FileFormatWriter.scala#L159

  2. 可能会有一些急切的执行问题吗? (不确定) https://issues.apache.org/jira/browse/SPARK-20865

有关我所遇到问题的更多详细信息,请参见here

想知道转换的惯用方式是什么?

1 个答案:

答案 0 :(得分:0)

Dataset.rdd()创建了一个新计划,该计划只是中断了增量计划。由于StreamExecution使用现有计划来收集指标并更新水印,因此我们永远不应创建新计划。否则,指标和水印将在新计划中更新,并且StreamExecution无法检索它们。

以下是Scala中用于在结构化流中转换列值的代码示例:

val convertedRows: RDD[Row] = df.queryExecution.toRdd.mapPartitions { iter: Iterator[InternalRow] =>
  iter.map { row =>
    val convertedValues: Array[Any] = new Array(conversionFunctions.length)
    var i = 0
    while (i < conversionFunctions.length) {
      convertedValues(i) = conversionFunctions(i)(row, i)
      i += 1
    }
    Row.fromSeq(convertedValues)
  }
}