【发布时间】:2018-10-02 22:22:33
【问题描述】:
首先让我说我对火花比较陌生,所以如果我说的东西没有意义,请纠正我。
总结问题,不管我做什么,在某些阶段,一个执行器完成所有计算,这使得集群执行比本地的单处理器执行慢。
全文: 我编写了一个 spark 1.6 应用程序,它由一系列映射、过滤器、连接和一个简短的 graphx 部分组成。该应用程序仅使用一个数据源 - csv 文件。出于开发目的,我创建了一个模型数据集,包含 100 000 行,7MB,所有字段都具有均匀分布的随机数据(文件中也是随机排序)。连接是 PairRDD 上各个字段的自内连接(数据集有重复的键,每个键有约 200 个重复项,模仿真实数据),导致键内的笛卡尔积。然后我对连接的结果执行一些映射和过滤操作,将其存储为一些自定义类对象的 RDD,并将所有内容保存为图。
我在笔记本电脑上开发代码并运行它,大约需要 5 分钟(Windows 机器,本地文件)。令我惊讶的是,当我将 jar 部署到集群(主纱线、集群模式、HDFS 中的 csv 文件)并提交时,代码执行了 8 分钟。 我用较小的数据进行了相同的实验,结果在本地是 40 秒,在集群上是 1.1 分钟。
当我查看历史服务器时,我发现 2 个阶段特别长(每个阶段几乎 4 分钟),并且在这些阶段中,有一个任务需要超过 90% 的时间。我多次运行代码,即使每次都部署在不同的数据节点上,它总是花费大量时间的同一个任务。
令我惊讶的是,当我打开执行器时,我看到一个执行器几乎完成了所有工作(就花费的时间而言)并执行了大多数工作。在提供的屏幕截图中,第二个最“活跃”的执行者有 50 个任务,但情况并非总是如此——在不同的提交中,第二个最繁忙的执行者有 15 个任务,而领先的一个有 95 个任务。
此外,我看到 3.9 分钟的时间用于计算(第二个屏幕截图),这对 map 后不久的连接数据来说是最重的。我认为,数据可能不会被平均划分,一个执行者必须执行所有计算。因此,我尝试在加入之前(类似的执行时间)或加入之后(执行更慢)手动(使用 .partitionBy(new HashPartitioner(40)))对 pairRdd 进行分配。
可能是什么问题?任何帮助将不胜感激。
【问题讨论】:
标签: scala apache-spark