Spark Executor如何执行代码?它有多个线程在运行吗?如果是,它是否会打开多个JDBC连接以从/向RDBMS读取/写入数据?
答案 0 :(得分:3)
Spark Executor如何执行代码?
开源的美妙之处,包括Apache Spark项目,您可以自己查看代码并找到答案。这并不是说这是找到答案的最好也是唯一的方法,但我的可能并不像代码本身那样清晰(反之亦然):)
话虽如此,请亲自查看Executor的代码。
是否有多个线程正在运行?
是。请参阅this line其中Executor
创建一个新的TaskRunner
,它是一个Java Runnable
(一个单独的线程)。那Runnable
将是executed on the thread pool。
引用Spark用于线程池的Java Executors.newCachedThreadPool:
创建一个线程池,根据需要创建新线程,但会在可用时重用以前构造的线程,并在需要时使用提供的ThreadFactory创建新线程。
如果是,它是否会打开多个JDBC连接以从RDBMS读取/写入数据?
我相信你已经知道了答案。是的,它将打开多个连接,这就是为什么你应该使用foreachPartition
操作_“将函数f
应用于此数据集的每个分区。” (同样适用于RDD)和某种连接池。
答案 1 :(得分:0)
是的,如果你将spark.executor.cores
设置为大于1,那么你的执行器将有多个并行线程,是的,我想那时将会打开多个JDBC连接
答案 2 :(得分:-1)
您可以通过在本地运行spark来轻松测试。
val conf = new SparkConf()
.setMaster("local[2]")
.setAppName("JDBCTest")
val sc = new SparkContext(conf)
在上面的片段中,local [2]表示两个线程。现在,如果在处理RDD时打开JDBC连接,spark将为每个任务执行此操作。
转换和动作在spark中并行运行,设计spark在运行内存中任务时效率更高,因此首先我们应该避免编写需要为每个RDD打开JDBC连接的代码,而是可以将其加载到内存中处理,请参阅下面的代码段。
Dataset<Row> jdbcDF = spark.read().format("jdbc").option("url", mySQLConnectionURL)
.option("driver", MYSQL_DRIVER).option("dbtable", sql).option("user", userId)
.option("password", dbpassword).load();
干杯!