我正在尝试使用Hadoop Streaming来运行两个命令,例如gunzip | map_to_old_format.py
,但是错误的是gzip说“| .gz not found”或者其他类似的东西(仅当通过Hadoop运行时...如果我在命令行上运行,它运行正常。)
由于我无法弄清楚如何在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)
以及描述为here的Wrapper方法。
答案 0 :(得分:2)
我对Hadoop一无所知,但我猜测echo $data | gunzip
不起作用,因为$data
是一行data
,而$data
本身就是#!/bin/bash
gunzip | map_to_old_format.py
可能不是gzip格式。而不是逐行传递数据,你不能只在bash脚本文件中执行此操作吗?
cat data.gz | gunzip_and_map_to_old.sh
然后您可以通过传递gzip文件来调用它:
{{1}}
答案 1 :(得分:1)
这不能回答我的确切问题,但我可以通过将-jobconf
stream.recordreader.compression=gzip
添加到我的Hadoop命令(source where I learned this)来绕过它:
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脚本来完成上述操作,所以如果有可能,请告诉我。
答案 2 :(得分:1)
Hadoop流通常使用TextInputFormat读取输入文件,并通过std in将其逐行传递给python映射器(使用制表符分隔键和值(在大多数情况下是行号和行文本)。 / p>
如果输入文件的文件扩展名没有以.gz结尾,那么hadoops TextInputFormat在向你传递一行之前不会知道gunzip文件内容。您可以按照其他答案中的建议配置属性以强制hadoop对该文件进行gunzip。