Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.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
Apache spark 如何编写两个流式df';在Spark structured streaming中,在MySQL中的两个不同的表中添加了哪些内容?_Apache Spark_Spark Structured Streaming - Fatal编程技术网

Apache spark 如何编写两个流式df';在Spark structured streaming中,在MySQL中的两个不同的表中添加了哪些内容?

Apache spark 如何编写两个流式df';在Spark structured streaming中,在MySQL中的两个不同的表中添加了哪些内容?,apache-spark,spark-structured-streaming,Apache Spark,Spark Structured Streaming,我使用的是spark 2.3.2版本 我在spark structured streaming中编写了代码,将流式数据帧数据插入到两个不同的MySQL表中 假设有两个流式df:DF1,DF2 我已经使用foreachWriter API编写了两个查询(query1、query2),分别从不同的流写入MySQL表。即DF1进入MYSQL表A,DF2进入MYSQL表B 当我运行spark作业时,它首先运行query1,然后运行query2,所以它写入表A,但不写入表B 如果我将代码更改为先运行que

我使用的是spark 2.3.2版本

我在spark structured streaming中编写了代码,将流式数据帧数据插入到两个不同的MySQL表中

假设有两个流式df:DF1,DF2

我已经使用foreachWriter API编写了两个查询(query1、query2),分别从不同的流写入MySQL表。即DF1进入MYSQL表A,DF2进入MYSQL表B

当我运行spark作业时,它首先运行query1,然后运行query2,所以它写入表A,但不写入表B

如果我将代码更改为先运行query2,然后再运行query1,它将写入表B,但不会写入表A

所以我知道它执行第一个查询只是为了写入表

注意:我已经尝试将不同的MySQL用户/数据库分别分配给两个表。但是没有运气

有人能给我建议吗?如何让它工作

我的代码如下:

import java.sql._

class  JDBCSink1(url:String, user:String, pwd:String) extends ForeachWriter[org.apache.spark.sql.Row] {
      val driver = "com.mysql.jdbc.Driver"
      var connection:Connection = _
      var statement:Statement = _
      
    def open(partitionId: Long,version: Long): Boolean = {
        Class.forName(driver)
        connection = DriverManager.getConnection(url, user, pwd)
        statement = connection.createStatement
        true
      }

      def process(value: (org.apache.spark.sql.Row)): Unit = {

        val insertSql = """ INSERT INTO tableA(col1,col2,col3) VALUES(?,?,?); """
        val preparedStmt: PreparedStatement = connection.prepareStatement(insertSql)
        preparedStmt.setString (1, value(0).toString)
        preparedStmt.setString (2, value(1).toString)
        preparedStmt.setString (3, value(2).toString)
        preparedStmt.execute
      }

      def close(errorOrNull: Throwable): Unit = {
        connection.close
      }
   }



class  JDBCSink2(url:String, user:String, pwd:String) extends ForeachWriter[org.apache.spark.sql.Row] {
      val driver = "com.mysql.jdbc.Driver"
      var connection:Connection = _
      var statement:Statement = _
      
    def open(partitionId: Long,version: Long): Boolean = {
        Class.forName(driver)
        connection = DriverManager.getConnection(url, user, pwd)
        statement = connection.createStatement
        true
      }

      def process(value: (org.apache.spark.sql.Row)): Unit = {

        val insertSql = """ INSERT INTO tableB(col1,col2) VALUES(?,?); """
        val preparedStmt: PreparedStatement = connection.prepareStatement(insertSql)
        preparedStmt.setString (1, value(0).toString)
        preparedStmt.setString (2, value(1).toString)
        preparedStmt.execute
      }

      def close(errorOrNull: Throwable): Unit = {
        connection.close
      }
   }



val url1="jdbc:mysql://hostname:3306/db1"
val url2="jdbc:mysql://hostname:3306/db2"

val user1 ="usr1"
val user2="usr2"
val pwd = "password"

val Writer1 = new JDBCSink1(url1,user1, pwd)

val Writer2 = new JDBCSink2(url2,user2, pwd)


val query2 =
  streamDF2
    .writeStream
    .foreach(Writer2)
    .outputMode("append")
    .trigger(ProcessingTime("35 seconds"))
    .start().awaitTermination()



val query1 =
  streamDF1
    .writeStream
    .foreach(Writer1)
    .outputMode("append")
    .trigger(ProcessingTime("30 seconds"))
    .start().awaitTermination()

由于
等待终止
,您正在阻止第二个查询。如果希望有两个输出流,则需要在等待其终止之前启动这两个输出流:

val查询2=
streamDF2
.writeStream
.foreach(编写器2)
.outputMode(“追加”)
.触发器(处理时间(“35秒”))
.start()
瓦尔查询1=
流DF1
.writeStream
.foreach(编写器1)
.outputMode(“追加”)
.触发器(处理时间(“30秒”))
.start()
问题1.等待终止()
查询2.1终止()

编辑:

Spark还允许您为不同的流式查询安排和分配资源,如中所述。您可以基于配置池

  • 调度模式:可以是
    FIFO
    FAIR
  • 权重:“这控制池相对于其他池在集群中的份额。默认情况下,所有池的权重均为1。例如,如果将特定池的权重设置为2,则它将获得比其他活动池多2倍的资源。”
  • minShare:“除了总体权重外,每个池都可以获得管理员希望的最小份额(作为CPU核心数)
池配置可以通过创建一个XML文件来设置,类似于
conf/fairscheduler.XML.template
,将名为fairscheduler.XML的文件放在类路径上,或者在SparkConf中设置
spark.scheduler.allocation.file
属性

conf.set("spark.scheduler.allocation.file", "/path/to/file")
可以按如下方式应用不同的池:

spark.sparkContext.setLocalProperty(“spark.scheduler.pool”、“pool1”)
spark.sparkContext.setLocalProperty(“spark.scheduler.pool”、“pool2”)
//在上面的示例中,您可以告诉Spark使用这些池
val query1=streamDF1.writeStream.[…].start(pool1)
val query2=streamDF2.writeStream.[…].start(pool2)

您正在阻止第二个查询,因为
等待终止。如果希望有两个输出流,则需要在等待其终止之前启动这两个输出流:

val查询2=
streamDF2
.writeStream
.foreach(编写器2)
.outputMode(“追加”)
.触发器(处理时间(“35秒”))
.start()
瓦尔查询1=
流DF1
.writeStream
.foreach(编写器1)
.outputMode(“追加”)
.触发器(处理时间(“30秒”))
.start()
问题1.等待终止()
查询2.1终止()

编辑:

Spark还允许您为不同的流式查询安排和分配资源,如中所述。您可以基于配置池

  • 调度模式:可以是
    FIFO
    FAIR
  • 权重:“这控制池相对于其他池在集群中的份额。默认情况下,所有池的权重均为1。例如,如果将特定池的权重设置为2,则它将获得比其他活动池多2倍的资源。”
  • minShare:“除了总体权重外,每个池都可以获得管理员希望的最小份额(作为CPU核心数)
池配置可以通过创建一个XML文件来设置,类似于
conf/fairscheduler.XML.template
,将名为fairscheduler.XML的文件放在类路径上,或者在SparkConf中设置
spark.scheduler.allocation.file
属性

conf.set("spark.scheduler.allocation.file", "/path/to/file")
可以按如下方式应用不同的池:

spark.sparkContext.setLocalProperty(“spark.scheduler.pool”、“pool1”)
spark.sparkContext.setLocalProperty(“spark.scheduler.pool”、“pool2”)
//在上面的示例中,您可以告诉Spark使用这些池
val query1=streamDF1.writeStream.[…].start(pool1)
val query2=streamDF2.writeStream.[…].start(pool2)

谢谢,迈克。我会尽力通知你的。非常感谢你,迈克。现在一切都好了。我真的挣扎了两天。你解决了我的问题。祝你今天愉快。谢谢迈克。我会尽力通知你的。非常感谢迈克。现在一切都好了。我真的挣扎了两天。你解决了我的问题。祝你有美好的一天。