前言:目前自己在做使用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 索引的优化以及思考的更多相关文章

  1. Lucene.net(4.8.0) 学习问题记录五: JIEba分词和Lucene的结合,以及对分词器的思考

    前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...

  2. Lucene.net(4.8.0) 学习问题记录六:Lucene 的索引系统和搜索过程分析

    前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...

  3. Lucene.net(4.8.0) 学习问题记录三: 索引的创建 IndexWriter 和索引速度的优化

    前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...

  4. Lucene.net(4.8.0) 学习问题记录二: 分词器Analyzer中的TokenStream和AttributeSource

    前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...

  5. Lucene.net(4.8.0) 学习问题记录一:分词器Analyzer的构造和内部成员ReuseStategy

    前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...

  6. MongoDB学习笔记(四)--索引 && 性能优化

    索引                                                                                             基础索引 ...

  7. Vue.js 2.0 学习重点记录

      Vue.js兼容性 Vue.js.js 不支持 IE8 及其以下版本,因为 Vue.js.js 使用了 IE8 不能模拟的 ECMAScript 5 特性. Vue.js.js 支持所有兼容 EC ...

  8. bootstrap3.0学习笔记记录1

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. thinkphp5.0学习笔记(四)数据库的操作

    ThinkPHP内置了抽象数据库访问层,把不同的数据库操作封装起来,我们只需要使用公共的Db类进行操作,而无需针对不同的数据库写不同的代码和底层实现,Db类会自动调用相应的数据库驱动来处理.采用PDO ...

随机推荐

  1. golang 栈操作

    Monk's Love for Food   Our monk loves food. Hence,he took up position of a manager at Sagar,a restau ...

  2. 腾讯WeTest发布《2017中国移动游戏质量白皮书》,专注手游品质提升

    1月8日,腾讯质量开放平台WeTest正式发布<2017中国移动游戏质量白皮书>. 刚刚过去的这一年,市场逐渐成熟,中国移动互联网由增量市场转向存量市场.中国移动游戏市场急剧变化,真正的精 ...

  3. Tsung:开源多协议分布式负载&压力测试工具

    Main features High Performance: the load can be distributed on a cluster of client machines Multi-pr ...

  4. 2017春 前端自动化(二) 页面自动刷新、sass与css转换的使用、pxToRem直观转换

    2017春 前端自动化(二)   页面自动刷新.sass与css转换的使用.pxToRem直观转换 引言:   此文要演示:浏览器页面自动刷新:移动端px与rem的转换,简单直观化:使用sass自动生 ...

  5. hadoop+hive+spark搭建(一)

    1.准备三台虚拟机 2.hadoop+hive+spark+java软件包 传送门:Hadoop官网 Hive官网 Spark官网      一.修改主机名,hosts文件 主机名修改 hostnam ...

  6. promise 和 async 的用法

    promise // 先构造一个 promise 函数 // resolve 和 reject 都是一个函数 // resolve 在成功时调用 // reject 在失败时调用 function p ...

  7. 那些年原生js实现的楼层跳转

    最近做一个需求~~楼层跳转(京东.淘宝侧边导航),由于现在项目都用框架,所以 jquery是不能再用了,只好自己原生写一个,其实实现起来很简单,无非就是获取到每个楼层距离文档顶部的距离,然后通过控制滚 ...

  8. 关于对JavaScript待于完善的一些知识点

    学习JavaScript也存在一段时间,以下是个人对JavaScript中抽象的知识点记录备案,将有待于后面逐个完善...... 1.JavaScript在内存中的体现(内存中栈堆与基本类型及引用类型 ...

  9. 利用java的反射,实现工厂创建对象

    public static Object getInstance(Class c){ Object obj = null; try { obj = c.newInstance(); } catch ( ...

  10. Mac搭建cocos2dx+Android studio开发环境以及AnySDK的集成

    配置环境: mac osx 10.12.6 cocos2dx 3.14 Android studio 2.3 目标: 在mac上配置cocos Android开发环境,接入AnySDK 配置: 1.安 ...