4

Tomcat サーバーから取得した大量のログ ファイルのインデックスを作成しようとしています。各ファイルを開き、各行のインデックスを作成し、Apache lucene を使用して各行を保存するコードを作成しました。これらはすべてマルチスレッドを使用して行われます。

このコードを実行しようとすると、この例外が発生します

org.apache.lucene.store.LockObtainFailedException: Lock obtain timed out:

コード

  if (indexWriter.getConfig().getOpenMode() == IndexWriterConfig.OpenMode.CREATE)
        {
          // New index, so we just add the document (no old document can be there):
           System.out.println("adding " + path);

                indexWriter.addDocument(doc);

       } else {
          // Existing index (an old copy of this document may have been indexed) so 
       // we use updateDocument instead to replace the old one matching the exact 
           // path, if present:
            System.out.println("updating " + path);

                indexWriter.updateDocument(new Term("path", path), doc);

          }
        indexWriter.commit();
        indexWriter.close();

毎回インデックスをコミットしているので、書き込みロックが発生する可能性があると思いました。だから私は削除しましたindexWriter.commit();:

if (indexWriter.getConfig().getOpenMode() == IndexWriterConfig.OpenMode.CREATE)
    {
      // New index, so we just add the document (no old document can be there):
       System.out.println("adding " + path);

            indexWriter.addDocument(doc);

   } else {
      // Existing index (an old copy of this document may have been indexed) so 
   // we use updateDocument instead to replace the old one matching the exact 
       // path, if present:
        System.out.println("updating " + path);

            indexWriter.updateDocument(new Term("path", path), doc);

      }

    indexWriter.close();

今、私は例外を取得しません

Q. 私の質問は、なぜ indexWriter.commit(); なのかということです。例外が発生します。indexWriter.commit(); を削除しても 検索中に問題はありません。つまり、意図したとおりの結果が得られます。次に、なぜ indexWriter.commit(); を使用するのですか? ?

4

1 に答える 1

2

つまり、DB コミットに似ています。トランザクションをコミットしない限り、Solr に追加されたドキュメントはメモリに保持されるだけです。コミット時にのみ、Document はインデックスに保持されます。
ドキュメントがメモリ内にあるときに Solr がクラッシュすると、これらのドキュメントが失われる可能性があります。

説明:-

初日からの Lucene の原則の 1 つは、ライト ワンス ポリシーです。ファイルを 2 回書き込むことはありません。IndexWriter を介してドキュメントを追加すると、メモリにインデックスが作成され、特定のしきい値 (最大バッファ ドキュメントまたは RAM バッファ サイズ) に達すると、すべてのドキュメントがメイン メモリからディスクに書き込まれます。詳細については、こちらとこちらをご覧ください。ドキュメントをディスクに書き込むと、セグメントと呼ばれるまったく新しいインデックスが作成されます。ここで、一連のドキュメントにインデックスを付けるか、本番環境でインクリメンタル インデックスを実行すると、セグメントの数が頻繁に変化することがわかります。ただし、commit を呼び出すと、Lucene は RAM バッファ全体をセグメントにフラッシュし、それらを同期して、このコミットに属するすべてのセグメントへのポインタを SEGMENTS ファイルに書き込みます

ドキュメントがすでに Solr に存在する場合は、上書きされるだけです (一意の ID によって決定されます)。
したがって、検索は正常に機能する可能性がありますが、コミットしない限り、最新のドキュメントは検索できません。

また、indexwriter を開いてインデックスをロックすると、ライターを閉じてロックを解除する必要があります。

于 2013-03-19T13:45:15.207 に答える