`
dingjob
  • 浏览: 183264 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

基于Lucene的商业搜索应用架构研究(下)——遇到的问题

阅读更多
     由于也是初次开发基于Lucene的商业应用,经验比较缺乏,在开发过程中遇到了不少问题,有些比较大众化的问题,这里不细讲,对于稍微复杂的问题展开来写下,也希望得到博友的一些分享。

  

     1.单分词的研究

      对于 “上海apen 公司”进行搜索,要能够搜索出  上海a的模糊查询。首先这个需求有一定弊端,索引会因此变大,搜索效率会变低,目前的解决方案有:



1.类似系统A的like搜索 ,用wizardFiter对query进行通配符的过滤,这种过滤会增加上去这些词条。

2. 使用庖丁解牛,辅助生成分词方法

3. javaCC,根据自定义的规则生成查询方法。

4. 已经有网上比较成熟的分词。



对于chineseAnalyzer进行研究



bufferIndex  读进缓冲区的数据集长度,

dataLen  本次term值的长度。





 if (bufferIndex >= dataLen) {
    dataLen = input.read(ioBuffer);
    bufferIndex = 0;
   }

 

读取一个字符

 

c = ioBuffer[bufferIndex++]; 

 // 本段拆分的词

 private final Token flush() {

 

  if (length > 0) {
   // System.out.println(new String(buffer, 0, length));
   return new Token(new String(buffer, 0, length), start, start
     + length);
  } else
   return null;
}




  其中对于英文的分词逻辑是:如果下一个不是英文字符(_是英文字符),则会继续走,直到出现空格,中文等,就调用flush 函数,建立新的token.

 if (charType != -1 && charType != 1 && length > 0) {}


  项目中改造了chinese分词,目前命名为sigleLetterAnyaler,分词要实现analyer的接口,主要工作包括切分,然后计算其起至位置,这里修改了它对于英文的分词逻辑.

  

    2. Digester读取嵌套的文件

采用模板加载一些控制参数,如,有哪些字段,如何分词,索引路径等。(需要进一步看下这个包的应用)





    3.多线程和线程池

设计中,建立索引时,在提取数据时采用多个线程,线程采集好数据放在线程池内,线程池内线程会被放入等待队列,但是执行顺序是随机的。(线程池的应用还需进一步深化)。





    4. Cache

     应该说,开发搜索引擎不用cache是不行的,系统A非常巧妙的应用了缓存,而且写了比较强大的三级缓存,在读数据的时候,如果创建indexReader对象,则效率非常低,需要把所有索引的数据取到内存。所以要用cache。indexWriter使用了线程池,线程池的执行原理是放进去就开始执行,多个线程可以共用一个indexWriter对象。效率非常高,他重写了indexWriter.close 方法,当调用时,数量减一,并不销毁对象,这样以后再从cache取就直接取到了这个对象indexWriter close时是不是销毁对象

@Override
 public IndexReader getIndexReader(String directory) throws IOException {
  Lock lock = this.getLock(directory);
  lock.lock();
  try {
   CachedIndexWriter indexWriter = cache.get(directory);
   if (indexWriter != null) {
    //从cache里得到的indexWriter都要调用close方法
    indexWriter.close();
    if (log.isDebugEnabled()) {
     log.debug("the index writer exist in cache.remove it now.");
    }
    if (!cache.remove(directory)) {
     throw new IOException("the directory '" + directory
       + "' may be in use. cann't create IndexReader.");
    }
   }
   return super.getIndexReader(directory);
  } finally {
   lock.unlock();
  }



indexReader 的cache 比较简单,可以采用map将其缓存起来,每个indexType一个即可。



     5.  Lucene新的方法使用



      Lucene 2.4 对于搜索废弃了原来的search尽量使用新的方法。也即将废弃了indexModifer,它的效率也是非常低的,不建议使用。



     6.  jboss 直接关闭会有 write.lock,导致每次取索引都会报错的问题。

   正常的使用linux 命令是不会有的,只有强杀进程和直接关闭的方式是会有的,程序是无法控制被强杀进程时再做相应操作的,jboss 怎么回收这个的jboss正常关闭会调用程序的实现了DisposableBean的destory方法的,所以一定要维护好一个对象的生命周期

     7.  发布hessian原理

    ASF 中使用内置的jetty 发布hessian,hessian要求的不仅仅是参数实体要序列化,内部所有对象都要序列化,lucene内部query等对象都是没有序列化的,不能传输.这里采用了java内建对象,采用map和set 等进行传输,实现客户端和服务端的完全独立,服务端用java反射机制进行解析,解析为相应的conditon方法,然后对改conditon进行query条件构造.

    8.  Too many Files的解决方案


  搜索过程中发现经常会报这个错误,出现这个问题的原因分析下有两个方面,

(1)indexReader对象没有关闭导致的,cache种维护的indexReader会认为一直在打开这个文件。

(2)当前打开的文档数确实超过linux文档数限制,这个可以系统配置。


   开始直接在新的indexReader产生时,调用indexReader的close方法,close旧的对象实验证明这样是不行的,可能会关掉正在调用中的对象(其实这个是lucene的机制不够合理,正在使用中的对象都可以关闭) 会爆出 indexReader is closed的错误,最终还是放到线程池来关闭,这样我们以为解决了,看打出来的日志,有新建的有close的,我们认为这个线程池已经起到了作用,能够维护好线程了,第二天一看,还是不行,我统计了一下开启了 150个reader对象,只有40几个关闭掉了,看来还有没有关闭的对象,最终发现原来是new CachedindexReader后没有及时更新缓存的对象,导致关闭的是旧的引用对象,这也导致了另外诸如查询结果不匹配的情况。

     9. 内存溢出的解决方案

    这个问题和上面的问题有一定联系,这里放在一起总结,刚开始的内存溢出是indexReader对象没有全部关闭导致的,发现关闭后还是内存占用超大,Jprofile跟踪内存后发现,每次大数据量查询消耗200M左右内存,主要从如下几个方面作了优化
(1)排序方面,lucene的sort排序如果不使用类型来指定它,采用auto类型,会导致数据排序时占用很大内存,这里采用了指定其类型为Sting类型
(2) 主动的垃圾回收机制,当数据量超大时,查询结果返回超过10000条,使用gc回收 (3)页面级别控制,不能只输入公司来查询
(4)并发机制,如果出现同时访问量达到40个,返回系统正忙,不允许查询。
(5)健全的邮件通知机制,发生内存溢出时有通知邮件,但是系统继续执行,不能崩溃,因为在内存溢出时,垃圾回收器会回收部分内存,可能不影响接下来的访问。

      10. 并发时,JBOSS无响应的解决方案

     在线上环境,建索引时进行查询,或者大量用户并发查询时,会导致线程一致等待,直到JBOSS没有响应
     经确认,我们在同步时,锁了log4j 日志这个常量,结果造成死锁,写日志的方法在等
我们的同步方法,我们的同步方法在等写日志的方法释放出来。锁log这个常量是大家经常做的,但是这里最好定义一个没有用的常量来同步代码块,否则容易造成死锁。
1
0
分享到:
评论

相关推荐

    基于Lucene的搜索引擎的研究与应用

    文章主要研究和应用了基于Lucene的搜索引擎,其特点是利用开源网络爬虫工具抓取互联网信息,并通过Lucene的API对特定信息进行索引和搜索。下面详细介绍相关知识点。 1. Lucene基础 Lucene是由Apache软件基金会提供...

    基于Lucene的全文检索引擎研究与应用

    ### 基于Lucene的全文检索引擎研究与应用 #### 一、Lucene概述 Lucene是一款由Java编写的全文检索引擎工具包,具备快速的索引访问速度,支持多用户访问,并且可以在多种平台上运行。随着数字信息量的爆炸性增长,...

    基于Lucene的全文检索引擎研究与应用.pdf

    ### 基于Lucene的全文检索引擎研究与应用 #### 概述 随着信息技术的飞速发展,尤其是互联网的普及,企业和个人积累了大量的电子文档。如何高效地管理和检索这些文档成为了亟待解决的问题。全文检索技术作为一种...

    基于Lucene的全文检索系统研究与开发

    ### 基于Lucene的全文检索系统研究与开发 #### 摘要与背景介绍 本文探讨了一种基于Jakarta Lucene构建的全文检索系统模型。相较于Google的站内检索及传统数据库检索方法,该模型展现出显著的优势,特别是在关键字...

    基于Lucene的搜索策略研究

    ### 基于Lucene的搜索策略研究 随着信息技术的发展和社会信息化程度的加深,人们面临着海量数据的管理和检索挑战。如何高效地从大量的文档中找到所需的信息成为了亟待解决的问题。在这种背景下,Lucene作为一种开源...

    基于Lucene的搜索引擎

    **基于Lucene的搜索引擎** Lucene是一个开源的全文检索库,由Apache软件基金会开发并维护。它是Java编写的一个高性能、可扩展的信息检索库,为开发者提供了构建搜索功能的基础框架。这个课程设计创建了一个简单的...

    基于Lucene的小型搜索引擎

    《基于Lucene的小型搜索引擎构建详解》 在信息爆炸的时代,如何快速、准确地找到所需信息成为了一项挑战。搜索引擎作为解决这一问题的关键工具,其技术实现也引起了广泛关注。本篇将详细介绍一个基于Apache Lucene...

    基于Lucene的WEB站内搜索引擎的研究与实现

    ### 基于Lucene的WEB站内搜索引擎研究与实现 #### 一、搜索引擎基本原理与Lucene概述 搜索引擎的基本原理涉及对大量文档或网页进行分析、索引和检索的过程。这一过程通常包括数据采集(爬虫)、预处理(如分词、...

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

    基于LUCENE的搜索引擎可应用于各种场景,如企业内部知识库的检索、网站内容搜索、邮件搜索等。通过学习和掌握LUCENE,开发者能够快速构建出满足特定需求的高效搜索引擎。 总结,LUCENE作为一个强大的全文搜索库,为...

    基于Lucene的信息检索的研究与应用.PDF

    基于Lucene的信息检索的研究与应用.PDF 基于Lucene的信息检索的研究与应用.PDF

    一种基于Lucene检索引擎的全文数据库的研究与实现

    ### 一种基于Lucene检索引擎的全文数据库的研究与实现 #### 1. 引言 随着信息技术的飞速发展和互联网的普及,大量的文本信息被数字化存储,这为信息检索带来了前所未有的挑战和机遇。传统的数据库管理系统(DBMS)...

    基于Lucene的搜索引擎在Struts中的应用.pdf

    ### 基于Lucene的搜索引擎在Struts中的应用 #### 概述 在现代企业级应用中,信息检索已成为不可或缺的功能,特别是全文检索技术,它以计算机数据(如文字、图像)为处理对象,实现了按照数据内容进行信息检索的...

Global site tag (gtag.js) - Google Analytics