场合
用户可以上传Documents,一个队列消息将被放入带有文件ID的队列中。工作者角色将选择此并获取文档。用Lucene完全解析它。解析完成后,应更新Webrole上的Lucene IndexSearcher。
在Web角色上我保留了一个静态的Lucene IndexSearcher,因为否则你必须在每个搜索请求中创建一个新的IndexSearch,这会带来很多开销等。
我想要做的是从工作者角色发送通知,以便更新他的IndexSearcher所需的Web角色。
可能的解决方案
什么是最好的解决方案,还是有其他解决方案?
非常感谢!
答案 0 :(得分:2)
如果您的工作者角色使用类似(DateTime.MaxValue - DateTime.UtcNow).Ticks.ToString("d19")
的PK将每个完成的作业的详细信息写入表中,您将获得已处理的最新作业的排序列表。设置您的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.
}
对于执行索引编制工作的辅助角色,这很好,因为他们可以不加思索地写入表而不用担心冲突。对于您,您还有他们正在处理的作业的审核日志(假设您在其中放置了一些详细信息)。
但是,您还有一个问题:听起来您有1个更新索引的Web角色。这个Web角色当然可以根据您选择的频率轮询此表(只需跟踪LastIndexTime以便稍后搜索)。如果您有多个Web角色,那么您的问题是如何控制Web角色的并发性。每个Web角色是否都维护自己的索引,或者您是否已将其存储在某个地方?对不起,但是如果这很明显的话,我不是Lucene的专家。
无论如何,如果您的WebRole中有多个实例,并且所有人都可以看到一个索引,则需要防止多个角色反复更新索引。您可以通过租用索引(如果存储在blob存储中)来执行此操作。
根据评论进行更新:
如果每个WebRole实例都有自己的索引,那么您不必担心租赁。只有当他们一起共享blob资源时才会这样。因此,这种技术应该可以正常工作,并且唯一可能的障碍是Web角色的轮询间隔可能略微不同步,导致所有更新之前的结果会有所不同(取决于您点击的实例)。在桌子上每30秒轮询一次,这将是你最大的不同步。每个Web角色实例只需跟踪上次更新并从该点进行增量搜索。
答案 1 :(得分:1)
根据上传频率,您可能会发现队列消息导致您不必要的更新。例如,如果您收到十几个上传并在近距离处理它们,那么您现在有十几个队列消息,每个消息都告诉您的Web角色要更新。保留单个信号(可能是表行或SQL Azure行)会更有意义。您可以简单地将行值设置为1,表示需要更新。当您的Web角色检测到此更改时,请重置为0并开始更新。注意:如果使用Azure表行,则需要轮询更新(并且根据流量,您可以开始累积大量事务)。您也可以将AppFabric Cache用于此信号。
您可以在Web角色的内部端点上使用WCF服务。但是,您仍然遇到突发问题(如果您在webrole更新时获得了十几个上传内容,那么您不希望再进行其他更新)。