0

我正在将非常大的(大小和计数)文档写入 solr 索引(具有许多数字和一些文本字段的 100 多个字段)。我在 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 秒自动提交一次并执行一次 softAutoCommit (Solr 4.0) 功能。那应该照顾 Solr 的事情。您还必须调整您的 JVM 垃圾收集选项,以便您不会暂停世界 GC。

于 2012-12-04T14:34:03.713 回答