在1000个文件中搜索字符串,每个文件大小为1GB

时间:2012-07-31 02:45:50

标签: bash shell unix hadoop grep

我正在研究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。我需要在所有这些String中找到1000 files,以及哪些文件包含该特定字符串。我正在使用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上面的命令或使上面的命令更快地搜索文件?

任何建议都将受到赞赏。

3 个答案:

答案 0 :(得分:1)

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

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

<强>更新

要继续这样做,您可以从标准字数计数示例开始:http://wiki.apache.org/hadoop/WordCount。您可以删除Reducer并只修改Mapper。它在一行中读取输入行,其中行作为Text对象包含在值中。我不知道您的数据是什么格式,但您甚至可以将Text转换为String并对该值进行硬编码.contains(“”)以找到您要搜索的String(为简单起见,不是速度或最佳实践) )。你只需要锻炼Mapper正在处理的文件,然后写出文件名。

答案 1 :(得分:1)

您可以从grep类中获得提示。它附带示例文件夹中的分发。

./ bin / hadoop jar hadoop-mapred-examples-0.22.0.jar grep input output regex

有关此类实现的详细信息,您可以转到该目录。分发附带的“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);
}

答案 2 :(得分:1)

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

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

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