Lucene.net(4.8.0) 学习问题记录四: IndexWriter 索引的优化以及思考
前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移。因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3.6.0 ,PanGu分词也是对应Lucene3.6.0版本的。不过好在Lucene.net 已经有了Core 2.0版本(4.8.0 bate版),而PanGu分词,目前有人正在做,貌似已经做完,只是还没有测试~,Lucene升级的改变我都会加粗表示。
Lucene.net 4.8.0
https://github.com/apache/lucenenet
PanGu分词(可以直接使用的)
https://github.com/SilentCC/Lucene.Net.Analysis.PanGu
JIEba分词(可以直接使用的)
https://github.com/SilentCC/JIEba-netcore2.0
Lucene.net 4.8.0 和之前的Lucene.net 3.6.0 改动还是相当多的,这里对自己开发过程遇到的问题,做一个记录吧,希望可以帮到和我一样需要升级Lucene.net的人。我也是第一次接触Lucene ,也希望可以帮助初学Lucene的同学。
一,优化建索引速度的方法总结
1.IndexWriter的简介
http://www.cnblogs.com/dacc123/p/8228298.html
在这片博文,介绍了IndexWriter, 也提到了IndexWriter优化索引速度的方法,但是觉得还比较片面,所以重新写一篇优化索引速度的博文。
2.优化索引速度的方法
2.1 使用更快的硬件设备
使用更快的硬件设备,使用固态硬盘代替普通的硬盘,会提高索引的读写速度。
2.2 设置IndexWriter的RAMBufferSizeMB
设置IndexWriter的RAMBufferSizeMB 使得IndexWriter能利用更多的内存,应对海量的数据,这样IndexWriter的flush的操作也会减少。当然同样的设置还有设置IndexWriter的MaxBufferedDocs ,推荐使用RAMBufferSizeMB 。并且关闭,autoCommit = false。
2.3 设置IndexWriter的MergeFactor
IndexWriter的MergeFactor决定了当索引中segment数量达到多少时,就将这些segment合并成一个大的segment文件。设置MergeFactor越大,IndexWriter将会减少合并的操作,可以提高索引的速度。带来的结果是索引文件中会有很多的segment文件,需要优化,否则会影响搜索速度。所以需要选择一个合适的MergeFactor
2.4 关闭复合文件格式
setUseCompoundFile(false)。生成复合文件会消耗更多的时间,关闭复合文件格式会导致增加搜索和索引使用的文件句柄的数量。
2.5 使用单例的IndexWriter
多线程创建索引使用唯一的IndexWriter,而不是每次都创建一个IndexWriter。
2.6 使用更快的分词器
事实上建索引的时间大部分都花在了分词的时间上,一个好的分词器,将大大减少索引的时间。而关于分词器,我会再写一篇博文去研究,下面给出一个不通分词器的性能测试demo:
https://github.com/ysc/cws_evaluation
2.7 加快获取文档的时间
很多建索引速度慢的原因不是出在Lucene上,而是获取文档的速度太慢,所以一个很好的快速获取文档的机制很重要。
2.8 分布建索引
如果索引文件非常大,那么可以考虑分布建索引,再把这些分段索引合并起来。IndexWriter.AddIndexes()用来把不同文件夹中的索引合并到一个文件夹中,且合并之后的索引是最优的,也就是Optimize(1)之后的索引。当然分布索引放在不同的服务器上,效率才是翻倍的。
二,优化建索引速度的思考
1.分布建索引(伪)
我在做搜索的时候,42个G的索引文件,需要7个小时从头到尾重建完,这里包括了我获取文档的时间,以及接口通信的时间。然后优化Optimize(1),这也需要1~2个小时的时间。于是我想将重建索引的速度继续降低。通过上面的设置IndexWriter的参数的方法,时间虽然有减少,但是效果不明显。这也表示着,如果你建索引的时间已经大大的无法让你承受,那么修改IndexWriter的RAMBufferSizeMB,MergeFactor等等参数,也是无济于事的。Lucene的索引性能不会因为改了几个参数而得到显著的提升。所以这个时候我们就需要从分词器,分布建索引,以及整个重建索引的机制下手。
由于公司只给我了一台服务器,所以我选择在这台服务器上跑了两个相同的应用在不同的文件夹分布建索引,再调用IndexWriter.Addindexes合并索引,虽然是在同一台服务器上,分两个应用确实可以最大的发挥cpu的效率,最终6个小时后,两段索引都建完了。而合并需要半个小时,让我惊喜的是合并之后的索引已经是十分完美的。原本9个小时的索引重建工作也缩短到了6个半小时。这里要提一下IndexWriter.AddIndexes(),有两个函数.
//只是把一些列文件夹中的索引,复制到同一个文件夹中,并不会合并他们,
IndexWriter.AddIndexes(Directory[] d)
//把一系列文件中的索引,合并到同一个文件中,在合并时,子文件夹中不能有IndexWriter在操作
IndexWriter.AddIndexes(IndexReader[] i)
显然选择第二个是比较好的。
如果再有一台服务器,那么效率则是会翻倍的。
2. 选择新的分词器
我使用的是PanGu分词器,根据官网上的指标:
Core Duo 1.8 GHz 下单线程 分词速度为 390K 字符每秒,2线程分词速度为 690K 字符每秒。
在上面的链接中,我发现了很多分词速度更快的分词器,比如JIEba分词器,Word分词器。但是并不适合选择那些快速分词模式的分词器,因为搜索引擎最重要的是搜索效果,而不是你后台建索引的速度。一般的搜索引擎在建索引的时候会选择细粒度分词,也就是将词分的越细越好,分的词越多越好,这样可以提高召回率。当然带来的负面作用是分词的速度下降。所以建索引的时候还是选择那些细粒度的分词模式是最好的,而搜索的时候可以用粗粒度的分词模式,索引速度已经是次要的。
另外,推荐使用JIEba分词,JIEba分词的分词效果确实比PanGu分词要好。在PanGu分词打开多元分词开关之后二者的分词效果对比:
测试样例:小明硕士毕业于中国科学院计算所,后在日本京都大学深造 结巴分词(搜索引擎模式):小明/ 硕士/ 毕业/ 于/ 中国/ 科学/ 学院/ 科学院/ 中国科学院/ 计算/ 计算所/ ,/ 后/ 在/ 日本/ 京都/ 大学/ 日本京都大学/ 深造 盘古分词(开启多元分词开关): 小 明 硕士 毕业 于 中国科学院 计算所 后 在 日本 京都 大学 深造
3.更改重建索引机制
我的建索引机制是,每次向提供数据的接口请求200个文档,然后把200个文档调用写索引接口,返回正确写入后,再去请求下一个200个文档。我修改了这样的机制,使用一个文档队列,长度为10000.请求文档不需要等写索引返回成功直到队列满,写索引直接出队列知道队列为空。并且写在一个应用中。速度如何还没有测试。
4.根本错误
现在搜索引擎的机制是每天晚上重建索引,因为这个机制,给我带来了很多麻烦,所以才有优化建索引的需求。很显然一个好的搜索引擎肯定不是每晚重建索引,应该是实时的维护索引,但是由于应用比较多,实现起来开发成本很高,所以暂时只能这样先凑合。将在不久的将来,使用事件总线,彻底解决维护索引的机制。
三,结语
随着用户的增多,索引量的不断变大,分布式的搜索引擎,也必不可少,这篇博文值得推荐看看
http://blog.csdn.net/a276202460/article/details/62426189
Lucene.net(4.8.0) 学习问题记录四: IndexWriter 索引的优化以及思考的更多相关文章
- Lucene.net(4.8.0) 学习问题记录五: JIEba分词和Lucene的结合,以及对分词器的思考
前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...
- Lucene.net(4.8.0) 学习问题记录六:Lucene 的索引系统和搜索过程分析
前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...
- Lucene.net(4.8.0) 学习问题记录三: 索引的创建 IndexWriter 和索引速度的优化
前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...
- Lucene.net(4.8.0) 学习问题记录二: 分词器Analyzer中的TokenStream和AttributeSource
前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...
- Lucene.net(4.8.0) 学习问题记录一:分词器Analyzer的构造和内部成员ReuseStategy
前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...
- MongoDB学习笔记(四)--索引 && 性能优化
索引 基础索引 ...
- Vue.js 2.0 学习重点记录
Vue.js兼容性 Vue.js.js 不支持 IE8 及其以下版本,因为 Vue.js.js 使用了 IE8 不能模拟的 ECMAScript 5 特性. Vue.js.js 支持所有兼容 EC ...
- bootstrap3.0学习笔记记录1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- thinkphp5.0学习笔记(四)数据库的操作
ThinkPHP内置了抽象数据库访问层,把不同的数据库操作封装起来,我们只需要使用公共的Db类进行操作,而无需针对不同的数据库写不同的代码和底层实现,Db类会自动调用相应的数据库驱动来处理.采用PDO ...
随机推荐
- Head First设计模式之解释器模式
一.定义 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子. 主要解决:对于一些固定文法构建一个解释句子的解释器. 何时使用:如果一种特定类型的问题发生的频率足 ...
- JavaScript、ES5和ES6的介绍和区别
JavaScript由三部分组成: ECMAScript(核心) DOM(文档对象模型) BOM (浏览器对象模型) ES5(ECMAScript第五个版本) strict模式 严格模式,限制一些用法 ...
- css实现平行四边形、菱形图片效果
一.平行四边形 1. 使用两个元素实现 html <a class="button"> <div>click me</div> </a&g ...
- 轻量级弹出框 lightbox
1. 引入 lightbox.css 和 lightbox.js 2.检查 CSS 并确定调用的 prev.gif 和 next.gif 文件在正确的位置. 同样要确定调用的 loading.gif ...
- ORM框架 EF - code first 的封装 优化一
上一节我们讲到对EF(EntityFramework)的初步封装,任何事情都不可能一蹴而就,通过大量的实际项目的实战,也发现了其中的各种问题.在这一章中,我们对上一章的EF_Helper_DG进行优化 ...
- Java学习笔记19---内部类之简介成员内部类、局部内部类及匿名内部类
内部类,顾名思义,即定义在某个类内部的类,称包含该内部类的类为外部类. 从定义的位置来说,分为成员内部类和局部内部类:从类的特征来说,分为匿名内部类和静态内部类. 今天先简要介绍一下前三种内部类的定义 ...
- 模拟uClinux系统调用
这篇文章原来放在CU上的,现在挪过来了.CU上设置不可见了. 1. 目标 这里主要是实验一下uclinux的系统调用. 2. 环境 OS :vmware + red ...
- IIS发布 用户 \'IIS APPPOOL\\X\' 登录失败
曾多次遇到这个问题,我的解决方案就是修改数据库连接字符串 网上给的解决方案就是更换应用程序池的"进程模型":参考:http://jingyan.baidu.com/album/20 ...
- 使用Three.js 基本组件以及流程
1. 创建场景 var scene = new THREE.Scene(); 2. 创建相机,设置可视范围 var camera = new THREE.PerspectiveCamera(45, ...
- windows第四层负载均衡--基于NLB负载均衡
上面有一篇文章说windows第七层负载均衡,这次讲讲第四层负载均衡 TCP/IP协议族,第七层是应用层,第四层是传输层.第四层负载均衡主要通过IP进行转化. 一些优秀的第四层负载均衡软件,速度可以接 ...