Lucene核心--构建Lucene搜索(下篇,理论篇)

时间:2022-08-27 11:47:14

2.1.6 截取索引(Indextruncate)

一些应用程序的所以文档的大小先前是不知道的。作为控制RAM和磁盘存储空间的使用数量的安全机制,你可能想要限制每个字段允许输入索引的输入数量。一个大的二进制文档偶尔被错误地划分为文本文档,或者包含嵌入在它中的二进制被你的过滤器错误地处理,这些都是可能的。

另外一些应用程序处理知道文档大小,但是你想索引仅仅是其中的一部分内容。例如,你可能想每个文档索引仅仅200个单词或者字数。为了支持反转的情况,IndexWriter允许你截取每个字段索引以便于仅仅首先N个terms用于analzyed字段来建立索引。通过传入参数MaxField-Length.UNLIMITED和MaxField-Length.LIMITED来截取还是不做截取操作,MaxField-Length.LIMITED意味着字段会被截取10,000terms条。

使用任何字段截取前,请仔细地考虑一下。它意味着仅仅首先N个terms能够被搜索到,任何超过第N term将被完全忽略掉。

2.1.7 Near-real-time搜索

Lucene 2.9 引入了一个重要的特性—接近实时搜索,它关注于所有搜索引擎频繁的受到的一个挑战:在建立索引后能够迅速地搜索到documents。许多应用程序有这样的要求,但是对于实现来说,它是一个挑战。幸运的是,现在Lucene通过提供这个方法IndexWriter使之很容易实现:

IndexReader getReader()

这个方法立刻刷新任何缓存中添加或者删除的documents,然后,创建一个新的只读的IndexWriter,它包括哪些documents。在它的实现内部,一个新的打开的reader以一种新高效的方式被实例化,以便于任何旧的段(segments)与先前reader一样被共享。这样,如果仅仅几个文档被添加,这个转向时间将通常会很快。注意到,调用getReader必然使你的索引吞吐量的速度降低,因为它引起IndexWriter立刻冲刷一个新的段(segment),代替了等待直到它的RAM缓存已经满了。

2.1.8 优化一个索引

当你搜索索引时,Lucene必须分开地地搜索任一segment,然后,结合这个结果。尽管这无暇地奏效,通过优化索引应用程序处理大的索引会发现搜索性能得到了提高,其原因是由于它合并了许多segments到一个或者几个segments。在优化的过程中,我们看看磁盘的消耗情况。

没有优化情况下,你得到极好的搜索吞吐量是完全有可能的。因此,确保首先测试是否拟需要考虑优化索引。IndexWriter显露了四个进行优化的方法:

  • optimize() 使产生的索引到一个单一的段中,直到操作完成时才返回。
  • optimize(int maxNumSegments) 众所周知,它作为部分的优化,减少索引到指定最大的段数    maxNumSegments。因为最终的合并到一个段是花费比较大,就优化而言,五个段应该是比优化到一个段中要 快一点。为了更慢的搜索速度,允许你折中一下得到更少的优化时间。
  • optimize(boolean doWait)  doWait的值为false时,立刻调用并返回,而必要的合并操作在后台进行。
  • optimize(int maxNumSegments, boolean doWait) 合并以上两个方法的特性,运行优化操作。

索引优化消耗大量的CPU和输入/输出(I/0)资源。因此,谨慎地使用它。

2.1.9 其它directory实现

无论什么时候Lucene需要对索引进行读或者写时,它使用Directory方法实现这个操作。这些类,有具体的Directory实现从文件系统中读和写文件。它们的子类是基于抽象FSDirectory类。不幸的是,没有单一最好FSDirecotry实现。在某一个情形下,任何一个类都有潜在严重的限制。

Ø  SimpleFSDirectory 使用访问java.io.* APIs,遗憾的是,在读取过程中这个Directory实现不能扩展,原因是当多个线程在使用是,它必须使用内部锁来避免在java.io.*中缺乏按位置读取。

Ø  NIOFSDirectory 使用java.nio.* APIs按位置读取,当读取索引时,无内部锁以及使用多线程扩展性好。遗憾的是,由于长时间存在windows上的JREs问题,NIOFSDirectory变现不太理想,可能比SimpleFSDirectory更糟糕。

Ø  MMapDirectory 使用是内存映射I/O,没有任何锁。因此,它扩展到线程上非常好。但是因为内存I/O消耗线程地址空间,相当于你的索引的大小,在64位JRE上使用它最佳(依赖于OS)。Java没有提供一个清理”unmap”映射内存的文件区域,那意味着垃圾收集器起作用时,内在的文件会关闭以及内存会被释放。这意味着你能够轻易地有许多剩余的maps,消耗大量线程地址空间块以及遗留底层索引文件打开的时间比你希望的更高。另外,32为的JREs, 你肯能会遇到OutOfMemoryError 内存溢出错误。MMapDirectory Directory提供了setMaxChunkSize 方法避免这种情况发生。

2.1.10 并发、线程安全和锁问题

在这一节,我们讨论三个相近且相关的话题:多JVMs访问一个索引、IndexReader和IndexWriter的线程安全以及锁机制。理解这些内容是有必要的,尤其是对于并行服务于多个用户或者通过并发处理一些操作来扩展应用程序。

2.1.10.1 线程和多虚拟机安全

Lucene核心--构建Lucene搜索(下篇,理论篇)

Lucene的并发规则是很简单的:

ü  在一个单一索引上,任意数量仅仅只读IndexReader可能立刻打开。如果这些reader在相同的JVM还是多个JVMs,或者相同的计算机还是多个计算机。记住,在一个单一JVM中,对于给予索引资源的使用和性能的原因而分享单一的IndexReader实例使用多线程。例如,多线程或者多进程可能并行搜索相同的索引。

ü  仅仅一个单一的writer可能为索引所打开。Lucene使用一个写锁文件强制实施。只要一个IndexWriter创建了,一个写锁被获取。仅仅当写锁被关闭了,写锁就释放。既然这样,如果你使用IndexWriter对索引做了一些改动—例如,改变norms或者删除documents—然后IndexWriter充当一个writer:在做第一个改变前,它必须成功地获取写锁,仅仅释放它立刻关闭。

ü  IndexReader可能打开了,甚至当一个IndexWriter正在做对索引一些改变。任一IndexWriter在它打开时将总是展示索引。IndexWriter不会看到任何改变直到writer提交和reader再次被打开。当一个IndexReader已经代开了,以create = true打开一个新的IndexWriter是比较好的。IndexReader将继续搜索它的索引视图点。

ü  任何数量线程能够共享一个单一IndexReader实例或者InexWriter。这些内不仅仅是线程安全的,也是线程有好的,意味着他们通常对于添加线程扩展性挺好的(假如你的硬件有并发能力,因为大量的同步代码在内部是保持一个最小量的)

正如你看到的,Lucene 与多线程和多JVMs工作挺好的。但是,如果你需要在一个远程文件系统上分享一个索引,有意思的挑战。

2.1.10.2 从远程文件系统中访问索引

如果你打算有多个JVMs在不同的计算机上,访问相同的索引,你将不得不显露地访问远程文件系统的索引。一个普通的配置就是有一个单一专门的计算机在本地写入索引文件系统到存储索引远程计算机,然后,多台计算机通过一个远程文件系统实现搜索索引的功能。这样一个配置能够起作用,但是,相对于在本地文件系统而言,这个性能经常很糟糕。最佳的性能就是重复一个索引重复(replication)到每台需要做搜索的计算机文件系统中。Solr,在Lucene之上构建的企业搜索服务,支持盒子之外的replication功能。如果你仍然打算从一个远程文件系统中访问索引,意识到这方面的限制是很重要的。

2.1.10.3 索引锁

在某一刻,增强一个单一writer意味着一个一个IndexWriter或者一个IndexReader做删除或者改版norms,Lucene使用一个基于一个文件锁:如果这个锁文件(默认writer.lock)存在于你的索引目录中,一个当前的writer有索引代开。任何尝试去在相同索引上创建writer都会得到一个LockObtainFailedException。这个是一个相当重要的保护机制,这是因为,如果writer偶然创建一个单一索引,那将快速导致索引混乱。

Lucene允许你改变你的锁实现:任何LockFactory的子类能够通过调用Directory.setLockFactory作为你的锁实现的集合。确保在调用这个方法前打开一个在那个Directory下的IndexWriter实例。正常地情况下,你没有必要担心你使用的是哪个锁。通常只有拥有多个计算机或者JVMs的高级应用程序操作索引才有需要个性化锁的实现。

Lucene核心--构建Lucene搜索(下篇,理论篇)






Lucene核心--构建Lucene搜索(下篇,理论篇)的更多相关文章

  1. Lucene核心--构建Lucene搜索(上篇,理论篇)

    2.1构建Lucene搜索 2.1.1 Lucene内容模型 一个文档(document)就是Lucene建立索引和搜索的原子单元,它由一个或者多个字段(field)组成,字段才是Lucene的真实内 ...

  2. 关于React前端构建的一般过程 - 理论篇

    概要 本文以个人阅读实践经验归纳前端架构构建过程,以Step by Step方式说明创建一个前端项目的过程.并会对每个阶段所使用的技术进行可替代分析,如Express替换Hapi或者Koa的优缺点分析 ...

  3. Lucene简介(理论篇)

    Lucene 是一个软件程序的库或者说是一个工具套件,而不是一个完全的具有搜索特性的应用程序.它关注于自己的文本检索和搜索功能,提供API来完成商业中所涉及到的搜索功能.在搜索功能中,Lucene的功 ...

  4. 记一次企业级爬虫系统升级改造(五):基于JieBaNet+Lucene.Net实现全文搜索

    实现效果: 上一篇文章有附全文搜索结果的设计图,下面截一张开发完成上线后的实图: 基本风格是模仿的百度搜索结果,绿色的分页略显小清新. 目前已采集并创建索引的文章约3W多篇,索引文件不算太大,查询速度 ...

  5. lucene 核心概念及入门

    lucene Lucene介绍及核心概念 什么是Lucene Lucene是一套用于全文检索和搜索的开放源代码程序库,由Apache软件基金会支持和提供.Lucene提供了一个简单却强大的应用程序接口 ...

  6. 基于JieBaNet+Lucene.Net实现全文搜索

    实现效果: 上一篇文章有附全文搜索结果的设计图,下面截一张开发完成上线后的实图: 基本风格是模仿的百度搜索结果,绿色的分页略显小清新. 目前已采集并创建索引的文章约3W多篇,索引文件不算太大,查询速度 ...

  7. 借助 Lucene.Net 构建站内搜索引擎(上)

    前言:最近翻开了之前老杨(杨中科)的Lucene.Net站内搜索项目的教学视频,于是作为老杨脑残粉的我又跟着复习了一遍,学习途中做了一些笔记也就成了接下来您看到的这篇博文,仅仅是我的个人笔记,大神请呵 ...

  8. 借助 Lucene.Net 构建站内搜索引擎(下)

    前言:上一篇我们学习了Lucene.Net的基本概念.分词以及实现了一个最简单的搜索引擎,这一篇我们开始开发一个初具规模的站内搜索项目,通过开发站内搜索模块,我们可以方便地在项目中集成站内搜索功能.本 ...

  9. Lucene.net站内搜索—3、最简单搜索引擎代码

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

随机推荐

  1. matlab初学之strcat、num2str

    文章出处: http://blog.sina.com.cn/s/blog_6fb8aa0d01019id5.html http://wenda.so.com/q/1439143662729624 ht ...

  2. Spring MVC实现Junit Case

    Spring MVC中编写单元测试(WEB项目): 1. 首先开发一个基类,用于载入配置文件.以下所有的测试实现类都要继承这个类 package com.yusj.basecase; import o ...

  3. 【HDOJ】1076 An Easy Task

    水题,如题. #include <stdio.h> #define chk(Y) (Y%4==0 && Y%100!=0) || Y%400==0 int main() { ...

  4. realloc 函数的使用

    realloc 函数的使用 #include <stdio.h> #include <stdlib.h> #include <iostream> using nam ...

  5. 在iframe里调用parent&period;func&lpar;&rpar;引出的js函数运行在它们被定义的作用域里&comma;而不是它们被执行的作用域里

    有个document里定义了一个函数func(),同时在document里嵌入了一个iframe,在这个iframe里调用父窗口的方法:parent.func(),本来我以为这个函数的运行环境是在这个 ...

  6. Protel99se教程六&colon;创建原理图元件库

    在我们平时使用protel99se进行电路以及PCB设计的时候,系统自带的元件库和PCB封装库,只有一小部分,大部份元件的元件库以及封装库,我们都需要自己制作,使用protel99se,我们可以很容易 ...

  7. MDCC为移动开发者服务:一看、一聊、一聚

    MDCC为移动开发者服务:一看.一聊.一聚-CSDN.NET     MDCC为移动开发者服务:一看.一聊.一聚    发表于2013-11-05 20:54| 2698次阅读| 来源CSDN| 6 ...

  8. 【故障处理】ERROR 1872 &lpar;HY000&rpar;&colon; Slave failed to initialize relay log info structure from the repository

    今天在使用冷备份文件重做从库时遇到一个报错,值得研究一下. 版本:MySQL5.6.27 一.报错现象 dba:(none)> start slave; ERROR (HY000): Slave ...

  9. CSS用HTML中的style属性替换

    废话不多说上代码: 1.用CSS给文字添加背景色: <html> <head> <style type="text/css"> body {ba ...

  10. Go 语言读书笔记

    Go语言的设计理念很明确,就是将动态类型语言的编程容易度和静态类型语言的安全效率结合起来.     Go语言,又称Golang,是Google开发的一款静态强类型.编译型.并发型,并具有垃圾回收机制的 ...