Scala Spark如何处理涉及JDBC数据源的故障场景?
我正在编写一个与Spark的JDBC数据源实现有相似之处的数据源,我想问Spark如何处理某些故障场景。据我所知,如果执行者在运行任务时死亡,Spark将恢复执行者并尝试重新运行该任务。但是,在数据完整性和Spark的JDBC数据源API(例如,Scala Spark如何处理涉及JDBC数据源的故障场景?,scala,apache-spark,jdbc,apache-spark-sql,Scala,Apache Spark,Jdbc,Apache Spark Sql,我正在编写一个与Spark的JDBC数据源实现有相似之处的数据源,我想问Spark如何处理某些故障场景。据我所知,如果执行者在运行任务时死亡,Spark将恢复执行者并尝试重新运行该任务。但是,在数据完整性和Spark的JDBC数据源API(例如,df.write.format(“JDBC”).option(…).save())的上下文中,这是如何实现的 在的savePartition函数中,我们看到Spark调用从用户提供的数据库url/凭据生成的Java连接对象的提交和回滚函数(见下文)。但是
df.write.format(“JDBC”).option(…).save()
)的上下文中,这是如何实现的
在的savePartition函数中,我们看到Spark调用从用户提供的数据库url/凭据生成的Java连接对象的提交和回滚函数(见下文)。但是,如果一个执行器在commit()完成之后或在rollback()调用之前死亡,Spark是否会尝试重新运行任务并再次写入相同的数据分区,从而在数据库中创建重复的提交行?如果执行器在调用委托()或滚退()中死亡,会发生什么?
出于上述原因,我不得不引入一些重复数据消除逻辑。你最终可能会犯同样的错误两次(或更多) 但是,如果一个执行器在commit()完成之后或在rollback()调用之前死亡,Spark是否会尝试重新运行任务并再次写入相同的数据分区,从而在数据库中创建重复的提交行 由于Spark SQL(它是RDDAPI之上的一种高级API)并不真正了解JDBC或任何其他协议的所有特性,您会期待什么?更不用说底层执行运行时,即Spark Core 当您编写类似
df.write.format(“jdbc”).option(…).save()之类的结构化查询时,Spark SQL使用类似RDDAPI的低级程序集将其转换为分布式计算。由于Spark SQL试图采用尽可能多的“协议”(包括JDBC),因此它的DataSource API将大部分错误处理留给了数据源本身
Spark的核心是调度任务(不知道甚至不关心任务做什么),它只是监视执行,如果任务失败,它将再次尝试执行它(默认情况下,直到3次失败的尝试)
因此,当您编写自定义数据源时,您了解演练,并且必须在代码中处理此类重试
处理错误的一种方法是使用注册任务侦听器(例如,addTaskCompletionListener
或addTaskFailureListener
)。您能否描述一下如何实现此重复数据消除逻辑?我对一些细节很好奇,比如你在哪里添加的,你使用的是什么类型的数据库。这是一个Amazon红移,我不得不添加额外的时间戳列,后来用于ETL过程中的重复数据消除。一般来说,您只需要一些唯一的键就可以判断它是新记录还是重复记录,显然红移对于键(因此是时间戳)不是很好。你的数据目标是什么?谢谢!我正在尝试使用SQL Server。我对Redshift了解不多,但我会调查一下是否可以实现类似的策略。使用SQL Server实际上更简单—请看这里。
try {
...
if (supportsTransactions) {
conn.commit()
}
committed = true
Iterator.empty
} catch {
case e: SQLException =>
...
throw e
} finally {
if (!committed) {
// The stage must fail. We got here through an exception path, so
// let the exception through unless rollback() or close() want to
// tell the user about another problem.
if (supportsTransactions) {
conn.rollback()
}
conn.close()
} else {
...
}
}