Spark如何在多核或超线程机器上的一个任务中实现并行性

时间:2016-04-17 01:14:57

标签: multithreading apache-spark parallel-processing multicore

我一直在阅读并试图了解Spark框架如何在独立模式下使用其核心。根据Spark文档,参数“ spark.task.cpus ”的值默认设置为1,这意味着要为每个任务分配的核心数。

问题1: 对于多核机器(例如,总共4个核心,8个硬件线程),当“spark.task.cpus = 4”时,Spark会使用4个核心(每个核心1个线程)还是2个核心超线程?

如果我将“spark.task.cpus = 16”设置为超过此计算机上可用硬件线程的数量,会发生什么?

问题2: 这种硬件并行性是如何实现的?我试图查看代码,但找不到任何与硬件或JVM通信的内核级并行性。例如,如果任务是“过滤器”功能,那么单个过滤器任务如何分配到多个核心或线程?

也许我错过了什么。这与Scala语言有关吗?

1 个答案:

答案 0 :(得分:11)

要回答您的标题问题,Spark本身并不能在任务中为您提供并行性收益。 spark.task.cpus参数的主要目的是允许多线程性质的任务。如果在每个任务中调用外部多线程例程,或者您希望自己在任务级别封装最精细的并行度,则可能需要将spark.task.cpus设置为大于1。

  • 但是,将此参数设置为大于1并不是您经常要做的事情。

    • 如果可用内核的数量小于任务所需的内核数,则调度程序将不会启动任务,因此如果执行程序有8个内核,并且您已将spark.task.cpus设置为3,则只有2个任务将推出。
    • 如果您的任务没有始终消耗核心的全部容量,您可能会发现使用spark.task.cpus=1并在任务中遇到一些争用仍然可以提供更高的性能。
    • GC或I / O等内容的开销可能不应包含在spark.task.cpus设置中,因为它可能是一个更加静态的成本,不能与您的任务计数线性扩展。
  

问题1 :对于多核机器(例如,总共4个核心,8个硬件线程),当“spark.task.cpus = 4”时,Spark将使用4个核心(1每个核心的线程)还是2个带有超线程的核心?

JVM几乎总是依赖操作系统为它提供与CPU一起使用的信息和机制,而AFAIK Spark在这里没有做任何特别的事情。对于支持双核HT的英特尔®处理器,如果Runtime.getRuntime().availableProcessors()ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors()返回4,那么Spark也会看到4个内核。

  

问题2 :这种硬件并行性是如何实现的?我试图查看代码,但找不到任何与硬件或JVM通信的内核级并行性。例如,如果任务是“过滤器”功能,那么单个过滤器任务如何分配到多个核心或线程?

如上所述,Spark不会根据spark.task.cpus参数自动并行化任务。 Spark主要是数据并行引擎,其并行性主要通过将数据表示为RDD来实现。