2015-10-20 82 views
0

我试图实现除了实际数据集(输入)之外还处理大型文本文件(作为查找文件)的MapReduce作业。查找文件大于2GB。 我试图加载文本文件作为第三个参数如下:Hadoop分布式缓存处理大查找文本文件

但我得到了Java堆空间错误。

做了一些搜索之后,建议使用分布式缓存。这是我迄今 首先做的,我用这个方法来读取查找文件:

public static String readDistributedFile(Context context) throws IOException { 
     URI[] cacheFiles = context.getCacheFiles(); 
     Path path = new Path(cacheFiles[0].getPath().toString()); 
     FileSystem fs = FileSystem.get(new Configuration()); 
     StringBuilder sb = new StringBuilder(); 
     BufferedReader br = new BufferedReader(new InputStreamReader(fs.open(path))); 
     String line; 
     while ((line = br.readLine()) != null) { 
      // split line 
      sb.append(line); 
      sb.append("\n"); 
     } 
     br.close(); 
     return sb.toString();   
    } 

其次,在制图员:

protected void setup(Context context) 
       throws IOException, InterruptedException { 
      super.setup(context); 

      String lookUpText = readDistributedFile(context); 
      //do something with the text 
     } 

三,运行作业

hadoop jar mapReduceJob.jar the.specific.class -files ../LargeLookUpFileInStoredLocally.txt /user/name/inputdataset/*.gz /user/name/output 

但问题是,这项工作需要很长时间才能加载。 可能是使用分布式缓存不是一个好主意,也可能是我在代码中丢失了某些东西。

我正在使用Hadoop 2.5。 我已经检查了一些相关的问题,例如[1]。

任何想法都会很棒!

[1] Hadoop DistributedCache is deprecated - what is the preferred API?

回答

0

分布式缓存主要用于移动它们通过地图所需的文件减少在任务节点,并不罐子的一部分。

其他用法是在执行包含大小数据集的连接时,为了不使用多个输入路径,我们使用单个输入(大)文件,然后使用分布式缓存获取另一个小文件,然后比较(或加入)两个数据集。

在您的情况下更多时间的原因是因为您试图在地图缩小开始之前读取整个2 GB文件(因为它是在安装方法中启动的)。

你可以给出你为什么使用分布式缓存加载巨大的2GB文件的原因。

+0

非常感谢您的回复。我只需要一种方法来加载除我的数据集以外的额外输入。这个2G文件将以不同于数据集的方式进行处理。当我在本地加载它时(作为第三个参数),该类抛出Java堆空间错误。以这种方式搜索一些网站后。你知道更好的方法吗? – Daisy

+0

正如我上面所说,多输入是另一种选择。你将有两个映射器,每个处理不同的格式。但是你也需要一些属性,这在你的实际输入中也是存在的。最终你正在加入。你能解释一下,你对这个文件做了什么,以及你如何将它与实际输入连接起来? – Ramzy

+0

此大文件被视为“作业处理主数据集所需的额外只读数据”。因此,根据Hadoop:权威指南,可以使用“作业配置”或“分布式缓存”来完成。我的问题是这个文件真的很大。 – Daisy