我正在编写一个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对数据局部性的支持,还是有办法解决这个问题?
我还缺少其他技术吗?你推荐什么?
答案 0 :(得分:1)
你是对的。对于Hadoop内部来说,这不是一个好例子。大量的复制......有两个明显的解决方案,假设你不能只是在某处解开它:
另一种选择是编写一个实用程序来执行此操作。我为客户做了这个。 Apache VFS和压缩,truezip,然后hadoop库写(因为我做了一个通用的实用程序,我使用了很多其他库,但这是基本流程。)