Architecture 体系结构:分布式数据处理,具有节点故障容限
我有大量(成千上万)的数据/作业需要频繁重复处理。要处理的作业存储在SQL Server 2012(Web版)数据库中,该数据库会经常更新新作业和/或删除其中的作业 样本:Architecture 体系结构:分布式数据处理,具有节点故障容限,architecture,queue,distributed-computing,system-design,Architecture,Queue,Distributed Computing,System Design,我有大量(成千上万)的数据/作业需要频繁重复处理。要处理的作业存储在SQL Server 2012(Web版)数据库中,该数据库会经常更新新作业和/或删除其中的作业 样本: Id | WorkItem 1 | Copy X to Y 2 | Ping stackoverflow.com 3 | Verify backupset 4 | Send an email 我的目标是在多个节点之间分配作业处理,这既是出于性能原因,也是为了确保即使
Id | WorkItem
1 | Copy X to Y
2 | Ping stackoverflow.com
3 | Verify backupset
4 | Send an email
我的目标是在多个节点之间分配作业处理,这既是出于性能原因,也是为了确保即使节点出现故障也能处理作业
两个考虑因素:
- 我需要确保所有作业最终都由某个节点执行,并且在将作业添加到数据库驱动队列时,这种情况会持续发生
- 我希望所有节点都做一些工作,并防止单个节点获取大部分工作,因此实现某种循环似乎是有意义的
- 节点需要知道其他节点已经在处理什么,这样作业就不会被错误地处理两次。这意味着作业需要标记为正在处理
- 这些工作中的许多都非常小,但需要非常频繁地执行(可能每10-30秒执行一次)。不断更新谁在处理作业,然后释放作业,然后再次处理似乎是主要的数据库开销
- 如果节点在处理过程中死亡,会发生什么情况?有没有办法从中恢复过来
解决这个问题最有效的方法是什么?谢谢大家! 您可能需要尝试SQL Server的最佳配置(不是这方面的专家)。。。但基本方案是这样的:
- 有5列用于管理作业处理
一个叫做DONEUNTIL的,在处理节点死亡的情况下充当故障保护。。。它基本上是一个“估计的处理完成时间点”…
第二个被调用的节点ID,包含处理该作业的节点的ID。
第三个调用DONE,在作业完成后设置为1。
创建了第四个调用,其中包含作业放入表中时的时间戳。
第五个称为JOBID,它是主键 - 让每个节点经常清理DONEUNTIL已传递并完成的所有作业!=1通过将DONEUNTIL和NODEID设置为NULL
- 当一个节点准备好接受下一个作业时,它只选择创建的最早的作业ID,该作业ID在NODEID中为NULL,并且已完成!=1
然后,它会在开始处理之前适当地更新DONEUNTIL和NODEID。
完成处理后,它将更新DONE=1
这个计划真的很好。。。如果您有很多作业,将DONE=1的作业移动到存档表中可能是有意义的。。。这样,您的作业表只包含活动作业(正在等待处理或正在处理),这些作业应能保持其平稳运行…当然,您需要使用队列机制-Sql Server有一个内置的队列机制,称为Sql Service Broker。对于这种情况,一些RDBMS(如Oracle)有你可以建立的内在机制。。。您使用的是哪种RDBMS?@Yahia:SQL Server 2012,但很遗憾,Web版的so Enterprise功能是不可能实现的。有关实现此功能的基本方案,请参阅我的答案……谢谢,Yahia!这与我的想法非常一致(根据我的问题),除了我喜欢的DONEUNTIL想法。我试着看看是否有一种完全不同的方法来避免频繁的状态更新(同样,有成千上万的工作,许多工作以高频率重复执行),但我猜最终信息交换必须在某个地方发生。谢谢@亚历克斯,不客气。。。根据持久性的重要性,您可能能够使用一些内存中的DB和/或创建一个Web服务(可能带有内置内存缓存),而这些Web服务又会被不同的节点调用……这里有一个如何使用Service Broker的示例吗?