lucene 索引合并问题

lucene 索引合并 关键步骤如下:
            IndexWriter fswriter = null ;                //FS
            IndexWriter ramwriter = null ;                //RAM
            Directory fsDir;
            Directory ramDir;
            ramDir = new RAMDirectory();
           
            //  判断原索引文件是否存在
           
            //打开已经存在的索引文件  最后一项必须为false 若为true则会删除已经存在的索引 这一步很重要
            System.out.println("*********now open exist index :" + indexPath + "**********");
            fswriter = new IndexWriter(indexPath, new StandardAnalyzer(),false);
            //fswriter.setUseCompoundFile(false);        //设置复合索引false
           
            ramwriter = new IndexWriter(ramDir, new StandardAnalyzer(),true);        //构建给予RAM的索引
            System.out.println("CompoundFile()= " + fswriter.getUseCompoundFile());
           
            //对dataDir目录下的所有文件建立RAM索引
            BuildRamIndexDirectory(dataDir);
            ramwriter.optimize();                                //内存索引优化          
           
            System.out.println("...begin combin index.....");
            fswriter.addIndexes(new Directory[]{ramDir});       //索引合并
            ramwriter.close();                        //关闭内存索引       
            fswriter.close();                        //关闭文件索引

上述方法是通过RAM 和FS 合并  也可以合并 FS 和FS.
合并RAM索引的时候 可以根据内存大小 通过控制 RAM 索引的大小来分批量多次进行合并。
while(){
    if (condition for flushing memory to disk has been met){
           fswriter.addIndexes(new Directory[]{ramDir});       //索引合并
           ramwriter.close();                        //关闭内存索引  
           ramwriter = new IndexWriter(ramDir, new StandardAnalyzer(),true);        //构建给予RAM的索引
        }
}

关于建立索引多线程的一些资料,转载如下:
背景:单线程为30万条数据建索引花了10分钟,为了提高效率采用多线程
 
 起初我采用多个线程共享一个indexwriter实例(也意味着往同一个目录写索引),这是
 lucene in action 和lucene wiki的推荐做法,不知道到为什么总是报FileNotFoundException,
 很让人困惑。偶尔会成功一次。这个错误让我想起另外一个问题,就是在建索引的时候搜索也会报这个
 错误,lucene in action 明明也说了建索引读的时候没问题。
 
 言归正传,我第二次尝试使用每个线程单独拥有自己的indexwriter实例,但往同一个目录写索引,果然报了
 写锁的错, 这和书上说的很一致。
 
 最后没办法了,我使用每个线程单独使用自己的实例,往自己的目录写索引,最后一个干完的线程将所有的索引合并
 比如我开了4个线程,那么就有5个目录build_index,build_index1,build_index2,build_index3,build_index4
 线程1往build_index1中写,线程2往build_index2,。。。依次类推,最后一个干完的将build_index1-4目录的索引合并到
 build_index.
 
 
 我开了4个线程尝试发现也要花大概7-8分钟,合并索引的过程非常快20秒左右。
 开了10个线程,整个过程需要6分多钟,合并索引也只花了21秒。

似乎效果并不明显,这因该是因为数据量还不够大引起的,数据量越大,并行的优势会越明显
 
  可见合并索引的过程非常快,这又提供了另外的好处,我们通常将build_index作为搜索目录,就像上面说的那样,建索引的过程 会影响搜索(虽然按 照书上说是不影响的),如果我们采用这种方案,建索引的绝大部分过程其实与build_index目录无关,只有最后 合并的时候需要用到 build_index,但那个过程又非常的快速,所以可以极大的缓解建索引给搜索带来的问题。
 

顺便说:当然你也可以再开一个通知线程专门等待索引线程,当索引线程完毕之后加入通知线程的队列,通知线程发现自己的队列有通知记录就开始合并索引,这样就不用所有的线程完毕之后才开始合并索引。(这种方案待尝试)


 如果条件允许,你可以扩展一下这个方案,将多线程索引升级为多台机器同时建。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值