Lucene 从Azure工作者角色向Azure Web角色发送通知-最佳做法

Lucene 从Azure工作者角色向Azure Web角色发送通知-最佳做法,lucene,azure,lucene.net,azure-worker-roles,azure-web-roles,Lucene,Azure,Lucene.net,Azure Worker Roles,Azure Web Roles,形势 用户可以上载文档,一条队列消息将被放置到带有文档ID的队列中。工作者角色将拾取该消息并获取文档。用Lucene完全解析它。解析完成后,应该更新Webrole上的Lucene IndexSearcher 在Web角色中,我保留了一个静态Lucene IndexSearcher,因为否则您必须对每个搜索请求进行新的IndexSearch,这会带来大量开销等 我想做的是从工作者角色向Web角色发送一个通知,通知他需要更新他的IndexSearcher 可能的解决方案 做一些通知队列。Web角色

形势

用户可以上载文档,一条队列消息将被放置到带有文档ID的队列中。工作者角色将拾取该消息并获取文档。用Lucene完全解析它。解析完成后,应该更新Webrole上的Lucene IndexSearcher

在Web角色中,我保留了一个静态Lucene IndexSearcher,因为否则您必须对每个搜索请求进行新的IndexSearch,这会带来大量开销等

我想做的是从工作者角色向Web角色发送一个通知,通知他需要更新他的IndexSearcher

可能的解决方案

  • 做一些通知队列。Web角色启动一个无休止的任务,不断检查通知队列。如果他发现一条消息,那么他应该更新IndexSearch
  • 在工作者角色上启动WCF服务并与Web角色连接。从工作者角色执行回调,并通过服务告诉Web角色他需要更新他的IndexSearcher
  • 只需定期更新
最好的解决方案是什么,或者是否有其他解决方案


非常感谢

根据上载频率,您可能会发现队列消息导致不必要的更新。例如,如果您得到十几个上传并在近距离内处理它们,那么您现在就有十几个队列消息,每个消息都告诉您的web角色要更新。保留单个信号(可能是表行或SQL Azure行)更有意义。您可以简单地将行值设置为1,表示需要更新。当您的web角色检测到此更改时,请重置为0并启动更新。注意:如果使用Azure表行,您需要轮询更新(并且根据流量,您可能会开始累积大量事务)。您也可以将AppFabric缓存用于此信号


您可以在Web角色的内部端点上使用WCF服务。但是,您仍然存在突发问题(例如,如果您在webrole更新时收到十几次上传,那么您不想再进行十几次更新)。

如果您的工作者角色使用类似于
(DateTime.MaxValue-DateTime.UtcNow)的PK将每个完成的作业的详细信息写入表中。Ticks.ToString(“d19”)
,您将拥有已处理的最新作业的排序列表。将web角色设置为轮询表,如下所示:

var q = ctx.CreateQuery<LatestJobs>("jobstable")
    .Where(j => j.PartitionKey.CompareTo(LastIndexTime.GetReverseTicks()) < 0)
    .Take(1)
    .AsTableServiceQuery()

if (q.Count() > 0)
{
    //new jobs exist since last check... re-index.
}
var q=ctx.CreateQuery(“jobstable”)
.Where(j=>j.PartitionKey.CompareTo(LastIndexTime.GetReverseTicks())<0)
.采取(1)
.AsTableServiceQuery()
如果(q.Count()>0)
{
//自上次检查后存在新作业…重新编制索引。
}
对于执行索引工作的工作者角色来说,这是非常好的,因为他们可以不加选择地写入表而不必担心冲突。对于您来说,您还拥有他们正在处理的作业的审核日志(假设您在其中输入了一些详细信息)

但是,您还有一个问题:听起来您有一个web角色更新索引。当然,这个web角色可以按您选择的频率轮询此表(只需跟踪LastIndexTime以便稍后搜索)。您的问题是,如果您有多个web角色,如何控制这些角色的并发性。每个web角色都有自己的索引吗?还是有一个存储在某个地方的索引?对不起,如果这是显而易见的,我不是Lucene方面的专家

无论如何,如果您的WebRole中有多个实例,并且所有人都可以看到一个索引,那么您需要防止多个角色反复更新索引。您可以通过租用索引(如果存储在blob存储中)来实现这一点

根据评论更新:


如果每个WebRole实例都有自己的索引,那么您就不必担心租用问题。只有当它们共享一个blob资源时,才会这样做。因此,这种技术应该可以正常工作,您唯一的潜在障碍是web角色的轮询间隔可能会稍微不同步,导致在所有更新之前的结果有所不同(取决于您所访问的实例)。在桌面上每30秒轮询一次,这将是您的最大不同步。每个web角色实例只需跟踪上次更新的时间,并从该时间点开始进行增量搜索。

工作者角色一次不接收一条队列消息。他获取最多的消息(32条)并解析这些消息。在他解析完所有这些之后,他才会发送一个更新。因此,如果同时上传1、10或32个文档,他仍然只会更新一次。单信号的想法很好,但这意味着我需要不断地查询表行,对吗?每个实例都有自己的IndexSearcher。indexsearcher的更新意味着它从Blob存储下载所有新的Lucene索引文件,并将其保存在本地。这样他就可以很容易地质疑这一点。你说的出租指数是什么意思?将IndexSearch存储在BlobStorage中?有关更多说明,请参阅我的更新。租赁仅适用于blob存储中的共享资源。这里不是这样。我不认为勾号是主键的好选择,也许只是使用标识列?PartitionKey,而不是主键。为什么这不是一个好的选择呢?