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

Nod*_*ame 9 parallel-processing multithreading multicore apache-spark

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

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

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

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

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

Dim*_*rov 12

要回答您的标题问题,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来实现.