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



我正在写一个hadoop MapReduce作业,它运行在一个完整的Debian镜像(≈40 GB)的所有源代码文件上。由于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对数据局部性的支持,或者有办法解决这个问题?

我还缺少其他的技巧吗?你有什么建议吗?

你是正确的。这对Hadoop内部来说不是一个好例子。大量的抄袭……假设您不能在某个地方解压缩它,那么有两种明显的解决方案:

  1. 使用几个库中的任何一个来分解tarball,这些库允许您递归地读取压缩和归档文件(apache VFS对此的能力有限,但apache压缩库有更多的能力)。
  2. nfs将一堆数据节点本地空间挂载到主节点,然后获取并解压缩到该目录结构中…然后使用forqlift或类似的工具将小文件加载到HDFS。

另一个选择是编写一个实用程序来完成此操作。我为一个客户做过这件事。Apache VFS和压缩,truezip,然后hadoop库编写(因为我做了一个通用实用程序,我使用了很多其他库,但这是基本流程)。

相关内容

  • 没有找到相关文章

最新更新