架构:具有节点容错的分布式数据处理

时间:2012-12-16 21:30:25

标签: architecture queue distributed-computing system-design

我有很多需要频繁重复处理的数据(数万)数据/作业。要处理的作业存储在SQL Server 2012(Web Ed)数据库中,该数据库经常更新新作业和/或可能从中删除作业。

样品:

Id     |  WorkItem
1      |  Copy X to Y
2      |  Ping stackoverflow.com
3      |  Verify backupset
4      |  Send an email

我的目标是在多个节点之间分配作业处理,这既是出于性能原因,也是为了确保即使节点出现故障也能处理作业。

两个考虑因素:

  • 我需要确保所有作业最终都由某些节点执行,并且当作业被添加到数据库驱动的队列时,这种情况会不断发生。
  • 我希望所有节点都可以工作,并阻止单个节点获取大部分工作,因此实现某种循环似乎是有道理的。

因为整个系统需要抵抗节点故障,所以我无法将工作“分配”给节点,因为我不知道怎么了最新的,什么不是。我最初的想法是让每个节点从数据库“获取”一个或多个作业,处理它们,然后将数据返回到SQL数据库。但是,有一些问题:

  • 节点需要知道其他节点已经处理了什么,因此作业不会被错误地处理两次。这意味着需要将作业标记为正在处理。
  • 这些工作中的很多都非常小,但需要非常频繁地执行(可能每10-30秒)。不断更新谁正在处理作业然后释放作业,然后再次处理似乎是主要的数据库开销。
  • 如果节点在中间处理中死亡会怎样?有没有办法从中恢复?

解决此问题的最有效方法是什么?谢谢!

2 个答案:

答案 0 :(得分:1)

您可能需要尝试SQL Server的最佳配置(不是专家)...但基本方案如下:

  • 有5列来管理作业处理
    一个叫做DONEUNTIL的DONEUNTIL在你的处理节点死亡的情况下充当故障保护...它基本上是一个“估计的处理完成时间点”...... 第二个名为NODEID,包含处理该作业的NODE的ID 第三个叫做DONE,一旦工作完成就会设置为1 第四个名为CREATED,其中包含作业放入表格时的时间戳 第五个叫做JOBID,它是主键。

  • 让每个节点经常清理DONEUNTIL已通过的所有作业,并通过将DONEUNTIL和NODEID设置为NULL来完成DONE!= 1

  • 当节点准备好接受下一个作业时,它只选择最旧的CREATED在NODEID中为NULL且完成的JOB!= 1 然后它会在开始处理之前适当地更新DONEUNTIL和NODEID 完成处理后,它会更新DONE = 1。

您可以使用上述变体 - 例如具有作业优先级,重试计数器等,或将“作业管理信息”放入单独的表格等。

这个方案工作得很好......如果你有很多工作,将DONE = 1的工作移到存档表中可能是有意义的......这样你的工作表只包含活动工作(等待处理或正在处理的,应该保持它顺利运行......

答案 1 :(得分:0)

确定您需要使用队列机制 - Sql Server有一个名为Sql Service Broker的内置队列机制。