【问题标题】:multi threading from multiple machines多台机器的多线程
【发布时间】:2024-01-13 15:54:01
【问题描述】:

我进行了很多研究,但没有找到任何满足我需求的东西。我希望来自 SO 的人可以对此有所了解。

我有一个应用程序,其中预期负载是每个客户数千个工作,我可以拥有 100 多个客户。目前它有 50 个客户,每个客户接近 1000 个工作岗位。这些作业对时间敏感(由客户安排),最多可以运行 15 分钟(每个作业)。

为了扩展和匹配计划,我计划在单个服务器上以多线程方式运行它。到目前为止,一切都很好。但企业希望通过在组合中添加更多服务器来扩大规模(根据需要)。目前我拥有它的方式是当它在数据库中准备好时,控制台应用程序获取前 500 个并使用任务并行库生成 10 个线程并等待它们完成。我无法将其扩展到另一台服务器,因为该服务器可以获取相同的记录。我无法将 db 记录上的状态更新为正在处理,因为如果应用程序在一台服务器上崩溃,该作业将陷入困境。

我可以创建一个消息队列并让多台机器从中挑选。这样做的问题是队列必须是事务性的以支持处理任何崩溃。 MSMQ 仅支持 MS DTC 事务,因为它涉及数据库,我对 DTC 事务不太满意,尤其是多线程和多台机器。过多的维护和设置以及可能的未知问题。

SQL service broker 是不是一个好方法?有没有人在生产环境中做过这样的事情?我还想缩短交易时间(一项工作可以运行 15,20 分钟 - 主要是来自服务的流数据)。我做事务的唯一原因是保持队列的消息完整性。如果工作崩溃(重新出现在队列中),我需要重新选择工作

有什么智慧之言吗?

【问题讨论】:

  • Service Broker 的优势在于您可以将其与普通 SQL 事务一起使用。没有 MSDTC。许多 HA 解决方案不支持 MSDTC,因此通常无法使用。
  • 我目前在我当前客户端的十个不同应用程序中使用 SSB(不是我选择的队列引擎)。我不会向任何人推荐它。它很慢,没有好的工具,而且很不灵活。请改用 RabbitMQ 或 ZeroMQ。

标签: c# multithreading transactions parallel-processing message-queue


【解决方案1】:

为什么不让应用程序接收作业并将它们插入到将包含作业队列的表中。然后每个工作流程可以选择一组工作并将状态设置为处理中,然后完成工作并将状态设置为完成。还可以记录其他信息,例如处理每个作业的服务器名称、开始和结束时间戳。此外,您可以使用独立的工作进程来代替使用多个线程,从而使您的编程更容易。

[编辑] SQL Server 支持记录级锁定,并且还可以防止锁定升级。见Is it possible to force row level locking in SQL Server?。使用这种机制,您可以让您的工作进程对要处理的作业采取排他锁,直到它们完成或崩溃(从而释放锁)。

【讨论】:

  • 好的,当工作进程拿起一组作业,将它们标记为正在处理,然后在完成前崩溃时会发生什么。现在您在数据库中有一组标记为正在处理但永远不会被处理的作业?
  • 假设您的 RDBMS 支持记录级别锁定,您可以让相关工作进程锁定此记录。客户端崩溃后,记录将被解锁。另一种选择是有一个超时时间,然后另一个工作进程接管。作业的所有权更改为属于该服务器/工作进程。