Apache spark 如何编写两个流式df';在Spark structured streaming中,在MySQL中的两个不同的表中添加了哪些内容?
我使用的是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用户/数据库分别分配给两个表。但是没有运气 有人能给我建议吗?如何让它工作 我的代码如下: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
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核心数)
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)
谢谢,迈克。我会尽力通知你的。非常感谢你,迈克。现在一切都好了。我真的挣扎了两天。你解决了我的问题。祝你今天愉快。谢谢迈克。我会尽力通知你的。非常感谢迈克。现在一切都好了。我真的挣扎了两天。你解决了我的问题。祝你有美好的一天。