3

希望您能够帮助我。hadoop map-reduce 有一个令人头疼的问题。我一直在 map-reduce 上成功使用“-files”选项,hadoop 版本为 1.0.3。但是,当我使用“-archives”选项时,它会复制文件,但不会解压缩它们。我错过了什么?文档说“档案(zip、tar 和 tgz/tar.gz 文件)在从节点上未归档”,但这不是我所看到的。

我创建了 3 个文件 - 一个文本文件“alice.txt”、一个 zip 文件“bob.zip”(包含 b1.txt 和 bdir/b2.txt)和一个 tar 文件“claire.tar”(包含 c1.txt和 cdir/c2.txt)。然后我通过调用 hadoop 作业

hadoop jar myJar myClass -files ./etc/alice.txt -archives ./etc/bob.zip,./etc/claire.tar <input_path> <output_path>

这些文件确实存在并且格式正确:

% ls -l etc/alice.txt etc/bob.zip etc/claire.tar
-rw-rw-r-- 1 hadoop hadoop     6 Aug 20 18:44 etc/alice.txt
-rw-rw-r-- 1 hadoop hadoop   282 Aug 20 18:44 etc/bob.zip
-rw-rw-r-- 1 hadoop hadoop 10240 Aug 20 18:44 etc/claire.tar
% tar tf etc/claire.tar
c1.txt
cdir/c2.txt

然后我让我的映射器测试是否存在有问题的文件,就像这样,其中“lineNumber”是传递给映射器的键:

String key = Long.toString(lineNumber.get());
String [] files = {
    "alice.txt",
    "bob.zip",
    "claire.tar",
    "bdir",
    "cdir",
    "b1.txt",
    "b2.txt",
    "bdir/b2.txt",
    "c1.txt",
    "c2.txt",
    "cdir/c2.txt"
};
String fName = files[ (int) (lineNumber.get() % files.length)];
String val = codeFile(fName);
output.collect(new Text(key), new Text(val)); 

支持例程“codeFile”是:

private String codeFile(String fName) {
    Vector<String> clauses = new Vector<String>();
    clauses.add(fName);
    File f = new File(fName);

    if (!f.exists()) {
        clauses.add("nonexistent");
    } else {
        if (f.canRead()) clauses.add("readable");
        if (f.canWrite()) clauses.add("writable");
        if (f.canExecute()) clauses.add("executable");
        if (f.isDirectory()) clauses.add("dir");
        if (f.isFile()) clauses.add("file");
    }
    return Joiner.on(',').join(clauses);
}

使用 Guava 'Joiner' 类。映射器的输出值如下所示:

alice.txt,readable,writable,executable,file
bob.zip,readable,writable,executable,dir
claire.tar,readable,writable,executable,dir
bdir,nonexistent
b1.txt,nonexistent
b2.txt,nonexistent
bdir/b2.txt,nonexistent
cdir,nonexistent
c1.txt,nonexistent
c2.txt,nonexistent
cdir/c2.txt,nonexistent

所以你看到了问题 - 存档文件在那里,但它们没有解压缩。我错过了什么?我也尝试过使用 DistributedCache.addCacheArchive() 而不是使用 -archives,但问题仍然存在。

4

1 回答 1

0

分布式缓存不会将存档文件解压缩到任务的本地工作目录中 - 每个任务跟踪器上都有一个位置用于整个作业,并且在那里解压缩。

您需要检查 DistributedCache 以找到该位置并在那里查找文件。DistributedCache的 Javadocs显示了一个提取此信息的示例映射器。

您可以在定义 -files 和 -archives 通用选项时使用符号链接,并且将在 map / reduce 任务的本地工作目录中创建符号链接,从而使这更容易:

hadoop jar myJar myClass -files ./etc/alice.txt#file1.txt \
    -archives ./etc/bob.zip#bob,./etc/claire.tar#claire

然后您可以在尝试打开存档中的文件时使用映射器中的片段名称:

new File("bob").isDirectory() == true
于 2013-08-22T23:54:33.953 回答