我正在使用从NuGet安装的Lucene.net 3.0.3和AzureDirectory 2.0.4937.26631(在NuGet中称为Lucene.Net.Store.Azure)。
azuredirectory.codeplex.com处的项目描述“更具体:您可以将1..N工作者角色添加到索引,以及1..N搜索器webroles搜索目录近乎实时。“ (强调添加)暗示可以让多个辅助角色并行写入索引。但是,当我尝试这样做时,我得到许多“Lock获取超时:AzureLock@write.lock”。异常。
我的代码遵循AzureDirectory文档(azuredirectory.codeplex.com/documentation)中给出的示例。我的代码粗略(简化问题)。
var dbEntities = // Load database entities here
var docFactory = // Create class that builds lucene documents from dbEntities
var account = // get the CloudStorageAccount
var directory = new AzureDirectory(account, "<my container name>");
using(var writer = new IndexWriter(directory, new StandardAnalyzer(Version.LUCENE_30), createEvenIfExists, IndexWriter.MaxFieldLength.UNLIMITED))
{
foreach(var entity in entities)
{
writer.AddDocument(docFactory.CreateDocument(entity));
}
}
顺序运行时,此代码可以正常运行。但是,如果我在多个线程/ worker上并行运行相同的代码。我得到很多“Lock获取超时:AzureLock@write.lock。”例外:
[Lucene.Net.Store.LockObtainFailedException: Lock obtain timed out: AzureLock@write.lock.]
at Lucene.Net.Store.Lock.Obtain(Int64 lockWaitTimeout) in d:\Lucene.Net\FullRepo\trunk\src\core\Store\Lock.cs:line 83
at Lucene.Net.Index.IndexWriter.Init(Directory d, Analyzer a, Boolean create, IndexDeletionPolicy deletionPolicy, Int32 maxFieldLength, IndexingChain indexingChain, IndexCommit commit) in d:\Lucene.Net\FullRepo\trunk\src\core\Index\IndexWriter.cs:line 1228
at Lucene.Net.Index.IndexWriter..ctor(Directory d, Analyzer a, Boolean create, MaxFieldLength mfl) in d:\Lucene.Net\FullRepo\trunk\src\core\Index\IndexWriter.cs:line 1018
我知道在blob存储中创建了一个“write.lock”文件,当文件包含文本“write.lock”时,会保持锁定。我从搜索中看到,用户遇到了write.lock无法清理的问题。这似乎不是我的问题,因为我可以在顺序运行时获得相同的代码以正常工作,并且在这种情况下清除锁定文件。
我在Azure目录文档(azuredirectory.codeplex.com/documentation)中看到“索引一次只能由一个进程更新,因此通过索引角色推送所有添加/更新/删除操作是有意义的。”但是,这没有任何意义,因为您创建的任何角色都应该有多个实例,因此会有多个实例并行写入索引。此外,项目描述直接指出“您可以将1..N工作者角色添加到一个索引”。注意它是“一个”索引,而不是索引的碎片。
问题:
那么,项目描述是错误吗?或者是否有一些方法可以让多个IndexWrite并行添加到索引中?我无法在API中看到任何允许的内容。如果可能,请提供一个代码片段,说明如何使用AzureDirectory“让1..N工作者角色并行添加文档到索引”。
答案 0 :(得分:1)
最有效的方法是......
1)使用生产者/消费者设计模式
2)对于大型索引,生产者/消费者模式应生成单独的索引。例如,如果我有4个编写器,我构建了4个索引,那么我使用Lucene API来合并它们
3)之后你的硬盘上有一个很好的索引。使用AzureDirectory的最后一步是使用Lucene Directory.Copy命令将索引从FSDirectory(硬盘驱动器)复制到Azure目录。
我已经将它用于Azure中的IaaS / PaaS产品,这非常有用。请记住,(我之前在帖子中提到过)AzureDirectory在我看来并不是“企业”或“认真生产”准备......有些事情如:网络重试,上传大型索引,压缩大型索引需要先解决我能称它为“生产就绪”。如果可以,请使用IaaS Azure产品,然后您不需要Azure目录,并使用vanilla FSDirectory来构建/显示索引。