【发布时间】:2011-11-05 10:48:25
【问题描述】:
我正在尝试使用 Lucene.NET 2.9.2 索引大约 10.000.000 个文档。这些文档(不同长度的论坛帖子)从 MSSQL 数据库中批量获取 10.000 个,然后传递给我的名为 LuceneCorpus 的 Lucene.NET 包装类:
public static void IndexPosts(LuceneCorpus luceneCorpus, IPostsRepository postsRepository, int chunkSize)
{
// omitted: this whole method is executed in a background worker to enable GUI feedback
// chunkSize is 10.000
int count = 0;
// totalSteps is ~10.000.000
int totalSteps = postsRepository.All.Count();
while (true)
{
var posts = postsRepository.All.Skip(count).Take(chunkSize).ToList();
if (posts.Count == 0)
break;
luceneCorpus.AddPosts(posts);
count += posts.Count;
}
luceneCorpus.OptimizeIndex();
}
我读到建议使用单个 IndexWriter 而不是为每批文档打开和关闭一个新的。因此,我的 LuceneCorpus 类如下所示:
public class LuceneCorpus
{
private Analyzer _analyzer;
private Directory _indexDir;
private IndexWriter _writer;
public LuceneCorpus(DirectoryInfo indexDirectory)
{
_indexDir = FSDirectory.Open(indexDirectory);
_analyzer = new StandardAnalyzer(Version.LUCENE_29);
_writer = new IndexWriter(_indexDir, _analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
_writer.SetRAMBufferSizeMB(128);
}
public void AddPosts(IEnumerable<Post> posts)
{
List<Document> docs = new List<Document>();
foreach (var post in posts)
{
var doc = new Document();
doc.Add(new Field("SimplifiedBody", post.SimplifiedBody, Field.Store.NO, Field.Index.ANALYZED));
_writer.AddDocument(doc);
}
_writer.Commit();
}
public void OptimizeIndex()
{
_writer.Optimize();
}
}
现在,我的问题是内存消耗不断增加,直到我在 IndexPosts 方法中的某处索引了大约 700.000 个文档后最终遇到内存不足异常。
据我所知,索引写入器应在达到 RAMBufferSize (128 MB) 或调用 Commit() 时刷新。事实上,作者肯定会刷新,甚至会跟踪刷新,但内存仍然会被填满。作者是否以某种方式保留了对文档的引用,以便它们不会被垃圾收集或者我在这里遗漏了什么?
提前致谢!
编辑:我还尝试在 AddPosts 方法的范围内而不是在类范围内初始化 writer、analyzer 和 indexDir,但这也不能防止 OOM 异常。
【问题讨论】:
标签: indexing lucene.net out-of-memory