Hadoop ApacheSpark:核心数与执行器数之比

Hadoop ApacheSpark:核心数与执行器数之比,hadoop,apache-spark,yarn,Hadoop,Apache Spark,Yarn,我试图了解在纱线上运行火花作业时,芯数和执行器数之间的关系 测试环境如下所示: 数据节点数:3 数据节点计算机规格: CPU:内核i7-4790(内核数:4,线程数:8) 内存:32GB(8GB x 4) 硬盘驱动器:8TB(2TB x 4) 网络:1Gb Spark版本:1.0.0 Hadoop版本:2.4.0(Hortonworks HDP 2.1) Spark作业流:sc.textFile->filter->map->filter->mapToPair->reduceByKey->m

我试图了解在纱线上运行火花作业时,芯数和执行器数之间的关系

测试环境如下所示:

  • 数据节点数:3
  • 数据节点计算机规格:
    • CPU:内核i7-4790(内核数:4,线程数:8)
    • 内存:32GB(8GB x 4)
    • 硬盘驱动器:8TB(2TB x 4)
  • 网络:1Gb

  • Spark版本:1.0.0

  • Hadoop版本:2.4.0(Hortonworks HDP 2.1)

  • Spark作业流:sc.textFile->filter->map->filter->mapToPair->reduceByKey->map->saveAsTextFile

  • 输入数据

    • 类型:单个文本文件
    • 大小:165GB
    • 行数:454568833
  • 输出

    • 第二个过滤器后的行数:310640717
    • 结果文件的行数:99848268
    • 结果文件的大小:41GB
作业已使用以下配置运行:

  • ——主纱线客户端——执行器内存19G——执行器核心7——num executors 3
    (每个数据节点的执行器使用的核心数)

  • --主纱线客户端--执行器内存19G--执行器芯4--执行器芯数3
    (#芯数减少)

  • ——主纱线客户端——执行器内存4G——执行器芯2——num执行器12
    (芯越少,执行器越多)

  • 运行时间:

  • 50分钟15秒

  • 55分48秒

  • 31分23秒

  • 令我惊讶的是,(3)速度快得多。
    我认为(1)会更快,因为洗牌时执行者之间的通信会更少。
    尽管(1)中的#个核数少于(3),但#个核数不是关键因素,因为(2)的表现不错

    (在pwilmot的回答之后添加了以下内容。)

    有关信息,性能监视器屏幕截图如下所示:

    • (1)的Ganglia数据节点摘要-作业在04:37开始

    • (3)的Ganglia数据节点摘要-作业在19:47开始。在此之前请忽略图表

    该图大致分为两部分:

    • 第一:从开始到减少YKEY:CPU密集型,无网络活动
    • 第二步:还原后。Y键:CPU降低,网络I/O完成
    如图所示,(1)可以使用给定的CPU功率。所以,这可能不是线程数量的问题


    如何解释这个结果?

    我自己没有使用这些设置,所以这只是猜测,但如果我们将此问题视为分布式系统中的普通内核和线程,那么在集群中,您最多可以使用12个内核(4*3台机器)和24个线程(8*3台机器)。在前两个示例中,您为作业分配了相当数量的内核(潜在计算空间),但在这些内核上运行的线程(作业)数量非常有限,以至于您无法使用分配的大部分处理能力,因此即使分配了更多计算资源,作业也会变慢


    您提到您的关注点是在shuffle步骤中-虽然在shuffle步骤中限制开销是很好的,但通常更重要的是利用集群的并行化。考虑一个极端情况——一个具有零洗牌的单线程程序

    我认为主要原因之一是地方性。您的输入文件大小为165G,文件的相关块肯定分布在多个数据节点上,更多执行者可以避免网络复制


    尝试设置executor num equal blocks count,我认为可以更快。

    根据

    我注意到HDFS客户机在处理大量并发数据时遇到了问题 线程。粗略猜测,每个执行者最多可以执行五项任务 实现全写吞吐量,因此最好保持 每个执行器的核心数低于该数字

    所以我认为第一种配置比第三种配置慢是因为HDFS I/O吞吐量差

    为了让这一切更具体一些,下面是一个配置Spark应用程序以尽可能多地使用集群的工作示例 可能:假设一个集群有六个节点,每个节点运行NodeManager 配备16核和64GB内存。节点管理器容量, warn.nodemanager.resource.memory-mb和 warn.nodemanager.resource.cpu-vcores可能应设置为63* 1024分别为64512(兆字节)和15。我们避免分配100% 因为节点需要一些 用于运行OS和Hadoop守护进程的资源。在这种情况下,我们留下一个 千兆字节和这些系统进程的核心。Cloudera管理器帮助 通过考虑这些因素并配置这些纱线特性 自动地

    可能的第一个冲动是使用--num executors 6 --执行器内核15——执行器存储器63G。但是,这是错误的方法,因为:

    63GB+执行器内存开销不适合63GB容量 在节点管理者中。应用程序主机将占用一对一的核心 这意味着没有空间容纳15个核心执行器 在那个节点上。每个执行器15个内核可能导致HDFS I/O错误 吞吐量

    更好的选择是使用--num executors 17 --执行器核心5——执行器存储器19G。为什么?


    此配置会在除一个执行器之外的所有节点上产生三个执行器 AM将有两名执行人。 --执行器内存派生为(每个节点63/3个执行器)=21。21 * 0.07 = 1.47. 21-1.47~19


    Cloudera博客上的一篇文章对此进行了解释。

    Spark动态分配提供了灵活性并动态分配资源。在此情况下,可以给出最小和最大执行器的数量。也麻木了
    ratio_num_threads = nthread_job1 / nthread_job3 = 15/24 = 0.625
    inv_ratio_runtime = 1/(duration_job1 / duration_job3) = 1/(50/31) = 31/50 = 0.62
    
    ratio_num_threads = nthread_job2 / nthread_job1 = 12/15 = 0.8
    inv_ratio_runtime = 1/(duration_job2 / duration_job1) = 1/(55/50) = 50/55 = 0.91