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 ...
随机推荐
- Swift语言中与C/C++和Java不同的语法(四)
这一节,我们将会讨论一下Swift中的函数相关的基本内容 首先是函数的创建: func sayHello (name:String) -> String { return "Hello ...
- DBA 优化法则
硬件资源是根本,DBA是为了充分利用硬件资源:(更新中--) 统一SQL语句: 减少SQL嵌套: 执行计划返回结果集(决定计划走向): 合理使用临时表: tempdb分多文件: OLTP 条件使用变量 ...
- mac 安装mysql特种报错的对应解决方式
参考 :http://www.jianshu.com/p/776e72742c6e 原文废话太多了, 还是看我的好了. 配置环境变量 echo "export PATH=$PATH:/usr ...
- Netty对Protocol Buffer的支持(七)
Netty对Protocol Buffer的支持(七) 一.简介 在上一篇博文中笔者已经介绍了google的Protocol Buffer的使用,那么本文笔者就开始介绍netty对Protocol B ...
- 自动刷新 CSS文件
自动刷新 CSS文件 使用任何代码工具码 CSS,都是需要保存后再切换到浏览器按 F5 刷新查看效果,一次又一次,不管这个改动仅是一个小小的颜色.使用 CSSrefresh 后,改动 CSS 文件保存 ...
- Python模块学习------ 多线程threading(2)
一.避免使用thread模块,使用threading模块的原因: 1. 更高级别的threading模块更为先进,对线程的支持更加完善.而且使用thread模块的属性有可能会与threading 出现 ...
- 【有上下界的网络流】ZOJ2341 Reactor Cooling(有上下界可行流)
Description The terrorist group leaded by a well known international terrorist Ben Bladen is bulidi ...
- 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖
1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1945 Solve ...
- PE文件解析器的编写(二)——PE文件头的解析
之前在学习PE文件格式的时候,是通过自己查看各个结构,自己一步步计算各个成员在结构中的偏移,然后在计算出其在文件中的偏移,从而找到各个结构的值,但是在使用C语言编写这个工具的时候,就比这个方便的多,只 ...
- 微信小程序之两个页面传值
需求:发送页面点击某一个元素之后,获取该元素的属性值,然后把这些属性值传到接收页面中. 思路:获取当前点击元素的索引,就能获取当前元素的值,然后通过跳转的 url 地址传递值 还是整个完整的例子吧: ...