5

Lucene.net 3.0.3.0 (現在の最新バージョン)を使用しています。IndexWriterIndexSearcherの単一インスタンスを使用することが実稼働環境で適切な選択であるかどうかを知りたいです (スレッドの安全性を考慮して)。これらのインスタンスの新しいオブジェクトを作成することは高価な操作であり、lucene は内部的に同時要求をかなりうまく処理するというドキュメントを読みました。

これは、実稼働環境で lucene.net を使用したことのある人への質問です。これでうまくいくかどうか教えてください!

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Lucene.Net.Search;
    using Lucene.Net.Store;
    using System.IO;

    using Directory = Lucene.Net.Store.Directory;
    using Version = Lucene.Net.Util.Version;
    using Lucene.Net.Index;
    using Lucene.Net.Analysis.Standard;
    using Lucene.Net.Analysis;

    namespace MXLuceneConsoleApp
    {
        /// <summary>
        /// This helper class applies a singleton pattern to create Searcher and Writer objects as it's recommended to create them only once.
        /// Also the searcher gets reinitialized, if any write happens.    
        /// </summary>
        public class MXLuceneIndexHelper
        {
            private static IndexSearcher _searcher;        
            private static Directory _directory;
            private static Lazy<IndexWriter> _writer = new Lazy<IndexWriter>(() => new IndexWriter(_directory, new StandardAnalyzer(Version.LUCENE_30), IndexWriter.MaxFieldLength.UNLIMITED));

            //this private constructor makes it a singleton now.
            private MXLuceneIndexHelper() { }

            //Static constructor, opening the directory once for all.
            static MXLuceneIndexHelper()
            {
                _directory = FSDirectory.Open(new DirectoryInfo(Environment.CurrentDirectory + "\\LuceneIndexDir"));
            }

            public static IndexSearcher IndexSearcher
            {
                get
                {
                    if (_searcher == null)
                    {
                        InitializeSearcher();
                    }
                    else if (!_searcher.IndexReader.IsCurrent())
                    {                    
                        //_searcher.IndexReader.Reopen(); 
                        //refreshing the underlying Reader above doesn't do the trick, so I'm reinitializing the Searcher.
                        _searcher.Dispose();
                        InitializeSearcher();
                    }

                    return _searcher;
                }
            }

            public static IndexWriter IndexWriter
            {
                get 
                {                
                    //_writer.SetRAMBufferSizeMB(30.0);
                    return _writer.Value; 
                }
            }

            private static void InitializeSearcher()
            {
                _searcher = new IndexSearcher(_directory, false);

            }
        }//End of class
    }
4

1 に答える 1

3

私の理解では、インデックスごとに IndexWriter のインスタンスは 1 つしか存在しないはずです。この条件を確実にするために、デフォルトで Lucene で有効になっている組み込みのロックがあります。シングルトン パターンに関しては、.NET 4の新しいLazyクラスを参照する必要があると思います。これは、すべてのロックと null チェックを無料で処理します。

IndexSearcher に関しては、必要な数のインスタンスを自由に作成できます。ただし、既存のサーチャーを再利用するとパフォーマンスが向上すると思います。あなたのコードから、既存のサーチャーを再度開く方が、新しいサーチャーを作成するよりもはるかに安価であることがわかります。また、最初の検索を行うときに初期化されるサーチャーには組み込みのキャッシュがあります。IndexReaderWarmer を実装して、サーチャーがウォームアップされるタイミングを制御することもできます (最初の検索の前など)。

于 2013-01-23T14:42:36.053 に答える