我正在重构一个将进行大量计算的分析系统,并且我需要一些关于可能的架构设计的想法来解决我面临的数据一致性问题。
当前架构
我有一个基于队列的系统,其中不同的请求应用程序创建最终由工作人员使用的消息。
Each "请求应用程序“将大型计算分解为较小的部分,这些部分将被发送到队列并由workers.
当所有的部分都完成后,原始的“请求应用程序”将巩固成果。
另外,workers使用来自中央数据库 (SQL Server) 的信息来处理请求 (重要提示:工作人员不会更改数据库上的任何数据,只会使用它).
Problem
好的。到目前为止,一切都很好。当我们包含更新数据库信息的 Web 服务时,问题就出现了。这种情况随时可能发生,但至关重要的是,源自同一“请求应用程序”的每个“大型计算”都能在数据库中看到相同的数据。
例如:
- App A生成消息A1和A2,并将其发送到队列
- Worker W1选取消息 A1 进行处理。
- Web 服务器更新数据库,从状态更改S0 to S1.
- Worker W2获取消息A2进行处理
我只是不能让工作人员 W2 使用数据库的状态 S1。为了使整个计算保持一致,应该使用之前的 S0 状态。
Thoughts
-
A 锁图案以防止 Web 服务器在有工作人员使用数据库中的信息时更改数据库。
-
cons:锁定可能会持续很长时间,因为不同“请求应用程序”的计算形式可能会重叠(A1、B1、A2、B2、C1、B3 等)。
-
Create 新层数据库和工作人员之间(通过 req.app 控制数据库缓存的服务器)
-
cons:添加另一层可能会带来巨大的开销(也许?),而且这是一项繁重的工作,因为我必须重写工作人员的持久性(大量代码)。
我正在等待第二种解决方案,但对此不太有信心。
有什么绝妙的想法吗?我是否设计错误,或者遗漏了什么?
OBS:
- 这是一个巨大的 2 层遗留系统(C# 语言),我们正在尝试
以最少的努力演变成一个更具可扩展性的解决方案
可能的。
- 每个工作人员可能在不同的服务器上运行。
你可以版本化你的数据库吗?
假设请求应用程序用 ct1 标记计算的开始。现在,此计算生成的每条消息都带有相同的时间戳。
而且每个数据库更新都会用更新时间标记数据库状态。因此,状态 S0 在时间 t0 上,状态 S1 在时间 t1 上,等等。
现在,当工作人员收到消息时,它需要获取更新时间小于或等于消息时间的最大值的数据库状态。在您的示例中,如果 A1 和 A2 都带有 ct1 标记,并且 t1 > ct1,则两个工作人员都将检索 S0 而不是 S1。
这当然意味着您需要在数据库中保存多个版本。如果您知道计算必须在某个时间窗口后完成,您可以在一段时间后清理这些版本。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)