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