如果您只有两个 1 GB 文件,则使用hadoop fs -cat
(或更通用的)可能是可行的。hadoop fs -text
对于 100 个文件,尽管我会使用流式 API,因为它可以用于临时查询,而无需借助完整的 mapreduce 作业。例如,在您的情况下创建一个脚本get_filename_for_pattern.sh
:
#!/bin/bash
grep -q $1 && echo $mapreduce_map_input_file
cat >/dev/null # ignore the rest
请注意,您必须阅读整个输入,以避免出现java.io.IOException: Stream closed
异常。
然后发出命令
hadoop jar $HADOOP_HOME/hadoop-streaming.jar\
-Dstream.non.zero.exit.is.failure=false\
-files get_filename_for_pattern.sh\
-numReduceTasks 1\
-mapper "get_filename_for_pattern.sh bcd4bc3e1380a56108f486a4fffbc8dc"\
-reducer "uniq"\
-input /apps/hdmi-technology/b_dps/real-time/*\
-output /tmp/files_matching_bcd4bc3e1380a56108f486a4fffbc8dc
hadoop fs -cat /tmp/files_matching_bcd4bc3e1380a56108f486a4fffbc8dc/*
在较新的发行版mapred streaming
中,而不是hadoop jar $HADOOP_HOME/hadoop-streaming.jar
应该工作。在后一种情况下,您必须$HADOOP_HOME
正确设置才能找到 jar(或直接提供完整路径)。
对于更简单的查询,您甚至不需要脚本,只需将命令-mapper
直接提供给参数即可。但是对于任何稍微复杂的事情,最好使用脚本,因为获得转义权可能是一件苦差事。
如果您不需要减少阶段NONE
,请为相应的-reduce
选项提供符号参数(或仅使用-numReduceTasks 0
)。但是在您的情况下,为了将输出合并到一个文件中,有一个减少阶段很有用。