Scala Spark 1.6:java.lang.IllegalArgumentException:Spark.sql.execution.id已设置

Scala Spark 1.6:java.lang.IllegalArgumentException:Spark.sql.execution.id已设置,scala,apache-spark,apache-spark-sql,spark-dataframe,Scala,Apache Spark,Apache Spark Sql,Spark Dataframe,我使用的是spark 1.6,在运行以下代码时遇到了上述问题: // Imports import org.apache.spark.sql.hive.HiveContext import org.apache.spark.{SparkConf, SparkContext} import org.apache.spark.sql.SaveMode import scala.concurrent.ExecutionContext.Implicits.global import java.util.

我使用的是spark 1.6,在运行以下代码时遇到了上述问题:

// Imports
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.SaveMode
import scala.concurrent.ExecutionContext.Implicits.global
import java.util.Properties
import scala.concurrent.Future

// Set up spark on local with 2 threads
val conf = new SparkConf().setMaster("local[2]").setAppName("app")
val sc = new SparkContext(conf)
val sqlCtx = new HiveContext(sc)

// Create fake dataframe
import sqlCtx.implicits._
var df = sc.parallelize(1 to 50000).map { i => (i, i, i, i, i, i, i) }.toDF("a", "b", "c", "d", "e", "f", "g").repartition(2)
// Write it as a parquet file
df.write.parquet("/tmp/parquet1")
df = sqlCtx.read.parquet("/tmp/parquet1")

// JDBC connection
val url = s"jdbc:postgresql://localhost:5432/tempdb"
val prop = new Properties()
prop.setProperty("user", "admin")
prop.setProperty("password", "")

// 4 futures - at least one of them has been consistently failing for
val x1 = Future { df.write.jdbc(url, "temp1", prop) }
val x2 = Future { df.write.jdbc(url, "temp2", prop) }
val x3 = Future { df.write.jdbc(url, "temp3", prop) }
val x4 = Future { df.write.jdbc(url, "temp4", prop) }
以下是github的要点:

我得到的错误是: 在


这是一个spark bug还是我做错了什么/有什么解决办法吗?

测试1:如果您以串行方式而不是并行方式运行每个df.write操作,会有帮助吗


测试2:如果您将数据帧持久化,然后并行执行所有df.write操作,并在所有操作完成后将seralize设置为unpersist,以查看这是否有帮助,这是否有帮助?

在尝试了几件事情之后,我发现全局
ForkJoinPool
创建的一个线程将其
spark.sql.execution.id
属性设置为随机值。 我无法确定实际执行该操作的流程,但我可以使用自己的
ExecutionContext
来解决它

import java.util.concurrent.Executors
import concurrent.ExecutionContext
val executorService = Executors.newFixedThreadPool(4)
implicit val ec = ExecutionContext.fromExecutorService(executorService)
我使用的代码来自。 创建新线程时,
ForkJoinPool
可能会克隆线程属性,如果在SQL执行的上下文中发生这种情况,它将获得非空值,而
FixedThreadPool
将在实例化时创建线程

请检查一下


如果适用于您的环境,请考虑使用Spark 2.2.0或更高版本。

请问您在哪台机器上运行此代码?我特别感兴趣的是CPU(有多少核)?OSX El Capitan 10.11.1 | MacBook Air(13英寸,2014年初)| 1.7 GHz Intel Core i7 | 8 GB 1600 MHz DDR3(我相信i7是4核)有趣,我无法在类似的设置(来自spark shell)上重现这一点。这可能是一些讨厌的错误,他们以前在ID生成方面有问题。你可能想为此创建一个JIRA。你运行的是哪个版本的postgres?我运行的是9.3.5版本,我遇到了相同的问题。但这个解决方案似乎没有帮助。我仍然看到
spark.sql.execution.id已设置
错误。@smas问题不在于线程的数量,而在于这些线程的初始化。fork-join池将在随机时间初始化线程,并克隆所有属性以初始化新线程。因此,如果在初始化新线程时,现有线程设置了SQL执行id,那么它会将其复制到新线程,而不是生成新线程。
import java.util.concurrent.Executors
import concurrent.ExecutionContext
val executorService = Executors.newFixedThreadPool(4)
implicit val ec = ExecutionContext.fromExecutorService(executorService)