Lucene Java открывает слишком много файлов.Я правильно использую IndexWriter? - PullRequest
2 голосов
/ 19 июня 2011

Моя реализация Lucene Java поглощает слишком много файлов.Я следовал инструкциям в Lucene Wiki о слишком большом количестве открытых файлов, но это только помогло замедлить проблему.Вот мой код для добавления объектов (PTicket) в индекс:

//This gets called when the bean is instantiated
public void initializeIndex() {
    analyzer = new WhitespaceAnalyzer(Version.LUCENE_32);
    config = new IndexWriterConfig(Version.LUCENE_32, analyzer);

}


public void addAllToIndex(Collection<PTicket> records) {  
    IndexWriter indexWriter = null;
    config = new IndexWriterConfig(Version.LUCENE_32, analyzer);

    try{
        indexWriter = new IndexWriter(directory, config);
        for(PTicket record : records) {
            Document doc = new Document();
            StringBuffer documentText = new StringBuffer();
            doc.add(new Field("_id", record.getIdAsString(), Field.Store.YES, Field.Index.ANALYZED));
            doc.add(new Field("_type", record.getType(), Field.Store.YES, Field.Index.ANALYZED));

            for(String key : record.getProps().keySet()) {
                List<String> vals = record.getProps().get(key);

                for(String val : vals) {
                    addToDocument(doc, key, val);
                    documentText.append(val).append(" ");
                }
            }
            addToDocument(doc, DOC_TEXT, documentText.toString());        
            indexWriter.addDocument(doc);    
        }

        indexWriter.optimize();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        cleanup(indexWriter);
    }
}

private void cleanup(IndexWriter iw) {
    if(iw == null) {
        return;
    }

    try{
        iw.close();
    } catch (IOException ioe) {
        logger.error("Error trying to close index writer");
        logger.error("{}", ioe.getClass().getName());
        logger.error("{}", ioe.getMessage());
    }
}

private void addToDocument(Document doc, String field, String value) {
    doc.add(new Field(field, value, Field.Store.YES, Field.Index.ANALYZED));
}

РЕДАКТИРОВАТЬ ДОБАВИТЬ код для поиска

public Set<Object> searchIndex(AthenaSearch search) {  

    try {
        Query q = new QueryParser(Version.LUCENE_32, DOC_TEXT, analyzer).parse(query);

        //search is actually instantiated in initialization.  Lucene recommends this.
        //IndexSearcher searcher = new IndexSearcher(directory, true);
        TopDocs topDocs = searcher.search(q, numResults);
        ScoreDoc[] hits = topDocs.scoreDocs;
        for(int i=start;i<hits.length;++i) {
            int docId = hits[i].doc;
            Document d = searcher.doc(docId);
            ids.add(d.get("_id"));
        }
        return ids;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

Этот код находится в сетиapplication.

1) Это рекомендуемый способ использования IndexWriter (создание нового экземпляра для каждого добавления в индекс)?

2) Я читал, что повышение ulimit поможет, но этопросто кажется бинтом, который не решит актуальную проблему.

3) Может ли проблема заключаться в IndexSearcher?

Ответы [ 4 ]

3 голосов
/ 19 июня 2011

1) Это рекомендуемый способ использования IndexWriter (создание нового экземпляра при каждом добавлении в индекс)?

Я советую Нет, есть конструкторы , который проверит, существует ли, или создаст новую запись в каталоге, содержащем индекс.проблема 2 была бы решена, если вы повторно используете indexwriter.

EDIT:

Хорошо, в Lucene 3.2 большинство конструкторов, кроме одного, устарели, так что результат Indexwriter может быть достигнут с помощью EnumIndexWriterConfig.OpenMode со значением CREATE_OR_APPEND .

также, открытие нового устройства записи и закрытие для каждого добавления документа неэффективно, я предлагаю повторное использование, если вы хотите ускорить индексацию, установите setRamBufferSize значение по умолчанию составляет 16 МБ, так что делайте это методом проб и ошибок

из документов:

Обратите внимание, что вы можете открыть индекс с помощью create = true, даже когдачитатели используют индекс.Старые читатели продолжат поиск моментального снимка, который они открыли, и не увидят вновь созданный индекс, пока они не откроются снова.

также повторно используют IndexSearcher, я не вижукод для поиска, но Indexsearcher является потокобезопасным и может использоваться как Readonly , а также

, также я предлагаю вам использовать MergeFactor на устройстве записи, это не обязательно, но поможет ограничить созданиеинвертированных индексных файлов, делайте это методом проб и ошибок

1 голос
/ 19 июня 2011

Я думаю, что нам нужно увидеть ваш поисковый код, чтобы убедиться, но я подозреваю, что это проблема с поиском по индексу.В частности, убедитесь, что ваше устройство чтения индексов правильно закрыто, когда вы закончили с ним.

Удачи,

0 голосов
/ 20 июня 2011

Этот вопрос, вероятно, является дубликатом Слишком много открытых файлов Ошибка в Lucene

Я повторяю здесь мой ответ для этого.

Используйте составной индекс, чтобы уменьшить количество файлов. Когда этот флаг установлен, lucene запишет сегмент как один файл .cfs вместо нескольких файлов. Это значительно сократит количество файлов.

IndexWriter.setUseCompoundFile(true)
0 голосов
/ 19 июня 2011

Научный правильный ответ будет таким: Вы не можете сказать по этому фрагменту кода.

Более конструктивный ответ: Вы должны убедиться, что в каждый момент времени в индекс записывается только один IndexWriter, и поэтому вам необходим какой-то механизм, чтобы убедиться в этом. Поэтому мой ответ зависит от того, чего вы хотите достичь:

  • Вы хотите более глубокое понимание Lucene? или ..
  • Вы просто хотите создать и использовать индекс?

Если вы ответите на последний вопрос, вы, вероятно, захотите взглянуть на такие проекты, как Solr , который скрывает все чтение и запись индекса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...