关键词搜索性能优化

来源:互联网 发布:淘宝大象摄影好不好 编辑:程序博客网 时间:2024/04/29 16:46

需求:刚加入新的团队没多久,与项目组的大牛一起进行产品的日志分析。按照前面的设计文档,每台产品运行的服务器一天大概产生3~10G的日志。共有大概30台服务器。所以总共有上限大概为300G的日志每天需要分析。而关键词比较简单,可能是每行日志中包括一个单词,或者短句,目前有30个不等。也就是说每天需要从300G的日志中搜索出包括这些关键词的日志行和对应行的关键词。

当前现状:由于这位大牛需要负责整体的项目实现,进度比较紧张,加之对以前性能设计这部分没有太多的经验,在进行这部分搜索的实现时,直接用正则表达式匹配,一天下来,分析两台服务器就需要2,3个小时,远达不到上面所述的要求。在未做性能优化之前,不可能让老大去给我们增加服务器。而我以前做过性能测试,当然仅仅是测试,没有拿着代码去调优过。不过看在这个份上,大牛让去尝试下,看看能否把这个性能优化下来,至少达到前面所说的性能要求。

 

过程:优化从发现一个问题开始。在测试阶段,大牛发现每天下来,总发现分析不完,而且还一直是某种类型的日志导致的问题。一开始怀疑是乱码的问题,或者是日志文件太大的问题(实际只有20M左右),但是在定位时,发现在分析这行日时,在调用正则表达式的Macher.find方法时(JAVA实现),总是卡在那。就是说过了好几个小时都运行定位不到那一行。这一行是非常特殊的,总共足足有65536个字符,很恐怖吧,而且绝大部分是空格。

定位几个小时后,才发现并非功能问题,而是性能问题。正则表达式在匹配如此长的行,而正则表达式本身比较复杂的情况下,根本就不可能在几个小时内去找到匹配项。这是个教训,也告诉我们正则表达式在匹配时,匹配的字符越长,正则表达式越复杂,性能越差,并且是呈非线性递增的。

 

而从上面这个问题,让我意识到,正则表达式本身匹配是一个相当耗时的东西,需要尽量减少这种操作。另外如果实在需要进行正则匹配,就应该尽量减少待匹配的字符串,降低正则表达式的复杂度。 基于上面两点,以及目前的需求情况,我针对以前的实现做了如下的更改。

1) 从日志搜索的结果来看,每个日志文件中实际出问题的行数,估计在1%~30%之间。而关键词由一至多个单词组成,从每个关键词中抽取出一个关键字,首先先进行关键字(就是一个单词)的匹配,遍历每行的单词与对应关键字是否对应,应用hash集合实现,并利用其contains方法来判断。

 

2) 把出现关键字部分的行抽取出来,然后再进行正则匹配,没有包含关键字的部分可以肯定是不会有关键词的存在的。而正则匹配过程,不再是一次性的,而是先把行通过正则切分成短句数组,然后再在每个短句中进行关键词匹配。

 

3)由于使用的读取文件的IO流为RandomAccessFile方式,经测试非常不恰当,改用BufferReader实现。

 

4)另外还做了两个小优化,针对关键词的处理,都放到类的初始化的时候,而不是在每次查找的时候反复做预处理,另外代码中使用了String.format方式进行某些操作,改用直接的方式进行操作。

 

通过第1)点,由于使用hash的强大性能,使得关键字的匹配,非常快速,比正则表达式不止快了上千倍,另外通过关键字的匹配,过滤掉了70%甚至更多不需要进行正则匹配的行。

通过第2)点,对包含关键字的正则匹配,通过切分成短句,缩小了待匹配的字符长度,从而也降低了后面需要匹配的表示关键词的正则表达式。对性能的提升也比较明显。

 

通过第3)点,使得IO的效率提高了近百倍。

通过第4)点,相关部分的性能提升也比较大。

 

最后通过整体实测,性能较原来,提高了两个数量级,估计在100~200倍之间。对几个文件的抽取测试操作,从400多秒,下降到2秒多。

 

总结:这是我第一次进行性能调优操作,效果还是非常显著的。关键的一点就是,关注耗时的操作在哪些部分,尽量减少耗时或者不进行耗时的操作,把耗时的操作变成不耗时的操作。

其中有一点需要注意,基于关键词的搜索,关键词在日志中出现的次数较少,搜索后进行正则处理的就越少,性能就越好。另外搜索的包含关键字和包含关键词的行数比例,也是一个很重要的参数,目前大概70%~90%左右,也就是说搜索出包含关键字的行,70%~90%包含关键词。

 

在优化后的结果是完全可以满足需求的,但是从算法的极致上讲,以及从目前的情况来看,还可以优化,提高性能50%左右。 尤其是以后在关键词在日志中大量出现,而不是现在的30%,可能达到50%~60%时,上面的优化就不是那么明显了。 后续完全可以不用正则表达式来进行关键词的匹配。

 

题外话: 通过参与这个项目,让自己学了不少东西,包含数据库Hibernate方面的。另外自己还需要熟悉项目中关于多线程的问题,理清几个类的关系,要做到熟练运用。

 

 

 

 

 

原创粉丝点击