这篇博客并不是证明Lucene.net的性能有多强悍,实际上Lucene.net的并发能力并不让人很满意,这得看你怎么用它。

因为Lucene 本身就是一个搜索引擎的基础框架,相当于一辆车子的发动机,而你做的是怎么造出一辆车速度快的车子来。很显然你要有一个好的轮胎,和空气阻力很小的车身造型。如果你的轮子是正方形的,那么马力再强劲的发动起都带不起来,对吧。

作为一名研发工程师,我相信大多工程师都不会造出一个正方形的轮子来跑车。每个人都有使用Lucene的方式,你可以使用elasticsearch 或者solr这些基于Lucene已经二次开发好的搜索引擎框架,你也可以自己基于Lucene进行二次开发,打造属于你自己的搜索引擎。

我属于后者。这里说的Lucene性能包括两种:

1. 建索引的速度

2.搜索的速度

对于搜索引擎来说这两个性能很关键。对于用户来说搜索的速度才是他们最关心的,当然速度也只是搜索效果的一方面,因为还有排序的问题。

接下来先讨论下Lucene.net 的搜索速度:

在讨论搜索速度之前,我们可以简单了解一下Lucene是怎么搜索的,涉及到Lucene的search最重要的几个类:

表面上:

1. 你先得创建一个IndexReader  IndexReader类是提供操作索引的权限(search,write,delete,update...)所以无论是在搜索还是建索引的时候,都需要创建一个IndexReader。  IndexReader 是一个虚类,它的子类有两种:AtomicReader 和 CompositeReader  AtomicReader故名思议是原子型的IndexReader... 这后面的内容还是有点多的,足以再写一篇文章做总结了。由于不是文章的核心内容,所以放到文章的结尾里补充,如果充分利用好Lucene的IndexReader,你也可以做自己想做的事情,因为Lucene给了你自定义的权限和众多功能的api接口。

2. 创建一个IndexReader ,你需要Directory类,因为Directory是管理索引文件的类。这又是一个十分重要的类,它在Lucene.Store包中。

Directory类是Lucene操作索引目录的类,负责管理目录里的索引文件。我们知道Lucene同一时刻只允许同一个线程进行创建索引操作,经常看到索引文件里有write.lock文件,就是Directory实例创建的。I

我们常用Directory的这几个子类创建IndexReader 实例:FSDirectory,RAMDriectory 。前者表示在文件目录里也就是硬盘中操作索引,后者是加载到内存中操作索引。

而FSDirectory 的子类又有三个:MMapDirectory, NIOFSDirectory, SimpleFSDirectory。这里有必要介绍一下MMapDirectory , 它是利用虚拟内存技术实现的操作文件目录,这里暂且提一下。

于是我们通常可以这样创建一个IndexReader

FSDriectory dir = FSDirectory.Open(storage.IndexDir);
IndexReader indexReader = DirectoryReader.Open(dir);

通过FSDirectory 打开一个索引目录,再通过FSDirectory 创建一个indexReader。

3. 创建IndexSearcher  IndexSearcher 的构造函数传入一个IndexReader .IndexSearch提供了Search方法供检索索引。

IndexSearcher 有个重要的性质:线程安全。也就是多线程可以同时使用一个IndexSearch实例。

IndexSearcher luceneSearcher = new Lucene.Net.Search.IndexSearcher(IndexReader);

4. 构造Query

Lucene 的提供了很多Query方式,比如TermQuery 查询文档中某个term是否存在,PhraseQuery 查询文档中两个或多个词是否存在和设定他们之间的距离,

FuzzyQuery 模糊查询,BooleanQuery 集合子查询的查询,等等。。。

TermQuery termQuery = new TermQuery(new Term(filedName,value));
PhraseQuery phraseQuery = new PhraseQuyer();
phraseQuery.Add(new Term(filedName,value));
phraseQuery.Add(new Term(filedName,value));
phraseQuery.Slop=;
BooleanQuery booleanQuery = new BooleanQuery();
booleanQuery.Add(termQuery, Occur.Must);
booleanQuery.Add(phraseQuery,Occur.Must); luceneSearcher.search(booleanQuery,topn);

上面的只是举例,当然在实际开发中是不会一路写下来的。

代码上就完成了一个检索索引的大致过程,占的篇幅有点多而且内容简单,这肯定不是为了撑篇幅的,因为这些类的使用是比较影响搜索速度的。比如FSDirectory,RAMDirectory..的选用,IndexSearcher的使用和查询方式Query的搭配。

上面的是表面的代码,我觉得有必要对Lucene检索时候,内部的机制进行了解,这样可以解释为什么Lucene不仅是I/O操作密集型的应用,它的CPU消耗也不是开玩笑的。

现在的这个搜索流程就像一个轮子,我们改怎么去用最好的搭配,来达到最快的搜索速度呢?如果你的搜索单条记录更快,那么并发性能就越高。

不同的方法造的轮子的摩擦力是不一样的,所以我们要尽可能的减少的摩擦力。

Lucene.net 的性能探究--Lucene.net 的并发处理能力到底有多强?的更多相关文章

  1. Lucene学习总结之七:Lucene搜索过程解析

    一.Lucene搜索过程总论 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 其可用如下图示: 总共包括以下几个过程: ...

  2. Lucene学习总结之三:Lucene的索引文件格式(1)

    Lucene的索引里面存了些什么,如何存放的,也即Lucene的索引文件格式,是读懂Lucene源代码的一把钥匙. 当我们真正进入到Lucene源代码之中的时候,我们会发现: Lucene的索引过程, ...

  3. Lucene系列六:Lucene搜索详解(Lucene搜索流程详解、搜索核心API详解、基本查询详解、QueryParser详解)

    一.搜索流程详解 1. 先看一下Lucene的架构图 由图可知搜索的过程如下: 用户输入搜索的关键字.对关键字进行分词.根据分词结果去索引库里面找到对应的文章id.根据文章id找到对应的文章 2. L ...

  4. Lucene学习总结之七:Lucene搜索过程解析 2014-06-25 14:23 863人阅读 评论(1) 收藏

    一.Lucene搜索过程总论 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户输入的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 其可用如下图示: 总共包括以下几个过程: ...

  5. Lucene学习总结之三:Lucene的索引文件格式(1) 2014-06-25 14:15 1124人阅读 评论(0) 收藏

    Lucene的索引里面存了些什么,如何存放的,也即Lucene的索引文件格式,是读懂Lucene源代码的一把钥匙. 当我们真正进入到Lucene源代码之中的时候,我们会发现: Lucene的索引过程, ...

  6. Lucene学习之一:使用lucene为数据库表创建索引,并按关键字查询

    最近项目中要用到模糊查询,开始研究lucene,期间走了好多弯路,总算实现了一个简单的demo. 使用的lucene jar包是3.6版本. 一:建立数据库表,并加上测试数据.数据库表:UserInf ...

  7. Lucene学习总结之六:Lucene打分公式的数学推导

    在进行Lucene的搜索过程解析之前,有必要单独的一张把Lucene score公式的推导,各部分的意义阐述一下.因为Lucene的搜索过程,很重要的一个步骤就是逐步的计算各部分的分数. Lucene ...

  8. Lucene学习之二:Lucene的总体架构

    本文转载自:http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623596.html Lucene总的来说是: 一个高效的,可扩展的,全 ...

  9. Lucene学习总结之六:Lucene打分公式的数学推导 2014-06-25 14:20 384人阅读 评论(0) 收藏

    在进行Lucene的搜索过程解析之前,有必要单独的一张把Lucene score公式的推导,各部分的意义阐述一下.因为Lucene的搜索过程,很重要的一个步骤就是逐步的计算各部分的分数. Lucene ...

随机推荐

  1. centos7 下 nfs 搭建总结

    nfs一般用于生产环境磁盘空间不足导致数据无法写入,从而通过异机远程挂载磁盘方式解决问题. 一. rpm -qa | grep nfs-utils rpm -qa | grep rpcbind 二. ...

  2. 牛牛与数组 (简单dp)

    题目链接 这种题一看就是dp啊,dp[i][j]表示第i位放j的方案数,转移方程为dp[i][j]=dp[i-1][k]{k<=i||k%i!=0},当然我们可以三层循环来找,但数据显然会超时, ...

  3. Djangol里面MVT的原理

    MVT Django是一款python的web开发框架与MVC有所不同,属于MVT框架m表示model,负责与数据库交互v 表示view,是核心,负责接收请求.获取数据.返回结果t 表示templat ...

  4. C# - 代码重构

    隐藏更多 只暴露集合中供人使用的单一功能,将关于集合的更多功能隐藏掉. 旧版本 public class Animal{    private List<string> LanguageL ...

  5. Ansible之Playbook详解、案例

    什么是playbook playbooks是一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活.简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的 ...

  6. CDQ分治求不知道多少维偏序 (持续更新 ]

    求三维偏序的模板 : //Author : 15owzLy1 //luogu3810.cpp //2018 12 25 16:31:58 #include <cstdio> #includ ...

  7. 【easy】88. Merge Sorted Array 合并两个有序数组

    合并两个有序的list 把排序好的nums2插入nums1中,假设nums1这个vector的空间永远是够的 思路:倒序!! class Solution { public: void merge(v ...

  8. 【转载】Vue自定义指令实现pc端加载更多

    转载来源:https://www.86886.wang/detail/5a6f19e644f9da55274c3bbd,谢谢作者分享! 原理 document.documentElement.scro ...

  9. 【linux】awk相关

    按字段相加文本内容 a 3 b 4 c 5 a 8 d 2 c 6 将上面内容中字段相同的数据相加 awk -F ' ' '{sum[$1]+=$2}END{for(i in sum){print i ...

  10. linux环境部署python3+django

    1. 确定Linux安装C/C++编译器,在线安装: yum install gcc gcc-c++ autoconf automake 2. 安装依赖环境: yum -y install zlib- ...