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 ...
随机推荐
- 非常好用的弹出层 layer,常用功能demo,快速上手!
功能强大,实用,操作方便,文档齐全. 参数灵活,丰富.可以作为开发项目的公共模块,多处使用.老文档地址:http://layer.layui.com/api.html 已经停止维护 新文档地址:htt ...
- 利用lsof恢复进程占用的文件
说明:经常会遇到这种情况,没有使用正确的方式清理进程占用的文件,比如日志.导致空间并没有释放.也有的时候需要恢复进程占用的文件. 解决方式 lsof |grep del # 找出自己要恢复的文件名称. ...
- 2018年手机应用UI设计趋势预测
用户需求瞬息万变,而手机软件UI设计为适应变化的用户需求,也相应的发生着变化.但是,这并不意味着用户需求和UI设计趋势就是无迹可寻的.事实上,根据前几年的手机app界面设计变化的特点,尤其是2017年 ...
- Windows程序设计学习笔记(四)自绘控件与贴图的实现
Windows系统提供大量的控件供我们使用,但是系统提供的控件样式都是统一的,不管什么东西看久了自然会厌烦,为了使界面更加美观,添加一些新的东西我们需要自己绘制控件. 控件在默认情况下并不进行自绘,如 ...
- Python 浅析线程(threading模块)和进程(process)
线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 进程与线程 什么 ...
- Go使用flag包开发命令行工具
flag包是Go语言标准库提供用来解析命令行参数的包,使得开发命令行工具更为简单 常用方法 1.flag.Usage 输出使用方法,如linux下ls -h的帮助输出 2.flag.Type(参数名, ...
- ConstraintLayout知识记录
一.准备工作 1. 确保SDK Tools已经下载了ContraintLayout的支持库. 2. gradle中增加对ConstraintLayout的依赖. compile 'com.andr ...
- jq手风琴效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- InnoDB一棵B+树可以存放多少行数据?
一个问题? InnoDB一棵B+树可以存放多少行数据?这个问题的简单回答是:约2千万.为什么是这么多呢?因为这是可以算出来的,要搞清楚这个问题,我们先从InnoDB索引数据结构.数据组织方式说起. 我 ...
- zookeeper之分布式锁以及分布式计数器(通过curator框架实现)
有人可能会问zookeeper我知道,但是curator是什么呢? 其实curator是apachede针对zookeeper开发的一个api框架是apache的顶级项目 他与zookeeper原生a ...