我有大约 1000 个文件
,每个文件的大小为 1GB
。我需要在所有这些 1000 个文件
中找到一个字符串,以及哪些文件包含该特定字符串。我正在使用 Hadoop 文件系统,所有这些 1000 个文件
都在 Hadoop 文件系统中。
所有 1000 个文件
都在真实文件夹下,所以如果我这样做,我将获得所有 1000 个文件
。我需要在真实文件夹下找到哪些文件包含特定字符串 hello。
bash-3.00$ hadoop fs -ls /technology/dps/real
这是我在 hdfs 中的数据结构-
row format delimited
fields terminated by '\29'
collection items terminated by ','
map keys terminated by ':'
stored as textfile
我如何编写 MapReduce 作业来解决这个特定问题,以便我可以找到哪些文件包含特定字符串?任何简单的例子都会对我有很大帮助。
更新:-
在 Unix 中使用 grep 我可以解决上述问题场景,但是它非常非常慢并且需要很多时间才能获得实际输出-
hadoop fs -ls /technology/dps/real | awk '{print $8}' | while read f; do hadoop fs -cat $f | grep cec7051a1380a47a4497a107fecb84c1 >/dev/null && echo $f; done
所以这就是我寻找一些 MapReduce 作业来解决此类问题的原因...
最佳答案
听起来您正在寻找类似 grep 的程序,使用 Hadoop Streaming 很容易实现(Hadoop Java API 也可以):
首先,编写一个映射器,如果正在处理的行包含您的搜索字符串,则输出正在处理的文件的名称。我使用 Python,但任何语言都可以:
#!/usr/bin/env python
import os
import sys
SEARCH_STRING = os.environ["SEARCH_STRING"]
for line in sys.stdin:
if SEARCH_STRING in line.split():
print os.environ["map_input_file"]
此代码从 SEARCH_STRING
环境变量中读取搜索字符串。在这里,我拆分了输入行并检查搜索字符串是否匹配任何拆分;您可以更改它以执行子字符串搜索或使用正则表达式来检查匹配项。
接下来,使用此映射器而不使用缩减器运行 Hadoop 流作业:
$ bin/hadoop jar contrib/streaming/hadoop-streaming-*.jar \
-D mapred.reduce.tasks=0
-input hdfs:///data \
-mapper search.py \
-file search.py \
-output /search_results \
-cmdenv SEARCH_STRING="Apache"
输出会分几部分写;要获得匹配项列表,您可以简单地对文件进行 cat(前提是它们不太大):
$ bin/hadoop fs -cat /search_results/part-*
hdfs://localhost/data/CHANGES.txt
hdfs://localhost/data/CHANGES.txt
hdfs://localhost/data/ivy.xml
hdfs://localhost/data/README.txt
...
关于java - 使用 Hadoop 查找包含特定字符串的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11732936/