非常に大きな (サイズとカウントの両方の) ドキュメントを 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;
}