【问题标题】:Search for a String in 1000 files and each file size is 1GB在 1000 个文件中搜索一个字符串,每个文件大小为 1GB
【发布时间】:2012-07-31 02:45:49
【问题描述】:

我正在开发 SunOS(有点脑残)。以下是上述 Solaris 机器的磁盘吞吐量-

bash-3.00$ iostat -d 1 10
    sd0           sd1           sd2           sd3
kps tps serv  kps tps serv  kps tps serv  kps tps serv
  0   0    0  551  16    8  553  16    8  554  16    8
  0   0    0  701  11   25    0   0    0  1148  17   33
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0
  0   0    0    0   0    0    0   0    0    0   0    0

问题陈述

我有大约1000 files,每个文件的大小为1GB。我需要在所有这些1000 files 中找到一个String 以及哪些文件包含该特定字符串。我正在使用Hadoop File System,所有1000 files 都在Hadoop 文件系统中。

所有1000 files 都在real-time 文件夹下,所以如果我在下面这样做,我将得到所有1000 files。我需要找出哪些文件包含特定的字符串。

bash-3.00$ hadoop fs -ls /apps/technology/b_dps/real-time

所以对于上面的问题陈述,我使用下面的命令来查找所有包含特定字符串的文件-

hadoop fs -ls /apps/technology/b_dps/real-time | awk '{print $8}' | while read f; do hadoop fs -cat $f | grep cec7051a1380a47a4497a107fecb84c1 >/dev/null && echo $f; done

因此在上述情况下,它将找到包含此字符串 cec7051a1380a47a4497a107fecb84c1 的所有文件。它对我来说工作正常,我能够获取包含特定字符串的文件名。

我的问题是-

但是上面命令的问题是,它非常非常慢。那么有什么办法可以parallelize上面的命令或者让上面的命令搜索文件更快吗?

任何建议将不胜感激。

【问题讨论】:

  • 如果文件很大并且命中在文件的早期,grep -l pattern file 而如果grep pattern file >/dev/null && echo file 已经提供了实质性的优化。 grep -q 将提供类似的好处。
  • 所以你是说,我应该做这样的事情grep -l cec7051a1380a47a4497a107fecb84c1 >/dev/null ?
  • 如果您有输入文件名,grep -l pattern file 将打印文件名并在找到匹配项后立即退出。如果输入来自管道,grep -q pattern && print filename。无需重定向到/dev/null。当然,这是假设您有一个带有这些选项标志的 grep

标签: bash shell unix hadoop grep


【解决方案1】:

如果需要,您可以编写一个简单的 MapReduce 作业来实现此目的。不过,您实际上并不需要任何减速器,因此减速器的数量将设置为零。通过这种方式,您可以利用 MapReduce 的并行处理能力和块,虽然文件比串行 grep 快得多。

只需设置一个可以配置为搜索您想要的字符串的映射器。您可能会使用 TextInputFormat 读取文件,拆分行并检查您正在搜索的值。然后,您可以为匹配的 Mapper 写出当前输入文件的名称。

更新:

要开始此操作,您可以从标准字数示例开始:http://wiki.apache.org/hadoop/WordCount。您可以删除 Reducer,只需修改 Mapper。它每次读取输入一行,其中该行作为 Text 对象包含在值中。我不知道您的数据是什么格式,但您甚至可以将文本转换为字符串并针对该值硬编码 .contains("") 以找到您正在搜索的字符串(为了简单起见,而不是速度或最佳实践)。您只需要在命中时检查 Mapper 正在处理哪个文件,然后写出文件名。

【讨论】:

  • 感谢 Binary 的评论,我不擅长编写 MapReduce 作业。你能帮我们吗?如果您需要,我可以提供有关文件结构的更多详细信息。这样我就能明白更多了。
  • 我添加了一些建议,希望对您有所帮助。
【解决方案2】:

您可以从 grep 类中获得提示。它随示例文件夹中的分发一起提供。

./bin/hadoop jar hadoop-mapred-examples-0.22.0.jar grep 输入输出正则表达式

关于这个类的实现的详细源码你可以去目录。发行版自带的“src\examples\org\apache\hadoop\examples”

所以你可以在你的主类中这样做:

 Job searchjob = new Job(conf);    
 FileInputFormat.setInputPaths("job Name", "input direcotory in hdfs");
      searchjob.setMapperClass(SearchMapper.class);    
      searchjob.setCombinerClass(LongSumReducer.class);
      searchjob.setReducerClass(LongSumReducer.class);

您可以在 SearchMapper.class 中执行此操作。

   public void map(K key, Text value,
                      OutputCollector<Text, LongWritable> output,
                      Reporter reporter)
        throws IOException {
        String text = value.toString();
        Matcher matcher = pattern.matcher(text);
        if(matcher.find()) {
          output.collect(key,value);
}

【讨论】:

  • 您能解释一下 OutputCollector 与 Context 的比较吗?我见过几个使用 Context 而不是这个 OutputCollector 的映射器
  • 另外我认为你需要添加搜索模式——例如:Pattern p = Pattern.compile("&lt;text to search for&gt;");Matcher matcher = p.matcher(text);
【解决方案3】:

如果您有 1000 个文件,是否有任何理由使用细粒度并行化技术?为什么不直接使用 xargs 或 gnu 并行,并将工作拆分到文件中,而不是将工作拆分到文件中?

此外,您似乎在 grepping 一个文字字符串(不是正则表达式);您可以使用 -F grep 标志来搜索字符串文字,这可能会加快速度,具体取决于 grep 的实现/优化方式。

我没有专门使用 mapReduce,所以这篇文章可能会也可能不会。

【讨论】:

  • 如果必须在 Unix 中完成,那么我需要在上面的命令中进行哪些更改,因为您提到了有关使用 -F grep 的一些内容。你能修改我的 Unix 命令以便我能更理解它吗?这将有助于我理解它。
  • grep -F cec7051a1380a47a4497a107fecb84c
  • grep -F cec7051a1380a47a4497a107fecb84c *fgrep cec7051a1380a47a4497a107fecb84c * 您需要最后的类型 - 在这种情况下,通配符 ' * ' 表示,在所有文件中搜索
猜你喜欢
  • 1970-01-01
  • 2015-02-07
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 2013-04-27
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多