内部信息源与外部信息源搜索引擎优化方法的异同(构造一个真正*敏*感*词*、稳定、可靠的应用(图))

优采云 发布时间: 2022-03-29 10:08

  内部信息源与外部信息源搜索引擎优化方法的异同(构造一个真正*敏*感*词*、稳定、可靠的应用(图))

  核心提示:到目前为止,全文检索根本不是什么高科技门槛。记得之前看过一本书:“今天,任何程序员都可以轻松构建全文检索应用程序。” 是的,全文搜索的基本原理差不多都知道了,剩下的就是练习了。我见过纯自研的,有AS(Advanced Search)、BS(Basic Search)、DI(Di...

  /UploadnewFiles/http://www.xinxilong.com/UploadnewFiles/20090830190617734.gif

  到目前为止,全文检索根本不是一个高科技门槛。我记得读过一本书,上面写着:“今天,任何程序员都可以轻松构建全文检索应用程序。” 是的,全文搜索的基本原理差不多都知道了,剩下的就是练习了。我见过一个“体面的”纯自己开发的全文搜索架构,有AS(高级搜索)、BS(基本搜索)、DI(文摘)等结构,但更多的应用在开源项目上。Apache 的 Lucene 完美定制,是最著名、最古老、使用最广泛的开源全文检索项目之一。本次beta技术沙龙是关于lucene在*敏*感*词*网站中的应用。主讲人是移动之家团队的唐福林(《移动之家》总有东西要分享,

  众所周知,使用 Lucene 构建“索引查询”应用程序非常简单。搭建好环境,引用(修改)演示代码很容易成功。然而,要构建一个真正*敏*感*词*、稳定、可靠的应用程序,并不是那么简单。程序的编写,模块的分布,架构的设计,都有很多周到的关注。根据PPT提供的数据,目前Mobile Home的Lucene应用采用Lucene2.4.1+JDK1.6(64位)的组合,运行在8个CPU,32G在有内存的机器上,数据量超过3300万,原创数据文件超过14G。每天需要支持超过 350,000 次查询,高峰期 QPS 超过 20。

  演讲的主要内容在PPT中,内容非常丰富,不再赘述。需要补充的是,这个PPT讲的很清楚,需求-目标-进度-设计-启动-测试-启动,整个流程很清晰,给出的数据也很精准,我觉得,这也体现了移动端phone home 团队的开发规范。

  因为对Lucene的使用有一点经验,所以在这里补充几句,权利继续貂:

  在*敏*感*词*应用中,Lucene 更适合狭义的“搜索”,不应该负责数据存储。通过查看Lucene的源码我们也可以知道,Document和Field的存储效率还不够好。手机之家团队也发现了这一点,他们的方法是使用Lucene存储索引,使用Memcache + Berkeley DB(Java版)进行存储。这样有两个好处,一是减少了Lucene的数据规模,提高了程序的效率;另一方面,本系统还可以提供一些类似于SQL的查询功能。事实上,Lucene Project 本身似乎也注意到了这个问题,并在 Store 中添加了一个 db 选项,实际上是 Berkeley DB。如果只使用Lucene而不是Documents来存储索引,并且配置合理,单台机器可以支持几十G甚至上百G的索引。在大型应用程序中,Cache 非常重要。PPT中还提到,在程序提供服务之前,可以进行几次“热身”搜索来填充Searcher的Cache。根据我们的经验(Ginkgo Search),我们还可以在应用程序中提供 Cache for Document ,这将大大提高性能(同一个 JVM 内的 Cache 更快)。Lucene自己似乎也注意到了这个问题,在2.4版本中提供了Cache,并提供了LRU Cache的实现。在程序提供服务之前,可以执行搜索以填充 Searcher 的 Cache。根据我们的经验(Ginkgo Search),我们还可以在应用程序中提供 Cache for Document ,这将大大提高性能(同一个 JVM 内的 Cache 更快)。Lucene自己似乎也注意到了这个问题,在2.4版本中提供了Cache,并提供了LRU Cache的实现。在程序提供服务之前,可以执行搜索以填充 Searcher 的 Cache。根据我们的经验(Ginkgo Search),我们还可以在应用程序中提供 Cache for Document ,这将大大提高性能(同一个 JVM 内的 Cache 更快)。Lucene自己似乎也注意到了这个问题,在2.4版本中提供了Cache,并提供了LRU Cache的实现。

  但是根据我们的测试,在极端情况下,这个Cache可能会突破大小限制,一路扩展,最后吃光内存,甚至网上找到的很多LRU Cache实现在极端情况下也可能出现这样的问题(这是也是我们的困惑:反复检查程序逻辑没有问题),最后自己写了一个LRU Cache,修改了很多次。目前是稳定的。在编写Java服务程序时,记得设置退出钩子函数(RunTime.getRunTime.addShutdownHook)是一个非常好的习惯。很多Java程序员没有这个意识,或者只是写了一个finalize函数。因此,当程序异常退出时,可能会导致一些外部资源的状态不稳定。以Lucene为例,之前的IndexWriter默认使用了autoCommit,这样每增加一条记录,就提交一次。好处是如果中断了,之前添加的记录都可以使用。缺点是分度速度很低。新版本中,autoCommit默认为False,速度明显提升(我们测试的结果快了8倍左右),但如果中途异常退出,那就浪费了。如果我们添加一个退出钩子函数并在捕获退出信号时自动调用 writer.close() 方法,就可以避免这个问题。目前的Lucene兼容JDK1.4,其二进制版本也是用JDK1.4编译的。如果对性能要求比较高,可以自行下载Lucene Source Code,并使用更新版本的 JDK 编译它。.jar 文件,根据我的测试,速度大约快 30%。

  PS根据我的观察,国内公司内部的项目名称一般都还算中规中矩,有很多以“er”结尾的,大多是Indexer、Crawler、Layer之类的。似乎很少有外国名字具有“想象力”,例如Hadoop(这是一个“没有理由”的名字),Lucene(这是一个罕见的姓氏)。在中国,我和他们没有多少接触。过去,有一个重要的 DB 叫做 tudui(“土墩”),用于捕虾。目前银杏叶中有一个项目叫LaserTank,与实际使用无关,但给人留下了深刻的印象。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线