06月 9, 2013

一、背景

搜索引擎的log数据可以用于query理解、user理解、doc理解和ranking。我们运行共现词分析,挖掘出引擎的query log里面共现的词,离线建静态cache,用于提升引擎的性能。

二、共现词分析

分析query log里query的平均的term数,值为5。我们对query log依次进行一至四元共现词分析,高于四元的我们推荐用fullcache解决,而且高元的离线计算成本也太高。

做法如下

首先抽取query里分词后的term,因为term不一定是相邻的,所以根据指定的N元需要进行穷举N元共现词,使用python写map-reduce程序统计共现词。

然而这里统计出来的共现词会有问题,就是会重复。我们需要对共现词进行去重,这里分为同一元去重和不同元去重。

同一元去重

例如,query为 “中国 人民 大学 研究生 ” ,三元共现词有“中国 人民 大学”,“人民 大学 研究生”等四个三元共现词。根据我们的应用场景,所有的三元共现词都建静态cache,然后使用静态cache时,遇到相同的query,只会贪婪匹配第一个三元共现词,即“中国 人民 大学”,其他三个都白建了,这在索引大小膨胀敏感的情况下是不可接受的,需要去重。

不同元去重

还是上面的query,二元共现词有“中国 人民”,“人民 大学”,在已经建了三元共现词的情况下,建这两个二元共现词也同样是白费力气,不会被用到,所以需要去掉已经建过三元共现词的query串再去建二元共现词,这里也需要去重。

去重方案:

这里的方案是对每个query md5一个query id,这样在reduce统计共现词频时,统计query id的数目即可去重同一元的重复。不同元的去重,用上层的共现词对下层的共现词去做去重。步骤如下:

1. 先对N元共现词做N-1元共现词,所有的共现词频用真实词频的负数表示

2. 对新生成的N-1元共现词和之前未去重的N-1元共现词做map-reduce,统计去重后的词频

解决数据倾斜问题

在实现去重方案时,引入了query id, 而大量的高频共现词,导致这些共现词的query id链特别长,出现数据倾斜。

我们在第一次map时,对key做hash多份处理,key 为 “中国_人民”,根据hash的份数,hash为“中国_人民#0”,“中国_人民#1”,…

然后再做一轮map-reduce,即通过hash key和多轮map-reduce解决数据倾斜问题。

共现词部分结果

一至四元共现词及共现频度。

共现词分析实现小细节

现在的实现,把从query中抽取term做成接口对外开放,用户只需要实现process_log接口,从自己的log 中抽取出term,然后喂给共现词分析框架,即可完成多元共现词分析。

三、共现词分析用于静态cache

我们分析log的多元共现词,建静态cache,能有效提升引擎的性能,大量的query会落到静态cache上。在全内存情况下,能够节省CPU计算,即使在超内存情况下,IO落在SSD盘甚至普通盘上,也合并了IO,对引擎的性能提升有好处。

全内存性能提升效果:

超内存性能提升效果:

四、结尾

引擎的log数据包含各种信息,非常有价值,例如对于高latency的query进行分析,或者无少结果query的分析,对log数据进行各种挖掘,能为引擎的性能优化提供很多思路和方案,也能够提升搜索的效果和用户体验。

作者:钓雪

Tags: ,,.