0

非常に大きな (サイズとカウントの両方の) ドキュメントを solr インデックス (多くの数値フィールドといくつかのテキスト フィールドを持つ数百のフィールド) に書き込んでいます。W7 x64 で Tomcat 7 を使用しています。

何百万ものドキュメントをインデックス化するときの@Mauricoの提案に基づいて、書き込み操作を並列化します(以下のコードサンプルを参照)

Solrメソッドへの書き込みは、メインループから「タスク」されています(注:書き込み操作に時間がかかりすぎてメインアプリを保持しているため、タスクアウトします)

問題は、メモリ消費が制御不能に増加することです。原因はsolr書き込み操作です(コメントアウトすると、実行は正常に機能します)。この問題を処理するにはどうすればよいですか? Tomcat経由?またはSolrNet?

ご提案いただきありがとうございます。

        //main loop:
        {
               :
               :
               :
             //indexDocsList is the list I create in main loop and "chunk" it out to send to the task.
              List<IndexDocument> indexDocsList = new List<IndexDocument>();
              for(int n = 0; n< N; n++)
              {
                  indexDocsList.Add(new IndexDocument{X=1, Y=2.....});
                  if(n%5==0) //every 5th time we write to solr
                  {
                     var chunk = new List<IndexDocument>(indexDocsList);
                     indexDocsList.Clear();
                     Task.Factory.StartNew(() => WriteToSolr(chunk)).ContinueWith(task => chunk.Clear());
                     GC.Collect();
                   }
              }
      }

      private void WriteToSolr(List<IndexDocument> indexDocsList)
        {

            try
            {
                if (indexDocsList == null) return;
                if (indexDocsList.Count <= 0) return;
                int fromInclusive = 0;
                int toExclusive = indexDocsList.Count;
                int subRangeSize = 25;

                //TO DO: This is still leaking some serious memory, need to fix this 
                ParallelLoopResult results = Parallel.ForEach(Partitioner.Create(fromInclusive, toExclusive, subRangeSize), (range) =>
                {
                    _solr.AddRange(indexDocsList.GetRange(range.Item1, range.Item2 - range.Item1));
                    _solr.Commit();
                });


                indexDocsList.Clear();
                GC.Collect();
            }
            catch (Exception ex)
            {
                logger.ErrorException("WriteToSolr()", ex);
            }
            finally
            {

                GC.Collect();
            };
            return;
        }
4

1 に答える 1

3

各バッチの後に手動でコミットしています。これは、Solr にとって最もコストのかかる操作です。あなたの場合、x 秒ごとに autoCommit をお勧めし、softAutoCommit (Solr 4.0) 機能を実行します。これで、Solr 側の処理が行われるはずです。また、ワールド GC を一時停止しないように、JVM ガベージ コレクション オプションを微調整する必要があります。

于 2012-12-04T14:34:03.713 に答える