1

我正在尝试使用 Hadoop Streaming 来运行两个命令,gunzip | map_to_old_format.py例如美好的)。

由于我不知道如何即时在 Python 中进行 gunzip,因此我想创建一个 shell 脚本来为我执行此命令组合(例如gunzip_and_map_to_old.sh)。我尝试了以下方法,但 gzip 不喜欢(gzip 抱怨“gzip:stdin:不是 gzip 格式”):

#!/bin/bash
while read data; do
    echo $data | gunzip | map_to_old_format.py $2
done

关于 python gunzip,我尝试了这里f = gzip.GzipFile("", "rb", fileobj=sys.stdin)描述的 Wrapper 方法。

4

3 回答 3

2

我对 Hadoop 一无所知,但我猜这echo $data | gunzip行不通,因为$data它是一行data,并且$data它本身可能不是 gzip 格式。您不能在 bash 脚本文件中执行此操作,而不是逐行传递数据吗?

#!/bin/bash
gunzip | map_to_old_format.py

然后,您可以通过传入 gzip 文件来调用它,如下所示:

cat data.gz | gunzip_and_map_to_old.sh
于 2012-05-12T22:06:36.270 回答
1

这并没有回答我的确切问题,但我能够通过添加-jobconf stream.recordreader.compression=gzip到我的 Hadoop 命令(我了解到这一点的来源)来绕过它:

hadoop jar /usr/lib/hadoop/contrib/streaming/hadoop-streaming-*.jar \
    -jobconf stream.recordreader.compression=gzip \
    -D mapred.reduce.tasks=0 \
    -file map_to_old_format.py \
    -mapper map_to_old_format.py \
    -input /mydata/* -output output/newdata

注意:我仍然很好奇如何通过 shell 脚本完成上述操作,所以如果可能的话,请告诉我。

于 2012-05-12T20:18:24.087 回答
1

Hadoop 流通常使用 TextInputFormat 读取输入文件,并通过 std in 将其逐行传递给您的 python 映射器(使用制表符分隔键和值(在大多数情况下是行号和行文本)。

如果输入文件的文件扩展名不是以 .gz 结尾,那么 hadoops TextInputFormat 在一次传递一行之前不会知道 gunzip 文件内容。您可以按照其他答案中的建议配置属性以强制 hadoop 对文件进行压缩。

于 2012-05-12T22:30:33.983 回答