C# 4.0 Solrnet/Tomcat 7-编写多个大型文档内存消耗惊人地增长

C# 4.0 Solrnet/Tomcat 7-编写多个大型文档内存消耗惊人地增长,c#-4.0,solr,tomcat7,solrnet,C# 4.0,Solr,Tomcat7,Solrnet,我正在将非常大(大小和计数)的文档写入solr索引(100个字段,包含许多数字和一些文本字段)。我正在W7x64上使用Tomcat7 基于@Maurico的I并行化写入操作(参见下面的代码示例) write-to-Solr方法正在从主循环中“Task”输出(注意:由于write-op花费的时间太长,并且占用了主应用程序,所以我将其输出) 问题是内存消耗无法控制地增长,罪魁祸首是solr写操作(当我注释掉它们时,运行工作正常)。我如何处理这个问题?通过Tomcat?还是SolrNet 谢谢你的建议

我正在将非常大(大小和计数)的文档写入solr索引(100个字段,包含许多数字和一些文本字段)。我正在W7x64上使用Tomcat7

基于@Maurico的I并行化写入操作(参见下面的代码示例)

write-to-Solr方法正在从主循环中“Task”输出(注意:由于write-op花费的时间太长,并且占用了主应用程序,所以我将其输出)

问题是内存消耗无法控制地增长,罪魁祸首是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;
        }
//主循环:
{
:
:
:
//indexDocsList是我在主循环中创建的列表,并将其“分块”发送到任务。
List indexDocsList=新列表();
对于(int n=0;nWriteToSolr(chunk)).ContinueWith(Task=>chunk.Clear());
GC.Collect();
}
}
}
私有void WriteToSolr(列表indexDocsList)
{
尝试
{
if(indexDocsList==null)返回;
如果(indexDocsList.Count
{
_AddRange(indexDocsList.GetRange(range.Item1,range.Item2-range.Item1));
_solr.Commit();
});
indexDocsList.Clear();
GC.Collect();
}
捕获(例外情况除外)
{
ErrorException(“WriteToSolr()”,ex);
}
最后
{
GC.Collect();
};
返回;
}

您在每个批处理后都要手动提交。这是Solr最昂贵的操作。在您的情况下,我建议每x秒自动提交一次,并使用softAutoCommit(Solr 4.0)功能。这应该照顾到索尔的一面。您还必须调整JVM垃圾收集选项,以避免暂停world GC。

在每个批处理之后手动提交。这是Solr最昂贵的操作。在您的情况下,我建议每x秒自动提交一次,并使用softAutoCommit(Solr 4.0)功能。这应该照顾到索尔的一面。您还必须调整JVM垃圾收集选项,以避免暂停世界GC。

IMHO此代码过于复杂。。。为什么不使用我在博客上发布的代码?@Maurico-这会有什么不同?我只是使用了不同的并行化例程。我想我担心的是Tomcat似乎占用了很多内存,我是否做了一些根本错误的事情?对不起,我知道是.NET进程占用了太多内存。关于代码,更简单的代码更容易推理。感谢@Maurico,它是_solr.AddRange(indexDocsList.GetRange(range.Item1,range.Item2-range.Item1));这似乎在吞噬记忆。我可以看到Tomcat的内存增长…不知道如何处理它。有什么想法吗?我觉得这个代码太复杂了。。。为什么不使用我在博客上发布的代码?@Maurico-这会有什么不同?我只是使用了不同的并行化例程。我想我担心的是Tomcat似乎占用了很多内存,我是否做了一些根本错误的事情?对不起,我知道是.NET进程占用了太多内存。关于代码,更简单的代码更容易推理。感谢@Maurico,它是_solr.AddRange(indexDocsList.GetRange(range.Item1,range.Item2-range.Item1));这似乎在吞噬记忆。我可以看到Tomcat的内存增长…不知道如何处理它。有什么想法吗?