如何在hadoop中处理不可分割的500 MB +输入文件?

时间:2014-05-25 19:48:24

标签: hadoop mapreduce

我正在编写一个hadoop MapReduce作业,它运行在一个完整的Debian镜像(≈40GB)的所有源代码文件上。由于Debian镜像数据位于单独的机器上,而不在hadoop集群中,因此第一步是下载数据。

我的第一个实现下载文件并输出key = $ debian_package,value = $ file_contents。然后,每个密钥的各种值(通常为4)应减少为单个条目。然后,下一个MapReduce作业将作为键在debian包上运行,并将所有文件作为值运行。

然而,我注意到hadoop的输出值非常差,有时可能非常大(700 MB是我见过的最大值)。在MapReduce框架的各个地方,整个文件存储在内存中,有时两次甚至三次。我经常遇到内存不足错误,即使Java堆大小为6 GB。

现在我想知道如何分割数据,以便更好地匹配hadoop的64 MB块大小。

我不能简单地将大文件拆分成多个部分,因为它们是压缩的(tar / bz2,tar / xz,tar / gz,未来可能还有其他文件)。直到我向他们发送dpkg-source以提取整个包(必要!),文件需要保持其完整大小。

我想到的一个想法是将文件存储在第一个MapReduce中的hdfs上,并仅将路径传递给第二个MapReduce。但是,我正在绕过hadoop对数据局部性的支持,还是有办法解决这个问题?

我还缺少其他技术吗?你推荐什么?

1 个答案:

答案 0 :(得分:1)

你是对的。对于Hadoop内部来说,这不是一个好例子。大量的复制......有两个明显的解决方案,假设你不能只是在某处解开它:

  1. 使用几个库中的任何一个来分解tarball,这些库允许您递归地读取压缩文件和存档文件(apache VFS对此有限,但apache压缩库具有更多功能)。
  2. nfs将一堆数据节点本地空间挂载到主节点,然后获取并解压缩到该目录结构中......然后使用forqlift或类似工具将小文件加载到HDFS中。
  3. 另一种选择是编写一个实用程序来执行此操作。我为客户做了这个。 Apache VFS和压缩,truezip,然后hadoop库写(因为我做了一个通用的实用程序,我使用了很多其他库,但这是基本流程。)