我正在尝试使用scala的Futures API运行一个进程来并行运行某些操作。以下是示例代码段
import scala.util._
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
object ConcurrentContext {
def def appMain(args: Array[String]) = {
// configure spark
val spark = SparkSession
.builder
.appName("parjobs")
.getOrCreate()
val pool = Executors.newFixedThreadPool(5)
// create the implicit ExecutionContext based on our thread pool
implicit val xc = ExecutionContext.fromExecutorService(pool)
/** Wraps a code block in a Future and returns the future */
def executeAsync[T](f: => T): Future[T] = {
Future(f)
}
}
我的问题是: -
如果我将executor-cores值设置为4,它控制每个执行程序JVM的线程数,并在应用程序内创建一个5的线程池,哪一个优先?
如果我没有明确设置线程池,那么默认的ExecutionContext
将根据启动进程的机器上存在的所有核心创建一个默认线程池(这将是在这种情况下,执行者 - 核心财产会如何影响?
如果线程池值优先于executor-core,并且如果我使用默认值,那么每个JVM可能有多个线程(相当于CPU内核)?
答案 0 :(得分:1)
如果我将executor-cores值设置为4,它控制每个执行程序JVM的线程数,并在应用程序内创建一个5的线程池
执行Spark应用程序时,您拥有驱动程序和一个或多个执行程序。为简单起见,我们假设您只有一个执行程序。
执行者有4个CPU。
您可以与4个CPU并行运行多少个任务? 4确切地说!
驱动程序在Spark应用程序的那部分中运行,该部分具有5个线程的线程池。为简单起见,我们假设使用了所有5个。
您可以安排多少个Spark工作? 5确切地说!
每个Spark作业都可以有一个或多个阶段,其中包含一个或多个分区,可以使用任务进行处理。为了简单起见,让我们假设所有5个Spark作业都有1个阶段,1个分区(这是非常不可能的,但只是为了让你知道Spark如何工作它应该没问题。)
请记住,1个分区正好是1个任务。
Spark应用程序将提交多少个任务?每个任务1个任务5个任务。
在5-CPU执行程序上执行所有5个任务需要多长时间? 1个时间段(无论什么"时间段"可能意味着)。
执行器核心/ CPU与驱动程序上5个线程的线程池之间的关系。
如果我没有显式设置线程池,那么默认的ExecutionContext将根据启动进程的机器上存在的所有核心(这将是驱动程序)创建一个默认线程池,情况如何执行者 - 核心财产会受到影响吗?
我认为上面的部分也回答了这个问题。
如果线程池值优先于executor-core,并且如果我使用默认值,那么每个JVM可能有多个线程(相当于CPU内核)?
就是这样。正确的吗?