【问题标题】:Lucene.Net 2.9.2: OOM exception when adding many documentsLucene.Net 2.9.2:添加许多文档时出现 OOM 异常
【发布时间】: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


    【解决方案1】:

    我读到建议使用单个 IndexWriter 而不是 为每批文档打开和关闭一个新的。

    一般来说这可能是正确的,但您的特殊情况似乎需要另一种方法。您应该每批尝试一个作家。您的大内存需求迫使您使用效率不太理想的解决方案。用记忆换取速度,反之亦然——这很常见。

    【讨论】:

    • 一般来说没问题,但即使我使用批量写入方法,也会出现问题。我尝试了不同的批量大小(500、1000 或 10000 个文档),但内存仍在不断填满(!),直到内存用完。
    • 仅供参考:既然与 Lucene 无关的内存泄漏已修复,我什至可以使用单一编写器方法!
    【解决方案2】:

    尝试最新最好的。它有一些内存泄漏修复。

    https://svn.apache.org/repos/asf/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/

    【讨论】:

      【解决方案3】:

      显然 Lucene 并没有导致内存泄漏,但我的 PostsRepository 的 DataContext 是。我通过为每个“Take”迭代使用一个临时的非跟踪 DC 来解决它。

      还是很抱歉,谢谢!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-01
        • 1970-01-01
        • 2021-11-16
        • 1970-01-01
        • 2014-05-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多