gpt4 book ai didi

azure - 如何使用 AzureDirectory 和 Lucene.net 并行 IndexWriter?

转载 作者:行者123 更新时间:2023-12-04 21:43:46 26 4
gpt4 key购买 nike

我使用的是从 NuGet 安装的 Lucene.net 3.0.3 和 AzureDirectory 2.0.4937.26631(在 NuGet 中称为 Lucene.Net.Store.Azure)。

项目描述位于azuredirectory.codeplex.com指出“更具体地说:您可以有 1..N 个工作角色将文档添加到索引,以及 1..N 个搜索 Web 角色近乎实时地搜索目录。” (强调)这意味着可以有多个工作角色并行写入索引。但是,当我尝试执行此操作时,我收到许多“锁定获取超时:[email protected]”。异常(exception)。

我的代码遵循 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));
}
}

当顺序运行时,此代码工作正常。但是,如果我在多个线程/工作线程上并行运行相同的代码。我收到很多“锁定获取超时:[email protected]”。异常(exception):

[Lucene.Net.Store.LockObtainFailedException: Lock obtain timed out: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0c4d76797e6940636f674c7b7e6578692260636f67" rel="noreferrer noopener nofollow">[email protected]</a>.]
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

据我所知,“write.lock”文件是在 blob 存储中创建的,当该文件包含文本“wrote.lock”时,就会保持锁定。我从搜索中看到用户遇到了 write.lock 未清理的问题。这似乎不是我的问题,因为我可以让相同的代码在按顺序运行时正常工作,并且在这种情况下锁定文件会被清理。

我在 AzureDirectory 文档 ( azuredirectory.codeplex.com/documentation ) 中看到“索引一次只能由一个进程更新,因此通过索引角色推送所有添加/更新/删除操作是有意义的。”但是,这没有任何意义,因为您创建的任何角色都应该有多个实例,因此会有多个实例并行写入索引。此外,项目描述直接指出“您可以让 1..N 个工作角色将文档添加到一个索引”。请注意,它说的是“一个”索引,而不是索引碎片。

问题:

那么,项目描述是不是错误?或者实际上是否有某种方法可以让多个 IndexWriter 并行添加到索引中?我在 API 中看不到任何允许这样做的内容。如果可能,请提供如何使用 AzureDirectory 并行“让 1..N 个辅助角色将文档添加到索引”的代码片段。

最佳答案

执行此操作的最有效方法是...

1)使用生产者/消费者设计模式

  • 有了这个,您可以拥有 x 数量的线程/任务,每个单独的写入器写入索引
  • 您可以有 x 个消费者(即线程/任务)从数据库读取数据

2) 对于大型索引,生产者/消费者模式应生成单独的索引。例如,如果我有 4 个编写器,我会构建 4 个索引,然后使用 Lucene API 来合并它们

3) 之后,您的硬盘上就会有一个很好的索引。使用 AzureDirectory 的最后一步是使用 Lucene Directory.Copy 命令将索引从 FSDirectory(硬盘驱动器)复制到 Azure 目录。

  • 这很重要,因为 AzureDirectory 在内部使用 Azure Blob 存储上的元数据属性来确定索引的“上次更新指纹”
  • AzureDirectory 还会在上传之前压缩索引...这就是我喜欢将其发送到 Azure Blob 存储之前的硬盘驱动器步骤的原因,因为我可以使用并行线程在硬盘驱动器上压缩它。我更改了 AzureDirectory 的实现,因为它在内存中完成所有操作,而对于 20 gig 索引来说这样做并不好:)

我已将其用于 Azure 中的 IaaS/PaaS 产品,效果非常好。请记住,(我之前在帖子中提到过这一点)在我看来,AzureDirectory 还没有准备好“企业”或“严肃的生产”...一些事情,例如:网络重试、上传大型索引、大型索引的压缩需要在之前解决我可以称之为“生产就绪”。如果可以,请使用 IaaS Azure 产品,然后就不需要 Azure Directory,并且可以使用普通 FSDirectory 来构建/显示索引。

关于azure - 如何使用 AzureDirectory 和 Lucene.net 并行 IndexWriter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18469736/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com