我正在使用从NuGet安装的Lucene.net 3.0.3和AzureDirectory 2.0.4937.26631(在NuGet中称为Lucene.Net.Store.Azure)。
在azuredirectory.codeplex.com上的项目描述指出:“更具体地说:您可以具有1..N个工作人员角色,将文档添加到索引中,并且1..N个搜索者Webrol几乎实时地搜索目录。” (添加了重点)暗示可能有多个工作角色并行写入索引。但是,当我尝试执行此操作时,我得到许多“锁定超时: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..1工作者角色添加文件的索引。” 请注意,它说的是“一个”索引,而不是索引碎片。
题:
那么,项目描述仅仅是错误的吗?还是实际上有某种方法可以让多个IndexWriters并行添加到索引中?我在API中看不到任何允许的内容。如果可能,请同时提供一个代码片段,说明如何使用AzureDirectory来“具有1..N个辅助角色,将文档添加到索引中”。
执行此操作的最有效方法是...
1)使用生产者/消费者设计模式
2) 对于大型索引,生产者/消费者模式应生成单独的索引。例如,如果我有 4 个编写器,我会构建 4 个索引,然后使用 Lucene API 来合并它们
3) 之后你的硬盘上就有了一个很好的索引。使用 AzureDirectory 的最后一步是使用 Lucene Directory.Copy 命令将索引从 FSDirectory(硬盘驱动器)复制到 Azure 目录。
我已将其用于 Azure 中的 IaaS/PaaS 产品,效果非常好。请记住,(我之前在帖子中提到过这一点)在我看来,AzureDirectory 还没有准备好“企业”或“严肃的生产”...一些事情,例如:网络重试、上传大型索引、大型索引的压缩需要在之前解决我可以称之为“生产就绪”。如果可以,请使用 IaaS Azure 产品,然后您不需要 Azure Directory,并且可以使用普通 FSDirectory 来构建/显示索引。
| 归档时间: | 
 | 
| 查看次数: | 1539 次 | 
| 最近记录: |