优化从大型数据集中提取文本

时间:2014-10-05 11:16:36

标签: linux search grep

我有一个反复出现的问题,我需要搜索所有与模式匹配的线程的日志文件。例如以下

 (thread a) blah blah
 (thread b) blha
 (thread a) match blah
 (thread c) blah blah
 (thread d) blah match
 (thread a) xxx 

将生成线程a&的所有行。 d

有多个日志文件(已压缩)。多个是数百或数千。每个文件最多约20MB未压缩。

我现在这样做的方法是首先在所有文件中使用grep“match”,将(thread x)部分剪切为sort / uniq文件,然后在原始日志集上使用匹配线程的文件上使用fgrep。

我已经将最初的grep和最终的grep并行化了。然而,这仍然很慢。

有没有办法提高此工作负载的性能? (我虽然hadoop,但它需要太多资源来设置/实现)

这是整个过程的脚本。


    #!/bin/bash
    FILE=/tmp/thg.$$
    PAT=$1
    shift
    trap "rm -f $FILE" 3 13
    pargrep "$PAT" $@ | awk '{ print $6 }' | sed 's/(\(.*\)):/\1/' | sort | uniq >$FILE
    pargrep --fgrep $FILE $@
    rm -f $FILE

并行grep是一个更长的脚本,它管理最多N个grep进程的队列,这些进程可以处理M个文件。每个grep进程都会生成一个中间文件(在/ dev / shm或/ tmp - 一些内存文件系统中),然后在队列从任务中耗尽时将其连接起来。

我必须重启我的工作站,因为它运行了一组~3000个文件超过24小时。我猜两个带有8GB和16GB交换的双核不能达到这样的工作量: - )

1 个答案:

答案 0 :(得分:0)

<强>更新

要同时解压缩和grep您的文件,请尝试使用GNU Parallel这样的内容:

parallel -j 8 -k --eta 'gzcat {} | grep something ' ::: *.gz 

原始答案

嗯......我看到你没有得到任何答案,所以我会伸出脖子试试看。我没有对此进行测试,因为我没有多少备用GB的数据......

首先,我会对脚本进行基准测试,看看正在吃什么的时间。具体而言,它是初始grep阶段还是awk|sed|sort|uniq阶段?

我会删除sort|uniq,因为我怀疑排序多GB会耗费你的时间。如果是这种情况,可以尝试将sort|uniq替换为awk,如下所示:

pargrep ... | ... | awk '!seen[$0]++'

只会在第一次出现时打印每一行而无需对整个文件进行排序。

如果做不到这一点,我认为您需要对各个阶段的时间进行基准测试并报告。此外,您应该考虑发布您的pargrep代码,因为这可能是瓶颈。另外,你考虑过使用GNU Parallel吗?