`
qindongliang1922
  • 浏览: 2149211 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:116375
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:124638
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:58538
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:70412
社区版块
存档分类
最新评论

Lucene实时思路

阅读更多

这里是solr的实时搜索介绍http://sling2007.blog.163.com/blog/static/84732713201391752611763/
lucene的实时搜索可以分成:实时和近实时的搜索。实时只能依靠内存了。近实时可以用lucene中提供org.apache.lucene.index.DirectoryReader.open(IndexWriter writer, boolean applyAllDeletes) throws IOException
,可以在不十分影响性能的前提下,实现近实时的效果(比如每1s打开一次搜索,这类似于solr中的实现)。

一:实时搜索
lucene一般有ramdirectory和fsddirectory两种方式存储索引,第一个是内存方式,非常快,但没有持久化;第二个是硬盘方式,慢,但有持久化。
Lucene 的事务性,使得Lucene 可以增量的添加一个段,我们知道,倒排索引是有一定的格式的,而这个格式一旦写入是非常难以改变的,那么如何能够增量建索引呢?Lucene 使用段这个概念解决了这个问题,对于每个已经生成的段,其倒排索引结构不会再改变,而增量添加的文档添加到新的段中,段之间在一定的时刻进行合并,从而形成新的倒排索引结构。
Lucene 的事务性,使得Lucene 的索引不够实时,如果想Lucene 实时,则必须新添加的文档后IndexWriter 需要commit,在搜索的时候IndexReader 需要重新的打开,然而当索引在硬盘上的时候,尤其是索引非常大的时候,IndexWriter 的commit 操作和IndexReader 的open 操作都是非常慢的,根本达不到实时性的需要。

其实一般的应用,如果可以允许有1、2分钟的延时,那么用fsddirectory就足够了,每1分钟增加索引并commit即可。
但是如果有需求,要实时搜索的话,那么就需要用ram和fsd两种方式来组合使用了。

大致原理是用multireader组合多个索引的searcher即可。
(multireader可以为实时搜索服务,也可用于分布式索引啊)
实时步骤是:
1、先打开fsdindex,用于搜索;如果新增文档,则加入ramindex,并重打开ramsearcher。ram的重打开是很快的。
然后定时把ramindex写入磁盘。
2、在写入的时候,fsd需要commit并重新打开一个reader,这个时候需要新开一个ramindex。
在此时的搜索需要打开3个searcher,原ramsearcher,原fsdsearcher,新ramsearcher。
这个时候原ramindex写入磁盘的时候,只要不commit就不会出现重复结果。
3、ramindex写入磁盘结束,那么需要新打开一个fsdsearcher,这个过程是比较慢的。所以我们保持第2步的3个searcher先不变,继续服务。
4、当心得fsdsearcher打开完毕,那么丢弃原fsdsearcher和原ramseacher。使用新的fsdsearcher和ramsearcher

这4步中的操作大多是原子性的,如果做了(2)但没有做(3),如果来一个搜索,则将少看到一部分数据,如果做了(3)没有做(2)则,多看到一部分数据。所以需要加一个同步锁,以防数据异常。

二、近实时搜索

实现原理:
Near real time search的原理记录在LUCENE-1313和LUCENE-1516里。LUCENE-1313,在Index Writer内部维护了一个ram directory,在内存够用前,flush和merge操作只是把数据更新到ram directory,只有Index Writer上的optimize和commit操作才会导致ram directory上的数据完全同步到文件。LUCENE-1516,Index Writer提供了实时获得reader的API,这个调用将导致flush操作,生成新的segment,但不会commit(fsync),从而减少 了IO。新的segment被加入到新生成的reader里。从返回的reader里,可以看到更新。所以,只要每次新的搜索都从Index Writer获得一个新的reader,就可以搜索到最新的内容。这一操作的开销仅仅是flush,相对commit来说,开销很小。
Lucene的index组织方式为一个index目录下的多个segment。新的doc会加入新的segment里,这些新的小segment每隔一段时间就合并起来。因为合并,总的segment数量保持的较小,总体search速度仍然很快。为了防止读写冲突,lucene只创建新的 segment,并在任何active的reader不在使用后删除掉老的segment。
flush是把数据写入到操作系统的缓冲区,只要缓冲区不满,就不会有硬盘操作。
commit是把所有内存缓冲区的数据写入到硬盘,是完全的硬盘操作。
optimize是对多个segment进行合并,这个过程涉及到老segment的重新读入和新segment的合并,属于CPU和IO-bound的
重量级操作。这是因为,Lucene索引中最主要的结构posting通过VINT和delta的格式存储并紧密排列。合并时要对同一个term的posting进行归并排序,是一个读出,合并再生成的过程。
代码解读:
在IndexWriter获得reader的方法中,主要调用了两个方法doflush()和maybeMerge()。doflush() 将调用DocumentsWriter的flush方法,生成新的segment,返回的reader将能访问到新的segment。 DocumentsWriter接收多个document添加,并写入到同一个segment里。每一个加入的doc会经过多个DocConsumer组 成的流水线,他们包括StoredFieldsWriter(内部调用 FieldsWriter),TermVectorsTermsWriter,FreqProxTermsWriter,NormsWriter等。在外 界没有主动调用flush的情况下,RAM buffer全用完了或者加入的doc数足够大后,才会创建新的segment并flush到目录中。
FreqProxTermsWriter调用TermHashPerField负责term的索引过程,当索引某字段词项时,使用对应 TermsHashPerField的add()函数完成(一个)词项索引过程,并将索引内容(词项字符串/指针信息/位置信息等)存储于内存缓冲中。中 间的过程使用了CharBlockPool,IntBlockPool,ByteBlockPool,只要内存够用,可以不断往后添加。
特性试验:
设计一个文档检索程序,进程管理一个index writer和两个线程,线程A负责新文档的索引,线程B负责处理搜索请求,其中搜索时使用IndexWriter的新API获取新的reader。通过交替的生成index和search的请求,观察search的结果和索引目录的变化。实验结果如下:

1 打开indexwriter时,会生成一个lock文件
2 每次调用reader时,如果发生了更新,会先进行一次flush,把上次积攒在内存中的更新数据写成新的segment,多出一个.cfs。
3 从新的reader中,可以读到之前新加入的doc信息。
4 当新生成的segment达到十次后,会发生一次optimize,生成8个文件,为.fdt, .fdx, .frq, .fnm,
    .nrm, .prx, .tii, .tis。
5 当然,外界也可以主动触发optimize,结果是一样的。optimize前的多个segment的文件以及此前optimize的文件不再有用。
6 因为optimize生成cfs要消耗双倍磁盘空间,并增加额外的处理时间,当optimize的index大小较大,超过了index总大小的10或者一个规定大小时,即使index   writer指定了CFS格式,optimize仍然会保留为多个文件的格式(LUCENE-2773)。
7 调用indexwriter的close方法,lock文件会被释放,但除了optimize的结果文件外,此前生成的文件并不会被删除。只到下次打开此index目录时,不需要的文件才会被删除。
8 当三种情况下,indexwriter会试图删除不需要的文件,on open,on flushing a new    segment,On finishing a merge。但如果当前打开的reader正在使用文件,则不会删除。
9 因此,reader使用完后,一定要调用close方法,释放不需要的文件。


来自http://sling2007.blog.163.com/blog/static/84732713201352011445771/
分享到:
评论

相关推荐

    Lucene7.4位置相关性计算源代码思路.xmind

    Lucene7.4检索和打分过程的源代码阅读思路,这里只针对用BooleanQuery作为Query,从IndexSearch说起,从检索到打分的过程,还加入了自己的无关的一些想法,忽略即可。

    Lucene搜索引擎开发权威经典随书资源7-10

    本书基于Lucene的当前最新版本(2.1)精解了Lucene搜索引擎的相关知识,从基础知识到... 内容精练实用,书中所列代码可以搭建一座中型搜索平台,完整实例再现,让读者紧跟作者构建思路,Lucene搜索引擎技术完美演绎。

    lucene查询结果集分页代码

    在lucene搜索分页过程中,可以有两种方式 一种是将搜索结果集直接放到session中,但是假如结果集非常大,同时又存在大并发访问的时候,很可能造成服务器的内存不足,而使服务器宕机 还有一种是每次都重新进行搜索,这样...

    Lucene搜索引擎开发权威经典随书资源1-6章

    本书基于Lucene的当前最新版本(2.1)精解了Lucene搜索引擎的相关知识,从基础知识到... 内容精练实用,书中所列代码可以搭建一座中型搜索平台,完整实例再现,让读者紧跟作者构建思路,Lucene搜索引擎技术完美演绎。

    基于Lucene的WEB站内搜索引擎的研究与实现

    基于Lucene的WEB站内搜索引擎的研究与实现

    Lucene搜索引擎开发进阶实战_PDF电子书下载

    结合笔者的实际开发经验,总结了一些新的开发技巧和开发思路,并对网上流传的一些错误技术点和代码进行验证,同时给出正确的思路,旨在给开发者提供一本清晰、完整、易懂的指导手册。本书既可为零起点的Lucene初学者...

    Lucene学习思维导图

    学习搜索引擎时,大家往往不能够理清搜索引擎的脉络,通过这本思维导图,大家可以理解学习思路,里面有一些代码,帮助大家更好更快地学习Lucene.

    lucene全文检索

    本文描述了lucene全文检索的技术原理及实现思路,尤其针对java程序员在开发过程中实现检索功能提供了解决方案.

    人工智能-项目实践-搜索引擎-基于lucene的新闻搜索引擎[中科院现代信息检索项目作业]

    整体思路 在实现新闻信息检索系统时首先进行了信息采集,信息采集结束之后使用 Lucene 提供的 api 构建索引库, 前端使用 jsp 接收用户查询,在后台使用 servlet 对用户查询进 行分词处理,之后到索引库中进行文档匹配, ...

    lucene高级智能查询小案例

    目前还有一点bug,但是以实现功能和思路为主,小bug不影响整体功能

    传智播客Lucene3.0_精品课程

    好东西,思路清晰,不错的资源,希望能帮到你.....

    基于Ajax和Lucene的搜索引擎的设计与实现.zip

    同时增加自己对不同方面知识的了解,为后续的创作提供一定的设计思路和设计启发 , 并且可以快速完成相关题目设计,节约大量时间精力,也为后续的课题创作 提供有力的理论依据、实验依据和设计依据,例如提供一些...

    [搜索链接]java(结合lucene)版的公交搜索系统_javaso_new.rar

    学生可以通过这些论文了解到项目的整体框架和设计思路。 设计文档:详细记录了系统的设计过程,包括但不限于需求文档、系统架构设计、数据库设计、界面设计、功能模块设计等。学生可以根据这些文档进行系统的具体...

    elasticsearch设计思路

    介绍elasticsearch如何实现一个分布式近实时的搜索引擎的

    基于java的毕业设计(源代码+论文)3套(2)

    随着计算机专业的普及,越来越多的大学生选择了该热门专业,毕业时的毕业设计需要完整的源码以及论文。...2、[搜索链接]java(结合lucene)版的公交搜索系统_javaso 3、[搜索链接]Java网络爬虫(蜘蛛)源码_zhizhu

    文件检索管理系统

    基于Lucene的文件检索管理系统,可以索引文件,检索文件,文件格式包括word/ppt/pdf等,可以根据思路自己扩展。 该项目是myeclipse下面的一个完整工程,可以直接导入,包含了lib包。 项目采用B/S结构

    Java高级架构面试知识点整理.pdf

    底层的 lucene 介绍一下呗? 10.倒排索引了解吗? 11.es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊? 12.es 生产集群的部署架构是什么?每个索引的数据量大概有多少?每个索引大概有多少个分片? 13....

    Eclipse开发分布式商城系统+完整视频代码及文档

    │ 06.ssm框架整合思路.avi │ 07.ssm框架整合.avi │ 08.测试工程.avi │ 打开必读.txt │ 淘淘商城第一天笔记.docx │ ├─02.第二天 │ 07.商品类目选择完成.avi │ 01.课程计划.avi │ 02.展示首页.avi │ 03....

Global site tag (gtag.js) - Google Analytics