Spark / Hadoop作业未在parralel

时间:2017-03-19 12:11:38

标签: hadoop apache-spark parallel-processing mapreduce

我认为我有一个初学者错误,但我真的不知道如何修复它,这让我疯了。 我有一个由2台机器组成的集群:

  1. 8GB RAM(6.9可用),4个核心,Win10:运行主机,工作者,它也是我运行java驱动程序的机器(来自IntelliJ)
  2. 2GB RAM(1.3可用),4个核心,VM上的Ubuntu 16.04(在VBox中运行):运行工作者
  3. 我有一个类网络,我想通过从具有单个网络的列表开始,然后通过使用flatmap将每个网络转换为N个新网络,在for循环中生成网络。之后,我有一个过滤器和一个计数。步骤进行:

        JavaSparkContext sc = new JavaSparkContext(conf);
        List<Network> data = Arrays.asList(new Network());
        JavaRDD<Network> currentN = sc.parallelize(data);
        for(int k=1;k<=10;k++) {
            JavaRDD<Network> newN = currentN.flatMap(new MyFlatMap());
            currentN = newN;
        }
        JavaRDD<Network> filteredNetworks = currentN.filter(new MyFilter());
        System.out.println(filteredNetworks.count());
    

    算法工作并输出正确的值。

    但是,通过比较不同场景中应用程序的持续时间,我倾向于认为应用程序不是并行运行的:

    使用两台机器的群集,共有2GB的Ram和8个核心:持续时间1.5分钟

    仅使用第二台计算机(VM Ubuntu),1GB RAM,4核心的群集:持续时间1,1分钟

    仅使用第一台计算机(主计算机,工作程序和驱动程序)的群集,1GB RAM,4核心:持续时间3,2分钟

    我的火花UI的截图:

    Alive Workers Alive workers

    首次运行的事件时间表(使用两台机器): Event timeline of first run

    通过执行者(使用两台计算机)聚合指标 Metrics

    我不知道为什么在虚拟机中运行Ubuntu的机器比主机(主机,工程师和驱动程序)更快,因为主机有更好的CPU(i7 2.6GHZ与i3相比) ,9GHz的)。

    但主要的问题是为什么在一台机器上运行比在两台机器上运行更快?不应该是相反的吗?我的猜测是RDD不是并行计算的。如果是这种情况,请您解释为什么以及如何让它并行处理?

    解释作业的作用:

    基本上,这是我想在for循环中实现的目标:

    我从一个网络的RDD开始(它不是一个文件,它只是一个小类)。

    在for循环中,我使用flatMap将1个网络转换为10个新网络。

    迭代0:currentN = 1网络 - &gt; flatMap - &gt; currentN = 10网络

    迭代1:currentN = 10网络 - &gt; flatMap - &gt; currentN = 100网络

    迭代9:currentN = 10 ^ 8网络 - &gt; flatMap - &gt; currentN = 10 ^ 9网络

    正如我所说,我生成输入。我想并行生成这个,所以这意味着flatMap需要并行完成。要做到这一点,火花应该:

    1. 带有N个网络的RDD

    2. 将RDD划分为每个核心的8个分区,每个分区具有N / 8个网络

    3. 并行地在每台机器上应用flatMap,将每个N / 8网络转换为N / 8 * 10个新网络。

    4. 在每台机器上重复这些步骤,并行执行flatMap生成。

    5. for循环结束后,每台机器应该有10 ^ 9/8网络。并行过滤它们,然后在parralel中计算每台机器上每个RDD中的元素数量并输出答案。

    6. 这是我想要实现的,但由于某种原因,for循环中的flatMap生成仅在一台机器上完成。

2 个答案:

答案 0 :(得分:1)

来自spark UI的最后一个屏幕截图显示,在8个任务中,7个已完成,最长时间为37毫秒,而最长的任务至少运行46秒。

如果你有一个任务运行3分钟,而其他任务运行不到一秒钟,你的分布式计算不平衡,因此你无法利用多台机器完全运行,因为计算时间受最长时间的限制任务。

这种行为通常是由不平衡操作/转换(join,...)输入不平衡大小(1个Ko的7个文件和1个Go的1个文件)引起的。

最后很难在不确切知道你的工作的情况下解释你的时间与CPU,但可能的解释是你有一个数据密集型工作(而不是CPU密集型工作),因此瓶颈是硬盘(SSD)在具有最慢CPU的机器上)。

答案 1 :(得分:0)

我终于设法解决了这个问题。这个小虫非常愚蠢而且显而易见,但是我花了很长时间才搞清楚......

正如我之前提到的,我不是从文件中读取输入,而是从 1网络开始生成输入,然后我在该网络上执行flatMap以获得N个网络,而不是获得N * M个新网络等等。

但是因为我从一个网络开始,当我做

List<Network> data = Arrays.asList(new Network());
JavaRDD<Network> currentN = sc.parallelize(data);

数据在一个任务中仅在一个CPU上并行化,因为RDD只包含1个元素,因此存在问题。