此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
楼主【wind_324】截止到2008-07-16 17:31:52的历史汇总数据(不包括此帖):
发帖的总数量:19                       发帖的总分数:1258                     每贴平均分数:66                       
回帖的总数量:385                      得分贴总数量:185                      回帖的得分率:48%                      
结贴的总数量:18                       结贴的总分数:1158                     
无满意结贴数:0                        无满意结贴分:0                        
未结的帖子数:1                        未结的总分数:100                      
结贴的百分比:94.74 %               结分的百分比:92.05 %                  
无满意结贴率:0.00  %               无满意结分率:0.00  %                  
值得尊敬

解决方案 »

  1.   

    我也在学Lucene,400W条数据记录做索引,没有遇到楼主的情况啊?!
    内存也没有溢出。楼主的内存溢出会不会是楼主一次把所有记录读进内存引起的?
    楼主的增量索引一次1000条。第一次是指头1000条,还是头一次做19W索引?楼主能否把情况说得更详细一点?
      

  2.   

    我的代码。但是没有什么特殊的地方啊!package com.baizeju.indexgenerator;import java.sql.ResultSet;
    import java.sql.SQLException;import java.io.IOException;
    import java.util.Date;
    import java.text.SimpleDateFormat;import net.paoding.analysis.analyzer.PaodingAnalyzer;import org.apache.lucene.analysis.Analyzer;
    import org.apache.lucene.document.Document;
    import org.apache.lucene.document.Field;
    import org.apache.lucene.index.IndexWriter;import com.baizeju.Logger.Logger;import com.baizeju.DB;/**
     *
     * @author xiaoyuma
     */
    public class IndexGenerator {
        
        private static String INDEX_STORE_PATH = "E:\\Baizeju\\Index";
    private static String QUERY = "12345";
        
        protected static  Logger m_Logger = new Logger();
        
        protected void message( String szMsg ) {
            SimpleDateFormat bartDateFormat = new SimpleDateFormat("yyyyMMdd HH:mm:ss.SSS ");
    String szDatetime = bartDateFormat.format(new Date(  ));
            
            System.out.println( szDatetime+"-->>"+szMsg );
        }
        
        public IndexGenerator() {
            Logger.initialLogger();
            DB.setConnectionPara( "jdbc:mysql://localhost:3306/BZJ1", "root", "");
            DB.connectDB();
        }
        
        public void createIndex() {
            // 庖丁Analyzer
    Analyzer analyzer = new PaodingAnalyzer();
            
            //接下来是标准的Lucene建立索引和检索的代码
    IndexWriter writer = null;
            
            try {
                writer = new IndexWriter(INDEX_STORE_PATH, analyzer);
            }
            catch( Exception e ) {
                m_Logger.fatal( "不能创建索引:"+e);
                return;
            }
            
            try{
    // 从数据库取得网站列表
    ResultSet resultSet = DB.query( "Select SiteID From BZJ_Website");

    while( resultSet.next() ) {

                    message( "Total Memory: "+Runtime.getRuntime().totalMemory() + "  Free Memory: "+Runtime.getRuntime().freeMemory() + "  Maximum Memory: "+Runtime.getRuntime().maxMemory());
                    
                    // 从数据库取得职位列表
    ResultSet resultSetJob = DB.query( "Select JobID, IdentifyString, JobTitle, Description From BZJ_JobList Where SiteID="+resultSet.getString(1));
    message( "Total Memory: "+Runtime.getRuntime().totalMemory() + "  Free Memory: "+Runtime.getRuntime().freeMemory() + "  Maximum Memory: "+Runtime.getRuntime().maxMemory());
                    
                    int nIndex=0;
                    long nTotalTitleLength=0;
                    long nTotalDescLength=0;
                    boolean bGet;
            
                    for( int nIndex2=0; nIndex2<50; nIndex2++ ) {
                        message( "Index = "+nIndex2);
                        
                        if( resultSetJob!=null ) {
                            if( nIndex2!=0 ) {
                                resultSetJob.first();
                            }
                    
                            while( resultSetJob.next() ) {
                                Document jobItem = new Document();                            String szJobID = resultSetJob.getString(1);
                                String szJobTitle = resultSetJob.getString(3);
                                String szJobDesc = resultSetJob.getString(4);                            Field jobID             = new Field("JobID",szJobID,Field.Store.YES, Field.Index.UN_TOKENIZED );
                                Field jobTitle          = new Field("JobTitle",szJobTitle,Field.Store.YES, Field.Index.TOKENIZED );
                                Field jobDesc           = new Field("Description",szJobDesc,Field.Store.YES, Field.Index.TOKENIZED );                            nTotalTitleLength+=szJobTitle.length();
                                nTotalDescLength+=szJobDesc.length();                            jobItem.add(jobID);
                                jobItem.add(jobTitle);
                                jobItem.add(jobDesc);                            try{
                                    writer.addDocument(jobItem);
                                }
                                catch( IOException e ) {
                                    m_Logger.warning( "创建索引项目失败!");
                                }
                                nIndex++;
                            }
                            message( "Done!!!! "+nIndex+" records have been added.");
                            message( "Total Memory: "+Runtime.getRuntime().totalMemory() + "  Free Memory: "+Runtime.getRuntime().freeMemory() + "  Maximum Memory: "+Runtime.getRuntime().maxMemory());
                                
                        }
                    }
    }
    }
    catch( SQLException e ) {
    m_Logger.fatal( "数据库操作失败,不能取得站点列表");
    }
            try {
                if( writer!=null ) {
                    writer.close();
                }
            }
            catch( Exception e ) {
                
            }
        }
        
        public static void main( String[] args ) {
           IndexGenerator generator = new IndexGenerator();
           
           generator.createIndex();
    }
    }
      

  3.   

    nKannan 请问你是怎么把数据一点点写进lucene的?是做的增量索引吧?怎么分批的呢?你真的没有碰到过内存溢出么?我第一次是把所有的都加载了,后来一次1W也不行。还是溢出啊?你怎么弄的呢?
      

  4.   


    不还意思 是1W条,就是头一次1W,然后在写进去1W,因为总溢出,没办法了,就打算分19次给这些数据做索引。
      

  5.   

    上面就是我的程序啊,我就是用标准的例子改的。(我也是才学Lucene)我的数据在数据库中,我把ID,Title和Description三个域用Lucene做索引。ID长度在8-10,Title平均有8-10个汉字,Description有80-120汉字。我的记录大约有23W,我在程序中重复索引了50遍,最后总的有1000W条记录了。
      

  6.   

    我第一次 select ...from tb order by id limit 1,10000;
    第二次select ...from tb order by id limit 10000,10000;
    第三次select ...from tb order by id limit 20000,10000;
    ...没做什么回收,没弄过!
      

  7.   

    我第一次 select ...from tb order by id limit 1,10000;
    第二次select ...from tb order by id limit 10000,10000;
    第三次select ...from tb order by id limit 20000,10000;
    ...没做什么回收,没弄过!
      

  8.   

    我第一次 select ...from tb order by id limit 1,10000;
    第二次select ...from tb order by id limit 10000,10000;
    第三次select ...from tb order by id limit 20000,10000;
    ...没做什么回收,没弄过!
      

  9.   

    现在重新做了测试 我第一次写了10W数据 用了1小时37分钟。第二次写5K 用了近20分钟。如果一次加载19W到内存的话,机器吃不消了,机器老了点,大家见谅,有什么方法可以快点将后面的数据增量进去呢,现在5K的时候,机器卡的要死,cpu经常出现满贯的情况。高手指点!!!谢谢
      

  10.   


    呵呵 koko 真好 谢谢
      

  11.   

    我在想baidu、google每天何止数以万计的索引,不可能每次都做重建吧。肯定类似于增量的方式(lz个人猜测)。
    如果每次做增量都要好久好久,那么baidu,google早qq了。所以应该还是有解决方式的。如何优化创建增量索引的速度。
    再加50分!新手求知!高手指点!谢谢
      

  12.   

    你说的百度那些是索引的追加的lucene里面好像有这方面的功能,给19W数据做索引,我也没有弄过,我做得是txt文本的索引,没有出现死机的问题和内存溢出的问题,看不懂3楼的汗!
      

  13.   

    给你个建议,启动jconsole 仔细看看你的进程的内存使用情况再说吧!1G内存溢出?难道没有垃圾回收?
      

  14.   


    老大 内存溢出已经解决,是因为我数据量太大,一次加载到内存造成的。现在的问题是怎样提高创建增量索引的速度,5K条,鼠标就不能动了。如果首次创建的话,5k也就1秒多就OK了。还有 - - !老大,jconsole是啥?咋玩啊,没玩过。
      

  15.   

    public IndexWriter(Directory d,Analyzer a,boolean create,IndexWriter.MaxFieldLength mfl)
                throws CorruptIndexException, LockObtainFailedException,IOException
     这个IndexWriter的构造函数 构造的Indexwriter是增量的
      

  16.   


    老大 不是这个意思,一个ture一个flase嘛,这个我知道,关键是我的数据content字段是文章,超大,所以一次将19W数据加载到内存中,也就是一次建立所有的索引是不可能的,所有我就想分开来,也就是增量索引的方式,创建索引,我试着做了第一次做了10W数据的索引,后面还有10W ,要以增量索引的方式添加进去,现在就是现在是10W索引怎样增量添加可以快些?是不是增量的时候,每次要遍历一次已有的索引呢,不然为什么会这么慢?
      

  17.   

    writer.addDocument(doc);
    writer.flush(); // 加上这一句,把索引从内存写到磁盘
      

  18.   

    10w就卡了?我这都建过70w的数据都没卡啊!就是那样的呀!每两千条写到内存的索引中去,然后在磁盘上建个索引,writer.addindex方法之类的,将索引增加进去啊!
      

  19.   

    我重新测试了一下我的数据:
    共有数据项499945个,数据结构
    class JobRecord {
        public String szJobID;
        public String szJobTitle;
        public String szJobDesc;
    }
    统计数据长度(多数为中文,GBK编码):
    JobID是纯数字,长度在8-11位之间。
    JobTitle是GBK编码,多数为中文,也有纯英文的。平均长度在7.8(汉字算一个)。
    JobDesc是GBK编码,多数为中文,也有纯英文的。平均长度在179.1(汉字算一个)。一次性先从数据库查出全部记录到ResultSet,
    读入前时间和内存使用:20080721 10:57:24.968 -->>Total Memory: 532742144  Free Memory: 500238488  Maximum Memory: 1456734208
    读入后时间和内存使用:20080721 10:57:38.765 -->>Total Memory: 532742144  Free Memory: 284768328  Maximum Memory: 1456734208将ResultSet中的数据全部读入到ArrayList中:
    生成ArrayList后时间和内存使用:20080721 10:57:43.109 -->>Total Memory: 909459456  Free Memory: 383773336  Maximum Memory: 1456734208建立Lucene索引:
    20080721 11:01:00.765 -->>Total Memory: 909459456  Free Memory: 328840680  Maximum Memory: 1456734208建立的索引文件大小:
    Directory of E:\Baizeju\Index07/21/2008  11:05 AM    <DIR>          .
    07/21/2008  11:05 AM    <DIR>          ..
    07/21/2008  11:05 AM                 0 result.txt
    07/21/2008  11:01 AM                20 segments.gen
    07/21/2008  11:01 AM                95 segments_r
    07/21/2008  11:00 AM       270,839,025 _a.cfs
    07/21/2008  11:00 AM        29,821,400 _b.cfs
    07/21/2008  11:01 AM        24,783,663 _c.cfs
                   6 File(s)    325,444,203 bytes
                   2 Dir(s)   8,344,842,240 bytes free从此可见,读DB数据(DB的ResultSet对象)和保存数据在内存是消耗内存最多的操作,Lucene做索引耗时大(不过49W数据用了3分钟不到,比我预想得快多了),但是耗内存不是很大。