【问题标题】:Apache Spark timing forEach operation on JavaRDDJavaRDD 上每个操作的 Apache Spark 计时
【发布时间】:2016-07-10 22:22:55
【问题描述】:

问题:这是测试构建 RDD 所用时间的有效方法吗?

我在这里做两件事。基本方法是我们有 M 个我们称为 DropEvaluation 的实例和 N 个 DropResults。我们需要将每个 N DropResult 与每个 M DropEvaluations 进行比较。每个 N 必须被每个 M 看到,最终给我们 M 个结果。

如果我在构建 RDD 后不使用 .count(),驱动程序会继续执行下一行代码,并表示几乎没有时间构建需要 30 分钟才能构建的 RDD。

我只是想确保我没有遗漏一些东西,比如 .count() 可能需要很长时间?我猜要计时 .count() 我必须修改 Spark 的源代码?

M = 1000 或 2000。N = 10^7。

这实际上是一个笛卡尔问题——选择累加器是因为我们需要在适当的位置写入每个 M。构建完整的笛卡尔 RDD 也会很丑。

我们构建了一个 M 累加器列表(不能在 Java 中做一个列表累加器,对吧?)。然后我们用 foreach 循环遍历 RDD 中的 N 中的每一个。

澄清问题:总时间测量正确,我在问 RDD 上的 .count() 是否强制 Spark 等到 RDD 完成才能运行计数。 .count() 时间是否重要?

这是我们的代码:

// assume standin exists and does it's thing correctly

// this controls the final size of RDD, as we are not parallelizing something with an existing length
List<Integer> rangeN = IntStream.rangeClosed(simsLeft - blockSize + 1, simsLeft).boxed().collect(Collectors.toList());

// setup bogus array of size N for parallelize dataSetN to lead to dropResultsN       
JavaRDD<Integer> dataSetN = context.parallelize(rangeN);

// setup timing to create N
long NCreationStartTime = System.nanoTime();

// this maps each integer element of RDD dataSetN to a "geneDropped" chromosome simulation, we need N of these:
JavaRDD<TholdDropResult> dropResultsN = dataSetN.map(s -> standin.call(s)).persist(StorageLevel.MEMORY_ONLY());

// **** this line makes the driver wait until the RDD is done, right?
long dummyLength = dropResultsN.count();


long NCreationNanoSeconds = System.nanoTime() - NCreationStartTime;
double NCreationSeconds = (double)NCreationNanoSeconds / 1000000000.0;
double NCreationMinutes = NCreationSeconds / 60.0;

logger.error("{} test sims remaining", simsLeft);

// now get the time for just the dropComparison (part of accumulable's add)
long startDropCompareTime = System.nanoTime();

// here we iterate through each accumulator in the list and compare all N elements of dropResultsN RDD to each M in turn, our .add() is a custom AccumulableParam
for (Accumulable<TholdDropTuple, TholdDropResult> dropEvalAccum : accumList) {
    dropResultsN.foreach(new VoidFunction<TholdDropResult>() {
                    @Override
                    public void call(TholdDropResult dropResultFromN) throws Exception {
                            dropEvalAccum.add(dropResultFromN);
                    }
                });
            }

    // all the dropComparisons for all N to all M for this blocksize are done, check the time...
   long dropCompareNanoSeconds = System.nanoTime() - startDropCompareTime;
   double dropCompareSeconds = (double)dropCompareNanoSeconds / 1000000000.0;
    double dropCompareMinutes = dropCompareSeconds / 60.0;

    // write lines to indicate timing section
    // log and write to file the time for the N-creation

    ...

} // end for that goes through dropAccumList

【问题讨论】:

  • 我会注意到下面 Dikei 的回答,我 +1,它没有回答核心问题,这是准确计时创建 RDD 的有效方法吗?计数本身是否需要大量时间,是否会增加 RDD 创建时间?有没有关于定时 Spark 事物的好例子的链接?

标签: java scala apache-spark timing accumulator


【解决方案1】:

Spark 程序是惰性的,除非您在 RDD 上调用所有类似 count 的操作,否则它不会运行。您可以在Spark's document中找到常用操作列表

// **** this line makes the driver wait until the RDD is done, right?
long dummyLength = dropResultsN.count();

是的,在这种情况下,count 强制计算 dropResultsN,因此需要很长时间。如果你再做一次count,它会很快返回,因为 RDD 已经被计算和缓存了。

【讨论】:

  • 如果从未计算过 RDD,我会同意你的看法。由于我确实调用了dropResultsN.foreach,因此会对其进行计算。 Foreach 在您链接的列表中。所以,我认为是一半错了?我还以为我这样缓存了它:JavaRDD&lt;TholdDropResult&gt; dropResultsN = dataSetN.map(s -&gt; standin.call(s)).persist(StorageLevel.MEMORY_ONLY()); ...还是我只保留dataSetN?哇,你可能让我大吃一惊:)
  • 我的错,我没有看到persist 电话。使用 MEMORY_ONLY 调用 persist 与调用 cache 相同。
  • 请参阅上面对我的问题的评论,如果您对有效的 Spark 计时方法或一些链接/示例有其他观察,您确实会想到第一个 .count() 需要很长时间,我可能会接受这个答案,否则会放过几天,看看谁插话。谢谢。
  • 不,我从另一个问题(在我自己的回答中)中发现我坚持做正确的事情。尽管如此,还是按照my answer from an O'Reilly book, Learning Spark中给出的例子比较好:rddToPersist = existingRDD.map.etc.etc; rddToPersist.persist();
猜你喜欢
  • 2015-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多