Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database Spark结构化流式ForeachWriter和数据库性能_Database_Scala_Apache Spark_Jdbc_Spark Structured Streaming - Fatal编程技术网

Database Spark结构化流式ForeachWriter和数据库性能

Database Spark结构化流式ForeachWriter和数据库性能,database,scala,apache-spark,jdbc,spark-structured-streaming,Database,Scala,Apache Spark,Jdbc,Spark Structured Streaming,我尝试过实现一个结构化流,就像这样 myDataSet .map(r => StatementWrapper.Transform(r)) .writeStream .foreach(MyWrapper.myWriter) .start() .awaitTermination() 这一切似乎都是可行的,但看看MyWrapper.myWriter的吞吐量是可怕的。它实际上是试图成为JDBC接收器,它看起来像: val myWriter: ForeachWriter[Se

我尝试过实现一个结构化流,就像这样

myDataSet
  .map(r =>  StatementWrapper.Transform(r))
  .writeStream
  .foreach(MyWrapper.myWriter)
  .start()
  .awaitTermination()
这一切似乎都是可行的,但看看MyWrapper.myWriter的吞吐量是可怕的。它实际上是试图成为JDBC接收器,它看起来像:

val myWriter: ForeachWriter[Seq[String]] = new ForeachWriter[Seq[String]] {

  var connection: Connection = _

  override def open(partitionId: Long, version: Long): Boolean = {
    Try (connection = getRemoteConnection).isSuccess
  }

  override def process(row: Seq[String]) {
    val statement = connection.createStatement()
    try {
      row.foreach( s => statement.execute(s) )
    } catch {
      case e: SQLSyntaxErrorException => println(e)
      case e: SQLException => println(e)
    } finally {
      statement.closeOnCompletion()
    }
  }

  override def close(errorOrNull: Throwable) {
    connection.close()
  }
}
所以我的问题是-新的ForeachWriter是否为每一行实例化?因此,对数据集中的每一行调用open()和close()

是否有更好的设计来提高吞吐量


如何一次解析SQL语句并多次执行,同时保持数据库连接打开?

基础接收器的打开和关闭取决于您的
ForeachWriter
实现

调用
ForeachWriter
的相关类是,这是调用编写器的代码:

data.queryExecution.toRdd.foreachPartition { iter =>
  if (writer.open(TaskContext.getPartitionId(), batchId)) {
    try {
      while (iter.hasNext) {
        writer.process(encoder.fromRow(iter.next()))
      }
    } catch {
      case e: Throwable =>
        writer.close(e)
        throw e
    }
    writer.close(null)
  } else {
    writer.close(null)
  }
}

尝试打开和关闭从源生成的每个批的编写器。如果希望每次打开和关闭接收器驱动程序时
open
close
,则需要通过实现来实现

如果您希望对数据的处理方式有更多的控制,可以实现trait,它提供批id和底层的
DataFrame

trait Sink {
  def addBatch(batchId: Long, data: DataFrame): Unit
}

非常感谢。不管怎样,你可以解释或指出一篇文章,它描述了在所有三种模式(追加、更新和完成)中实现一个接收器时要考虑的问题。我的问题是输出模式和汇接接口是如何相互作用的?@ USE1870400 AFAIK,接收器根据所设置的输出模式获取数据的相对部分。例如,如果您只需要更新,那么接收器只会在每次作业迭代中更新元素?看起来每个分区只调用一次open和close。好的,这里的batch是流媒体中的microbatch id。更多详情请点击这里