繁体   English   中英

使用2000万条记录进行Lucene索引需要花费更多时间

[英]Lucene Indexing with 20 M Records taking more time

当我运行具有100万条记录的代码时,我具有以下用于索引的Lucene代码-它运行速度快(在15秒内索引(本地和具有高配置的服务器))。

当我尝试索引2000万条记录时,大约需要10分钟才能完成索引。

我正在具有超过100 GB RAM的Linux Server中运行这2000万条记录。 在这种情况下,设置更多的RAM缓冲区大小会有所帮助吗? 如果是,我可以设置多少RAM大小(我需要超过100 GB RAM)

我在本地计算机上尝试了相同的2000万条记录(8 GB RAM),花了同样的十分钟,我尝试在本地设置了10分钟相同的1 GB RAM缓冲区大小,而没有为2000万条设置任何RAM缓冲区也相同了10分钟记录在我的本地计算机上。

我尝试在Linux中不设置RAM缓冲区大小,但花了大约8分钟时间才获得2000万条记录。

final File docDir = new File(docsPath.getFile().getAbsolutePath());
LOG.info("Indexing to directory '" + indexPath + "'...");
Directory dir = FSDirectory.open(new File(indexPath.getFile().getAbsolutePath()));
Analyzer analyzer = null;
IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_47, analyzer);
iwc.setOpenMode(OpenMode.CREATE_OR_APPEND);
iwc.setRAMBufferSizeMB(512.0);
IndexWriter indexWriter = new IndexWriter(dir, iwc);

if (docDir.canRead()) {
    if (docDir.isDirectory()) {
        String[] files = docDir.list();
        if (files != null) {

            for (int i = 0; i < files.length; i++) {
                File file = new File(docDir, files[i]);
                String filePath = file.getPath();
                String delimiter = BatchUtil.getProperty("file.delimiter");
                if (filePath.indexOf("ecid") != -1) {
                    indexEcidFile(indexWriter, file, delimiter);
                } else if (filePath.indexOf("entity") != -1) {
                    indexEntityFile(indexWriter, file, delimiter);
                }
            }
        }
    }
}
indexWriter.forceMerge(2);
indexWriter.close();

以及用于索引的一种方法:

private void indexEntityFile(IndexWriter writer, File file, String delimiter) {

    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
        BufferedReader br = new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8")));

        Document doc = new Document();
        Field four_pk_Field = new StringField("four_pk", "", Field.Store.NO);
        doc.add(four_pk_Field);
        Field cust_grp_cd_Field = new StoredField("cust_grp_cd", "");
        Field cust_grp_mbrp_id_Field = new StoredField("cust_grp_mbrp_id", "");
        doc.add(cust_grp_cd_Field);
        doc.add(cust_grp_mbrp_id_Field);
        String line = null;

        while ((line = br.readLine()) != null) {

            String[] lineTokens = line.split("\\" + delimiter);
            four_pk_Field.setStringValue(four_pk);
            String cust_grp_cd = lineTokens[4];
            cust_grp_cd_Field.setStringValue(cust_grp_cd);
            String cust_grp_mbrp_id = lineTokens[5];
            cust_grp_mbrp_id_Field.setStringValue(cust_grp_mbrp_id);
            writer.addDocument(doc);
        }
        br.close();
    } catch (FileNotFoundException fnfe) {
        LOG.error("", fnfe);
    } catch (IOException ioe) {
        LOG.error("", ioe);
    } finally {
        try {
            fis.close();
        } catch (IOException e) {
            LOG.error("", e);
        }
    }
}

有任何想法吗?

发生这种情况是因为您尝试在一次提交中索引所有2000万个文档(Lucene需要将所有2000万个文档保留在内存中)。 解决该问题应采取的措施-添加

writer.commit()

indexEntityFile方法中,每个X添加文档。 X可能是一百万或类似

代码可能如下所示(只是展示方法,您需要根据需要修改此代码)

int numberOfDocsInBatch = 0;
...
writer.addDocument(doc);
numberOfDocsInBatch ++;
if (numberOfDocsInBatch == 1_000_000) {
   writer.commit();
   numberOfDocsInBatch = 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM