我有一个应用程序,其中应用了许多链接的数据集转换。这些转换中的每一个都会生成一个新的数据集,用作下一个转换的输入。
类似这样的东西:
Dataset<Results> transfomation1 =
input.map(...);
Dataset<Results> transfomation2 =
transfomation1.map(...);
Dataset<Results> transfomation3 =
transfomation2.map(...);
Dataset<Results> transfomation4 =
transfomation3.joinWith(transfomation2 ...;
// many other transformation
Dataset<Results> finalResult = transfomationN.map(...);
Dataset<Results> results = finalResults.collectasList();
重要的是,输入数据很小,真的很小, 根本不是大数据。
只有在最后,这些链接的转换生成的结果才被收集到驱动程序中。
最初执行此应用程序时,需要小时才能完成。首先要考虑这种丑陋的性能,是因为当在后续转换中将转换用作输入时,转换会被多次重新评估。然后,我只缓存了所有结果数据集,以避免重新评估。
Dataset<Results> transfomation1 =
input.map(...).cache();
Dataset<Results> transfomation2 =
transfomation1.map(...).cache();
Dataset<Results> transfomation3 =
transfomation2.map(...).cache();
// and so on ...
缓存这些数据集的结果不可见。仍然需要永远完成。
我要做的更改是在每个数据集之后添加一个动作:
Dataset<Results> transfomation1 =
input.map(...).cache();
transfomation1.collect();
Dataset<Results> transfomation2 =
transfomation1.map(...).cache();
transfomation2.collect();
Dataset<Results> transfomation3 =
transfomation2.map(...).cache();
transfomation3.collect();
// and so on ...
现在,执行时间从数小时变为2分钟。
根据我读过的一些文章,这是因为缓存仅在请求操作后才有效。我还读到,在像这样的链式计算中,DAG的增长会很快影响性能,并且有人建议执行一个将DAG截断的操作。
有人可以解释为什么这样的变化会带来如此巨大的变化,也许可以建议我做一个更好的方法,因为我不认为打电话到收集周围是这样做的正确方法。
我非常感谢任何评论。