在Hadoop中搜索/查找文件和文件内容

24

我目前正在使用Hadoop DFS开展一个项目。

  1. 我注意到在Hadoop Shell中没有搜索或查找命令。有没有办法在Hadoop DFS中搜索和查找文件(例如testfile.doc)?

  2. Hadoop支持文件内容搜索吗?如果支持,如何操作?例如,我在HDFS中存储了许多Word Doc文件,我想列出哪些文件里面含有“计算机科学”这个词语。

其他分布式文件系统呢?文件内容搜索是分布式文件系统的软肋吗?


我在另一篇文章中(https://www.quora.com/What-is-the-best-way-to-index-and-search-files-in-HDFS)回答了提出一个名为Schemaindex的软件来索引hdfs中所有文件名的建议。该软件基于Python和Adminlte(JS)构建。此索引软件还利用HDFS的inotify功能实时监视HDFS。该项目在Github上:schemaindex(https://github.com/qiyangduan/schemaindex)。如果有人想尝试它,可以通过以下方式安装: $ pip install schemaindex $schemaindex runserver 然后您可以创建数据源并“反映”数据源。免责声明:我是作者。 - Qiyang Duan
7个回答

47
  1. 您可以这样操作:hdfs dfs -ls -R / | grep [search_term]
  2. 听起来像是MapReduce作业可能比较适合这里。这里有一个类似的示例,但是针对文本文件。不过,如果这些文件很小,您可能会遇到效率低下的问题。基本上,每个文件都将被分配给一个map任务。如果文件很小,设置map任务的开销可能与处理文件所需的时间相比显著。

1
也许我还应该提一下,Lucene(http://lucene.apache.org/)可以进行索引和搜索,而且我认为有一个Word文档的插件。你可能可以把它们组合起来。我想在Lucene + Hadoop上已经做了一些工作。 - ajduff574
谢谢您的回复。但是,对于许多文件或目录,hadoop dfs -lsr / | grep [search_term] 不是非常慢吗? - leon
它绝对不算快,但也不太糟糕。在我们的群集上,有超过100,000个文件,仍然只需要不到一分钟的时间,我认为这相当可接受。 - ajduff574
我假设递归列表lsr命令没有使用任何map/reduce函数来进行搜索,是吗?为什么Hadoop不支持在元数据级别进行搜索呢?因为所有元数据都存储在Namenode的RAM中,对吧? - leon

4
根据数据在HDFS中的存储方式,您可能需要使用-text选项来进行字符串搜索。在我的情况下,我每天有数千条消息存储在一系列AVRO格式的HDFS序列文件中。从边缘节点的命令行中,这个脚本:
  1. 搜索/data/lake/raw目录的第一级以获取文件列表。
  2. 将结果传递给awk,输出第6和8列(日期和文件名)
  3. Grep输出与所询问的文件日期(2018-05-03)相符的行。
  4. 将这些具有两列的行传递给awk,只输出第2列,即文件列表。
  5. 使用while-loop读取每个文件名,并将其作为文本从HDFS中提取出来。
  6. 对文件的每一行进行grep,以查找字符串“7375675”。
  7. 满足该条件的行将被输出到屏幕(stdout)上。
有一个solr jar-file实现,据说更快,但我没有尝试过。
hadoop fs -ls /data/lake/raw | awk {'print $6"   "$8'} | grep 2018-05-03 | awk {'print $2'} | while read f; do hadoop fs -text $f | grep 7375675 && echo $f ; done

4

您可以使用hadoop.HdfsFindTool与solr一起使用,它比'hdfs dfs ls -R'更快速且更有用。

hadoop jar search-mr-job.jar org.apache.solr.hadoop.HdfsFindTool -find /user/hive/tmp -mtime 7

Usage: hadoop fs [generic options]
    [-find <path> ... <expression> ...]
    [-help [cmd ...]]
    [-usage [cmd ...]]

1

通常在hadoop中搜索文件时,如ajduff574所述,可以使用以下命令:

hdfs dfs -ls -R $path | grep "$file_pattern" | awk '{print $8}'

该代码简单地打印出每个模式的路径,如果需要在文件内容中搜索,则可以进一步进行操作。例如:

hdfs dfs -cat $(hdfs dfs -ls -R $path | grep "$file_pattern" | awk '{print $8}') | grep "$search_pattern"

search_pattern: 要在文件中查找的内容

file_pattern: 要查找的文件。

path: 递归查找的路径,包括子文件夹。


0

对于1,您可以这样搜索:

hadoop -find . -name "<name_of_file>"

0

1.- HDFS有一个名为-find的查找命令,对于你的第一个例子,可以这样使用:

hdfs dfs -find /some/path/ -name "testfile.doc"

2.- 对于内容搜索,我建议列出文件并将结果保存在文件中

  hdfs dfs -ls -R /some/path/ >> someFile

然后只需对该文件添加一些过滤器,例如:

  cat someFile | grep "computer science"

然后你将获得你的结果。


0

我知道这是一个非常老的话题,但是当我遇到它时,我想分享我的知识。

可以使用mapReduce作业org.apache.hadoop.examples.Grep来实现此目的:

Hadoop的Grep

hadoop org.apache.hadoop.examples.Grep
Grep <inDir> <outDir> <regex> [<group>]
Generic options supported are
-conf <configuration file>     specify an application configuration file
-D <property=value>            use value for given property
-fs <local|namenode:port>      specify a namenode
-jt <local|resourcemanager:port>    specify a ResourceManager
-files <comma separated list of files>    specify comma separated files to be copied to the map reduce cluster
-libjars <comma separated list of jars>    specify comma separated jar files to include in the classpath.
-archives <comma separated list of archives>    specify comma separated archives to be unarchived on the compute machines.

The general command line syntax is
bin/hadoop command [genericOptions] [commandOptions]

不幸的是,它似乎没有输出包含搜索词的实际文件,因此在您的情况下可能并不真正有用。 - mwol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接