zoukankan
html css js c++ java
Lucene.net 系列四 index 下
本文将介绍有关索引并发控制的问题,以结束对Lucene.net建立索引问题的讨论.
1
. 允许任意多的读操作并发.即可以有任意多的用户在同一时间对同一份索引做查询工作.
2
. 允许任意多的读操作在索引被正在被修改的时候进行.即哪怕索引正在被优化,添加删除文档,这时也是允许用户对索引进行查询工作. (it’s so cool.)
3
. 同一时间只允许一个对索引修改的操作.即同一时间只允许IndexWriter或IndexReader打开同一份索引.不能允许两个同时打开一份索引.
Lucene提供了几种对索引进行读写的操作.添加文档到索引,从索引中删除文档,优化索引,合并Segments.这些都是对索引进行写操作的方法. 查询的时候就会读取索引的内容.
有关索引并发的问题是一个比较重要的问题,而且是Lucene的初学者容易忽略的问题,当索引被破坏,或者程序突然出现异常的时候初学者往往不知道是自己的误操作造成的.
下面让我们看看Lucene是如何处理索引文件的并发控制的.
首先记住一下三点准则:
1
. 允许任意多的读操作并发.即可以有任意多的用户在同一时间对同一份索引做查询工作.
2
. 允许任意多的读操作在索引被正在被修改的时候进行.即哪怕索引正在被优化,添加删除文档,这时也是允许用户对索引进行查询工作. (it’s so cool.)
3
. 同一时间只允许一个对索引修改的操作.即同一时间只允许IndexWriter或IndexReader打开同一份索引.不能允许两个同时打开一份索引.
第一个准则很容易理解,第二个准则说明Lucene对并发的操作支持还是不错的.第三个准则也很正常,不过需要注意的是第三个准则只是表明IndexWriter和IndexReader不能并存,而没有反对在多线程中利用同一个IndexWriter对索引进行修改.这个功能可是经常用到的,所以不要以为它是不允许的.不过这个时候的并发就需要你自己加以控制,以免出现冲突.
(注: 在前面的系列中已说过IndexReader不是对Index进行读操作,而是从索引中删除docuemnt时使用的对象)
有关这三个原则在实际使用Lucene API时候的体现,让我们先看看下面这张表:
表中列出了有关索引的主要读写操作.其中空白处表示X轴的操作和Y轴的操作允许并发.
而X处表明X轴的操作和Y轴的操作不允许同时进行.
比如Add document到索引的时候不允许同时从索引中删除document.
其实以上这张表就是前面三个准则的体现.Add Optimize Merge操作都是由IndexWriter来做的.而Delete则是通过IndexReader完成.所以表中空白处正是第一条和第二条准则的体现,而X(冲突)处正是第三个原则的具体表现.
为了在不了解并发控制的情况下对Lucene API的乱用. Lucene提供了基于文件的锁机制以确保索引文件不会被破坏.
当你对index 进行修改的时候, 比如添加删除文档的时候就会产生
***
write.lock文件,而当你从segment进行读取信息或者合并segments的时候就会产生
***
commit.lock文件.在默认情况下,这些文件是放在系统临时文件夹下的. 简而言之, write.lock文件存在的时间比较长,也就是对index进行修改的锁时间比较长,而commit.lock存在的时间往往很短.具体情况见下表.
如果索引存在于server, 很多clients想访问的时候,自然希望能看到其他用户的锁文件,这时把锁文件放到系统临时文件夹就不好了.此时可以通过配置文件来改变锁文件存放的位置.
比如在一个asp.net的应用下,你就可以象下面这样利用web.config文件来实现你的目的.
<
configuration
>
<
appSettings
>
<
add key
=
"
Lucene.Net.lockdir
"
value
=
"
c:yourdir
"
/>
</
appSettings
>
</
configuration
>
不仅如此,在某些情况下比如你的索引文件存放在一个CD
-
ROM中,这时根本就无法对索引进行修改,也就不存在所谓的并发冲突,这种情况下你甚至可以讲锁文件的机制取消掉.同样通过配置文件.
<
configuration
>
<
appSettings
>
<
add key
=
"
disableLuceneLocks
"
value
=
"
true
"
/>
</
appSettings
>
</
configuration
>
不过请注意不要乱用此功能,不然你的索引文件将不再受到安全的保护.
下面用一个例子说明锁机制的体现.
using
System;
using
System.IO;
using
Lucene.Net.Analysis;
using
Lucene.Net.Index;
using
Lucene.Net.Store;
using
NUnit.Framework;
using
Directory
=
Lucene.Net.Store.Directory;
[TestFixture]
public
class
LockTest
{
private
Directory dir;
[SetUp]
public
void
Init()
{
String indexDir
=
"
index
"
;
dir
=
FSDirectory.GetDirectory(indexDir,
true
);
}
[Test]
[ExpectedException(
typeof
(IOException))]
public
void
WriteLock()
{
IndexWriter writer1
=
null
;
IndexWriter writer2
=
null
;
try
{
writer1
=
new
IndexWriter(dir,
new
SimpleAnalyzer(),
true
);
writer2
=
new
IndexWriter(dir,
new
SimpleAnalyzer(),
true
);
}
catch
(IOException e)
{
Console.Out.WriteLine(e.StackTrace);
}
finally
{
writer1.Close();
Assert.IsNull(writer2);
}
}
[Test]
public
void
CommitLock()
{
IndexReader reader1
=
null
;
IndexReader reader2
=
null
;
try
{
IndexWriter writer
=
new
IndexWriter(dir,
new
SimpleAnalyzer(),
true
);
writer.Close();
reader1
=
IndexReader.Open(dir);
reader2
=
IndexReader.Open(dir);
}
finally
{
reader1.Close();
reader2.Close();
}
}
}
不过很令人失望的是在Lucene(Java)中应该收到的异常在dotLucene(
1.4
.
3
)我却没有捕获到.随后我在dotLucene的论坛上问了一下,至今尚未有解答.这也是开源项目的无奈了吧.
查看全文
相关阅读:
Ubuntu 系统中设置环境变量 PATH 的方法
JSP页面EL表达式无效的问题
用超链接提交表单并传递一个参数
sql触发器应用SQL中DateTime转换成Varchar样式
算法导论第二章 习题作业记录
【欧拉题四】三位数乘积所得的最大回文数
Linux64下mysql安装和开发
算法导论第三章 学习笔记
【欧拉3】最大质因数
常用linux命令/工具
原文地址:https://www.cnblogs.com/kokoliu/p/615341.html
最新文章
Inverse.Cascade.All.Table
Intelligencia.UrlRewriter失效的问题
圆角边框CSS
NPOI Excel解决方案
IIS上部署WCF服务
NUnit
SQLite简介及SQLite在.NET中的应用
.NET 微信开放平台接口
快速理解socket
难以描述的bug.关于fluent.NHibernate和Serializable
热门文章
mock
用户 'NT AUTHORITY\NETWORK SERVICE' 登录失败
js:confirm
建站需求分析
ssh设置
如何选取table中几行 Mysql
JavaScript判断浏览器类型及版本
Ubuntu下的管理员权限
在ubuntu下如何搜索文件?
查看具体端口
Copyright © 2011-2022 走看看