我正在尝试在 Azure Web 角色中使用最新版本的 Lucene.NET(通过 NuGet 应用于我的项目)。原始 Web 应用程序 (MVC4) 已创建为能够在传统 Web 主机或 Azure 中运行:在前一种情况下,它使用基于文件系统的 Lucene 目录,将 Lucene 索引写入 *App_Data* 子目录;在后一种情况下,它使用从 NuGet ( Lucene.Net.Store.Azure ) 安装的 AzureDirectory。
被索引的文档要么来自网络,要么来自本地上传的一些文件,因为一些要索引的集合是封闭的并且相当小。首先,我尝试使用其中一个小型封闭集,计算大约 1,000 个文件,占用几 GB。
当我在我的开发环境中本地索引这个集合时,索引就完成了,我可以成功地使用它进行搜索。相反,当我尝试在 Azure 上建立索引时,它无法完成并且我不知道确切的问题:我添加了 Elmah 和 NLog 来记录任何问题,但是在 Elmah 或从 Azure 控制台配置的监视工具中没有注册任何内容。只有一次我从 NLog 收到错误,这是Lucene 索引编写器在提交文档添加时在进程结束时抛出的内存不足异常。所以我尝试了:
- 在我的 writer 上调用SetRAMBufferSizeMB(10.0)显式设置非常低的 RAM 缓冲区大小 。
- 多次提交,例如每添加 200 个文档。
- 在索引完成后删除对Optimize的任何调用(另请参见http://blog.trifork.com/2011/11/21/simon-says-optimize-is-bad-for-you/)。
- 以文件系统或 Azure 存储为目标。
- 将 Web 角色 VM 升级到大尺寸。
这些尝试中的大多数在不同的阶段都失败了:有时索引在 1-200 个文档后停止,有时会达到 8-900 个;如果我很幸运,它甚至可以完成。这仅发生在文件系统中,而从未发生在 Azure 存储中:我从来没有运气来完成索引。
我的 Lucene 代码的基本部分非常简单:
IndexWriter writer = new IndexWriter(directory, analyzer, IndexWriter.MaxFieldLength.UNLIMITED);
writer.SetRAMBufferSizeMB(10.0);
根据正在执行的测试,其中 directory 是FSDirectory或AzureDirectory的一个实例。然后,我添加文档及其字段(使用UpdateDocument,因为其中一个字段表示唯一 ID)。完成后,我调用writer.Dispose()。如果测试需要,我会在最终Dispose之前多次调用writer.Commit();这通常有助于系统在遇到内存异常之前继续运行。任何人都可以建议能够完成我的索引的提示吗?