2

情况

用户可以上传文档,队列消息将被放置到带有文档 ID 的队列中。Worker Role 会选择这个并获取文档。用 Lucene 完全解析它。解析完成后,应该更新 Webrole 上的 Lucene IndexSearcher。

在 Web 角色上,我保留了一个静态的 Lucene IndexSearcher,因为否则您必须为每个搜索请求创建一个新的 IndexSearch,这会产生很多开销等。

我想要做的是从 Worker Role 向 Web Role 发送通知,通知他需要更新他的 IndexSearcher。

可能的解决方案

  • 制作某种通知队列。Web 角色启动了一个无休止的任务,不断检查通知队列。如果他找到一条消息,那么他应该更新 IndexSearch。
  • 在 Worker 角色上启动 WCF 服务并与 Web 角色连接。从 Worker Role 进行回调,并通过 Service 告诉 Web Role 他需要更新他的 IndexSearcher。
  • 只需定期更新它

什么是最好的解决方案,或者还有其他解决方案吗?

非常感谢 !

4

2 回答 2

2

如果您的工作人员角色使用类似的 PK 将每个已完成作业的详细信息写入表中(DateTime.MaxValue - DateTime.UtcNow).Ticks.ToString("d19"),您将获得已处理的最新作业的排序列表。将您的网络角色设置为轮询表格,如下所示:

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.
}

对于做索引工作的工作者角色来说,这很好,因为他们可以不加选择地写入表而不必担心冲突。对您而言,您还拥有他们正在处理的作业的审核日志(假设您在其中放置了一些详细信息)。

但是,您还有一个问题:听起来您有 1 个更新索引的网络角色。这个网络角色当然可以根据您选择的任何频率轮询该表(只需跟踪 LastIndexTime 以便稍后搜索)。您的问题是如果您有多个角色,如何控制 Web 角色的并发性。每个 Web 角色是否都维护自己的索引,或者您是否将一个存储在某个地方供所有人使用?抱歉,如果这很明显,我不是 Lucene 专家。

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

根据评论更新:

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

于 2011-08-30T14:04:37.117 回答
1

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

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

于 2011-08-30T11:26:26.143 回答