Spark执行者是多线程的吗?

时间:2017-09-18 05:09:17

标签: apache-spark

Spark Executor如何执行代码?它有多个线程在运行吗?如果是,它是否会打开多个JDBC连接以从/向RDBMS读取/写入数据?

3 个答案:

答案 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();

干杯!