我正在使用从 NuGet 安装的 Lucene.net 3.0.3 和 AzureDirectory 2.0.4937.26631(在 NuGet 中称为 Lucene.Net.Store.Azure)。
azuredirectory.codeplex.com上的项目描述声明“更具体地说:您可以让 1..N 个工作人员角色将文档添加到索引,以及 1..N 个搜索者 webroles 近乎实时地搜索目录。” (添加了重点)暗示可以有多个工作角色并行写入索引。但是,当我尝试执行此操作时,我会收到许多“锁定获取超时: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));
}
}
按顺序运行时,此代码工作正常。但是,如果我在多个线程/工作者上并行运行相同的代码。我收到很多“锁定获取超时: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”文件,并且当文件包含文本“wrote.lock”时,锁定被持有。我从我的搜索中看到,用户遇到了 write.lock 没有被清理的问题。这似乎不是我的问题,因为我可以让相同的代码在按顺序运行时正常工作,并且在这种情况下会清除锁定文件。
我在 AzureDirectory 文档 ( azuredirectory.codeplex.com/documentation ) 中看到“索引一次只能由一个进程更新,因此通过索引角色推送所有添加/更新/删除操作是有意义的。” 但是,这没有任何意义,因为您创建的任何角色都应该有多个实例,因此会有多个实例并行写入索引。此外,项目描述直接声明“您可以让 1..N 个工作人员角色将文档添加到索引中”。请注意,它说的是“一个”索引,而不是索引碎片。
问题:
那么,项目描述是否完全错误?或者实际上有什么方法可以让多个 IndexWriters 并行添加到索引中?我在 API 中看不到任何允许这样做的内容。如果可能,请提供一个代码片段,说明如何使用 AzureDirectory 并行“让 1..N 个工作角色将文档添加到索引”。