`
stta04
  • 浏览: 114839 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

Lucene多线程操作实现

阅读更多

Lucene多线程操作实现<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

对于并发,Lucene 遵循以下规则:

1.
允许任意多的读操作并发,即任意数量用户可同时对同一索引做检索操作。
2.
即便正在进行索引修改操作(索引优化、添加文档、删除文档),依然允许任意多的检索操作并发执行。
3.
不允许并发修改操作,也就是说同一时间只允许一个索引修改操作。

Lucene
内部已经对多线程安全进行了处理,很多操作都使用了 lock 进行多线程同步锁定。只要遵循一定的规则,就可以在多线程环境下安全运行 Lucene
方案一:
建议:

1. Directotry
Analyzer 都是多线程安全类型,只需建立一个 Singleton 对象即可。
2.
所有线程使用同一个 IndexModifier 对象进行索引修改操作。
3. IndexWriter/IndexReader/IndexModifier/IndexSearcher
最好使用同一个 Directory 对象,否则多线程并发读写时可能引发 FileNotFoundException

IndexModifier
对象封装了 IndexWriter IndexReader 的常用操作,其内部实现了多线程同步锁定。使用 IndexModifier 可避免同时使用 IndexWriter IndexReader 时需要在多个对象之间进行同步的麻烦。等所有修改操作完成后,记住调用 Close() 方法关闭相关资源。并不是每次操作都需要调用 Optimize(),可以依据特定情况,定期执行优化操作。

--------

以下演示代码简单封装了一个 IndexModifier Signleton 类型,确保多线程使用同一个对象,且只能由最后一个多线程调用 Close 方法关闭。
代码不完善,仅供参考!需要做些修改才能应用于实际项目。

//索引修改器的获取和关闭

import java.io.File;

import java.io.IOException;

import java.io.StringReader;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Map;

import org.apache.lucene.analysis.Analyzer;

import org.apache.lucene.analysis.standard.StandardAnalyzer;

import org.apache.lucene.index.CorruptIndexException;

import org.apache.lucene.index.IndexModifier;

import org.apache.lucene.store.Directory;

import org.apache.lucene.store.LockObtainFailedException;

import org.apache.lucene.store.RAMDirectory;

public class MyIndexModifier {

private static Analyzer analyzer = new StandardAnalyzer();

private static IndexModifier modifier;

private static ArrayList<Thread> threadList = new ArrayList<Thread>();

private MyIndexModifier() { }

static final File INDEX_DIR = new File("D:/docindex");

public static IndexModifier GetInstance()

{

synchronized (threadList)

{

if (modifier == null)

{

try {

modifier = new IndexModifier(INDEX_DIR, analyzer, false);

//索引性能测试参数配置

modifier.setMergeFactor(1000);

System.out.println("MergeFactor: " + modifier.getMergeFactor());

System.out.println("MaxBufferedDocs: " + modifier.getMaxBufferedDocs());

} catch (CorruptIndexException e) {

e.printStackTrace();

} catch (LockObtainFailedException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

if (!threadList.contains(Thread.currentThread()))

threadList.add(Thread.currentThread());

return modifier;

}

}

public static void Close()

{

synchronized (threadList)

{

if (threadList.contains(Thread.currentThread()))

threadList.remove(Thread.currentThread());

if (threadList.size() == 0)

{

try {

if (modifier != null)

{

modifier.close();

modifier = null;

}

} catch (CorruptIndexException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

//线程处理类

import java.io.IOException;

import java.util.Date;

import org.apache.log4j.LogManager;

import org.apache.log4j.Logger;

import org.apache.lucene.document.Document;

import org.apache.lucene.document.Field;

import org.apache.lucene.index.CorruptIndexException;

import org.apache.lucene.index.IndexModifier;

import org.apache.lucene.index.StaleReaderException;

import org.apache.lucene.store.LockObtainFailedException;

import com.miracle.dm.framework.common.TimestampConverter;

public class TestModifer extends Thread{

private static Logger logger = LogManager.getLogger(TestModifer.class);

@Override

public void run() {

IndexModifier writer = MyIndexModifier.GetInstance();

try {

writer.deleteDocument(0);

} catch (StaleReaderException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

} catch (CorruptIndexException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

} catch (LockObtainFailedException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

} catch (IOException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

for (int x = 0; x < 10; x++)

{

Document doc = new Document();

TimestampConverter converter = new TimestampConverter();

Date date = new Date();

String docDate = converter.timestampToShortStr(date);

doc.add(new Field("docDate", docDate , Field.Store.YES, Field.Index.TOKENIZED));

try {

writer.addDocument(doc);

} catch (CorruptIndexException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (LockObtainFailedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

logger.debug(""+ Thread.currentThread()+","+ writer.docCount());

MyIndexModifier.Close(); // 注意不是调用 IndexModifier.Close()

}

}
多线程测试代码

import java.io.Console;

import java.io.IOException;

import java.util.Date;

import org.apache.log4j.LogManager;

import org.apache.log4j.Logger;

import org.apache.lucene.document.Document;

import org.apache.lucene.document.Field;

import org.apache.lucene.index.CorruptIndexException;

import org.apache.lucene.index.IndexModifier;

import org.apache.lucene.store.LockObtainFailedException;

import com.miracle.dm.framework.common.TimestampConverter;

public class test {

private static Logger logger = LogManager.getLogger(test.class);

public test(){

}

/**

* @param args

*/

public static void main(String[] args) {

for (int i = 0; i < 100; i++)

{

new TestModifer().start();

}

}

}

注意:使用lucene现在的新版本的朋友一定会发现,现在并不推荐使用。而查看API发现IndexModifier已经被IndexWriter代替。再查看IndexWriter,其中提供了新增,删除,更新索引文档的方法。

这里是自己编码来实现,但是我不知道当几千或更多用户在对索引进行操作,那会不会导致close长时间没有运行,而无法检索到最新的更新索引。希望大家帮我考虑一下是否会存在这方面的问题,如果存在该如何解决?

方案二:利用已有的lucene框架,例如compass

它对lucene实现了实时索引。可基于hibernate,当更新数据库时,系统会自动更新索引。

· CompassluceneSpringHibernate三者结合
转自:http://wemyss.blogbus.com/logs/8014799.html

1.概述

CompassluceneSpringHibernate三者的起来,以很低很低的成本快速实现企业应用中的搜索功能。

HomePage: http://www.opensymphony.com/compass/

springside里用了compass来做图书搜索,快速建立的流程如下:

1.用简单的compass annotationBook对象映射到Lucene

2.配置compass默认提供的基于Spring MVCIndex Controller Search Controller

3.编写查询结果的显示页面,将controller返回的变量显示出来。

2.Object/Search Engine Mapping Annotations配置

使用JDK5 annotation 来进行OSEM(Object/Search Engine Mapping)比用xml文件按简单许多,下面就是简单的搜索类,可见@SearchableID, @SearchableProperty@SearchableComponent三个标记,分别代表主键、可搜索的属性与关联的,另一个可搜索的对象,另外Compass要求POJO要有默认构造函数,要实现equals()hashcode():

详细请点击查看springside中的Product.java , Book.java, Category.java

publicclassProduct{

@SearchableId

privateIntegerid;

privateCategorycategory;

privateStringname;

privateDoubleunitprice;

@SearchableProperty(name="name")

publicStringgetName(){

returnthis.name;

}

@SearchableComponent(refAlias="category")

publicCategorygetCategory(){

returnthis.category;

}

publicDoublegetUnitprice(){

returnthis.unitprice;

}

3. spring,hibernate集成配置

3.1 spring配置文件

hiberante中的sessionFactory,transactionManager相比大家也是轻车熟路了.这里还是带过(因为不牵扯稿费的问题吗^_^ ).compass已经对对spring集成做了很好的封装,让我们的使用更加简单,我们可以不为compass编写一行代码,就可以做完搜索引擎的检索.下面是compassspring中的简明配置. 详情点击查看springside中的applicationContext-lucene.xml

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 8.25pt; HEIGHT: 12pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CUSER%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:href="mhtml:file://C:\Documents%20and%20Settings\USER\桌面\本周\Compass将lucene、Spring、Hibernate三者结合%20-%20Wemyss's%20Space%20-%20博客大巴.mht!http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif"></imagedata></shape><beans>
<shape id="_x0000_i1026" style="WIDTH: 8.25pt; HEIGHT: 12pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CUSER%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:href="mhtml:file://C:\Documents%20and%20Settings\USER\桌面\本周\Compass将lucene、Spring、Hibernate三者结合%20-%20Wemyss's%20Space%20-%20博客大巴.mht!http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif"></imagedata></shape>
<beanid="annotationConfiguration"class="org.compass.annotations.config.CompassAnnotationsConfiguration"></bean>
<shape id="_x0000_i1027" style="WIDTH: 8.25pt; HEIGHT: 12pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CUSER%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:href="mhtml:file://C:\Documents%20and%20Settings\USER\桌面\本周\Compass将lucene、Spring、Hibernate三者结合%20-%20Wemyss's%20Space%20-%20博客大巴.mht!http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif"></imagedata></shape>
<shape id="_x0000_i1028" style="WIDTH: 8.25pt; HEIGHT: 12pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CUSER%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:href="mhtml:file://C:\Documents%20and%20Settings\USER\桌面\本周\Compass将lucene、Spring、Hibernate三者结合%20-%20Wemyss's%20Space%20-%20博客大巴.mht!http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif"></imagedata></shape>
<beanid="compass"class="org.compass.spring.LocalCompassBean">
<shape id="_x0000_i1029" style="WIDTH: 8.25pt; HEIGHT: 12pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CUSER%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:href="mhtml:file://C:\Documents%20and%20Settings\USER\桌面\本周\Compass将lucene、Spring、Hibernate三者结合%20-%20Wemyss's%20Space%20-%20博客大巴.mht!http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif"></imagedata></shape>
<!--anontaition式设置-->
<shape id="_x0000_i1030" style="WIDTH: 8.25pt; HEIGHT: 12pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CUSER%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:href="mhtml:file://C:\Documents%20and%20Settings\USER\桌面\本周\Compass将lucene、Spring、Hibernate三者结合%20-%20Wemyss's%20Space%20-%20博客大巴.mht!http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif"></imagedata></shape>
<propertyname="classMappings">
<shape id="_x0000_i1031" style="WIDTH: 8.25pt; HEIGHT: 12pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CUSER%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:href="mhtml:file://C:\Documents%20and%20Settings\USER\桌面\本周\Compass将lucene、Spring、Hibernate三者结合%20-%20Wemyss's%20Space%20-%20博客大巴.mht!http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif"></imagedata></shape>
<list>
<shape id="_x0000_i1032" style="WIDTH: 8.25pt; HEIGHT: 12pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CUSER%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:href="mhtml:file://C:\Documents%20and%20Settings\USER\桌面\本周\Compass将lucene、Spring、Hibernate三者结合%20-%20Wemyss's%20Space%20-%20博客大巴.mht!http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif"></imagedata></shape>
<value>org.springside.bookstore.domain.Book</value>
<shape id="_x0000_i1033" style="WIDTH: 8.25pt; HEIGHT: 12pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CUSER%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:href="mhtml:file://C:\Documents%20and%20Settings\USER\桌面\本周\Compass将lucene、Spring、Hibernate三者结合%20-%20Wemyss's%20Space%20-%20博客大巴.mht!http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif"></imagedata></shape>
</list>
<shape id="_x0000_i1034" style="WIDTH: 8.25pt; HEIGHT: 12pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CUSER%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.gif" o:href="mhtml:file://C:\Documents%20and%20Settings\USER\桌面\本周\Compass将lucene、Spring、Hibernate三者结合%20-%20Wemyss's%20Space%20-%20博客大巴.mht!http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif"></imagedata></shape>
</property><br

分享到:
评论

相关推荐

    重要Lucene多线程操作实现.pdf

    重要Lucene多线程操作实现.pdf

    【重要】Lucene多线程操作实现[定义].pdf

    Lucene 是一个高性能、全文本搜索库,它提供了强大的搜索功能并支持多线程操作。在处理并发问题时,理解Lucene的多线程规则至关重要。 在Lucene中,多线程操作遵循以下关键原则: 1. **并发读取**:允许任意数量的...

    【重要】Lucene多线程操作实现.pdf

    ### Lucene与多线程操作 Lucene作为一个高性能的全文检索工具包,提供了强大的搜索能力,但它本身并不直接支持多线程操作。若要在使用Lucene的应用程序中实现多线程,开发者需要谨慎处理线程安全问题和资源共享。...

    lucene索引优化多线程多目录创建索引

    通过对“lucene_multiThreadIndex”压缩包的学习,你将掌握如何在Lucene中实现多线程索引,从而提高大型数据集的索引构建速度。通过实践,你可以更好地理解和应用这些技术,优化你的信息检索系统。

    Lucene5学习之多线程创建索引

    为了实现多线程并行处理,我们可以使用`IndexWriterConfig`的`setMergedSegmentWarmer`方法来设置一个合并监听器,这样在合并段时,我们可以执行自定义的任务,比如启动新的`IndexWriter`实例进行更多的索引操作。...

    Lucene索引的基本操作

    **Lucene索引的基本操作** Lucene是一款由Apache软件基金会开发的全文检索库,它提供了高效、可扩展的全文检索功能。...在实际应用中,还需要考虑更多的因素,如性能优化、多线程支持、错误处理等。

    基于lucene技术的增量索引

    - **并发控制**:在多线程环境下,需要确保对索引的操作是安全的,防止数据冲突和丢失。 - **优化索引**:定期执行索引优化(`IndexWriter.optimize()`)可以合并较小的段,提高搜索效率,但需要注意这是一项耗时...

    Lucene 实现控制台操作 C/R/U/D

    在实际应用中,还需要考虑如何优化性能,如使用多线程索引、设置缓存策略、选择合适的存储方式等。同时,为了提高用户体验,可以结合其他技术如 Solr 或 Elasticsearch 构建更复杂的搜索解决方案。 总结来说,...

    lucene 实现类似百度搜索

    4. **并发控制**:多线程环境下,合理使用 Locks 或 LockFree 机制保证数据一致性。 通过以上步骤和技巧,我们可以使用 Lucene 实现一个强大的搜索引擎,提供类似百度的搜索体验。无论是在网站、应用还是大数据环境...

    lucene实现索引查询

    Lucene 是一个高性能、全文本搜索库,被广泛用于构建...实际应用中,可能还需要考虑错误处理、性能优化、多线程支持、查询结果的排序和过滤等功能。理解并熟练运用这些知识,能帮助你构建高效、灵活的全文搜索系统。

    Lucene索引和查询

    - 多线程支持:在大型应用中,可能需要并发创建和查询索引,Lucene支持多线程操作。 - 性能优化:如使用内存映射文件(MMapDirectory)、优化写入策略等。 - 分布式搜索:通过Solr或Elasticsearch,可以实现分布式...

    Lucene.Net 实现全文检索

    - **性能优化**:考虑到效率,可以采用多线程创建索引,或者利用缓存技术提高查询速度。同时,定期进行索引合并可以减少磁盘碎片,提高查询效率。 - **错误处理和日志**:为了确保系统的健壮性,需要处理可能出现的...

    多线程搜索引擎java实现源代码

    本项目以"多线程搜索引擎java实现源代码"为标题,旨在介绍如何使用Java编程语言构建一个具备多线程特性的搜索引擎。这个搜索引擎可以抓取网络上的信息,存储网页快照,并建立索引,以便用户快速查询所需内容。下面...

    基于LUCENE的搜索引擎的设计与实现源代码

    此外,对于初学者,理解Java的IO流和多线程编程也是必要的,因为索引构建和搜索过程可能涉及大量的文件读写和并发操作。同时,掌握XML或者JSON等数据格式的处理也有助于处理数据源和结果输出。 总的来说,"基于...

    Lucene资料大全(包括Lucene_in_Action书等)

    - 多线程与分布式搜索 - 实战示例和最佳实践 **尚学堂科技_张志宇_lucene.ppt** 这份PPT可能包含对Lucene基础知识的快速概览,如Lucene的主要特点、基本用法,以及适合初学者的示例代码。它可能以简洁易懂的方式...

    lucene 华电项目 源码

    例如,多线程环境下,IndexWriter的并发控制是如何实现的,以及如何通过缓存策略来平衡性能和内存消耗。 总结来说,通过对“lucene 华电项目 源码”的深入研究,我们可以全面了解Lucene在电力行业信息检索中的实际...

    lucene基本包

    Lucene支持多线程操作,可以在高并发环境下高效地处理索引和查询任务,确保系统的稳定性。 7. **内存管理和性能优化** Lucene采用了高效的内存管理策略,如使用RAMDirectory和MMapDirectory进行索引存储,以及...

    lucene与sqlserver数据库实现索引的简单实例

    在实际应用中,可能还需要考虑如错误处理、性能优化、多线程索引、分布式搜索等高级话题。同时,为了简化开发流程,有一些第三方库如Solr和Elasticsearch提供了更高级的管理和部署功能,它们基于Lucene,提供了更...

Global site tag (gtag.js) - Google Analytics