RDD的最后一项未保存到HDFS

时间:2016-02-18 14:43:42

标签: java hadoop apache-spark hdfs yarn

我对Spark很新,目前在4个Spark工作人员上运行一些基本的ETL,从外部源读取项目,然后将它们保存到HDFS。很奇怪我在HDFS结果中缺少项目。

因为我需要遵循某些文件系统约定,所以我想将这些项目拆分为单独的存储桶并将它们保存在单独的子文件夹中(我知道这里的性能松散):

List<String> sources; // some list of strings
JavaRDD<Task> taskList; // a lot of tasks for each source
JavaRDD<Item> items = taskList.map(task -> new Extractor().execute(task));
for (String sourceId : sources) {
  String path = "hdfs:///sources/" + sourceId";
  JavaRDD<String> currentItems = items.filter(
    // filter only matching source ID items
    item -> item.getSource().equals(sourceId)).map(
    // serialise each filtered item
    item -> item.toString());

  // save to hdfs
  currentItems.saveAsTextFile("hdfs:///sources/" + sourceId);
}
jsc.stop(); // done

当我在转换/过滤/映射期间的任何时候调试.collect().size()时,会显示预期/正确的项目数。但是,当我在应用程序完成后查看HDFS中的文件时,我只找到每个源的文件中的一个项目(我知道Spark会将多个项目写入每个部分) -0000x文件)。

有什么想法吗?我不是百分之百确定是否可能重新使用每个filter(..).map(..)相同的RDD。当我将所有项目转储到同一个文件夹中时(没有此for shenanigan),一切都按预期工作。所有项目都是写的。我用当前的解决方案尝试items.cache(),但这也无济于事。

我确实删除了.filter(..)操作,并使用2个源的小数据集进行测试,每个源提取6个项目。结果是每个文件夹中有12个项目,因此filter(..)操作显然是罪魁祸首。

更新:在深入了解输入源之后,减少源数量以便更轻松地调试它,并找出问题是否仅在处理了比工作人员更多的项目时才会发生。代码的一些微小细节可能已经改变,但经过一些轻微的重构和测试以及不断增加的数据集,我再也无法观察到这些问题了。问题解决了(希望永远)。如果我找到原因,我会在这里更新。

我正在使用Yarn在Hadoop 2.7.2上运行Spark 1.6.0,我的Spark应用程序是用Java8编写的。应用程序运行顺利,并成功完成。

1 个答案:

答案 0 :(得分:1)

我认为您用于过滤的列表List<String> sources中的源ID比taskList中的源ID少。

如果您运行taskList.map(item -> item.getSource()).distinct().count(),它将等于sources.size()

如果答案为否,请在for循环中使用taskList.map(item -> item.getSource()).distinct().collectAsMap()代替sources