我正在重构一个分析系统,该系统将进行大量计算,并且我需要一些关于可能的架构设计的想法,以解决我面临的数据一致性问题。
当前的架构是基于队列的系统,在该系统中,不同的请求应用程序创建消息,最终由工作程序消耗。每个"请求应用程序"将大型计算分解为较小的部分,这些部分将被发送到队列并由工人处理。当所有部分完成时,源"请求应用程序"将汇总结果。此外,工人从集中式数据库(SQL Server)中消耗信息以处理请求(重要提示:工人不会更改数据库上的任何数据,只会消耗它)。
问题在于我们包含了一个 Web 服务来更新数据库中的信息。这可以随时发生,但是每个源自相同"请求应用程序"的"大型计算"都必须看到数据库上相同的数据。例如:
1. 应用程序 A 生成消息 A1 和 A2,并将其发送到队列。 2. 工人 W1 挑选出消息 A1 进行处理。 3. Web 服务器更新数据库,从状态 S0 更改为 S1。 4. 工人 W2 挑选出消息 A2 进行处理。
我无法允许工人 W2 使用数据库的 S1 状态。为了使整个计算保持一致,它应该使用先前的 S0 状态。
我考虑了两种解决方案:
1. 使用锁定模式来防止 Web 服务器在工人从中消耗信息时更改数据库。缺点是锁可能会持续很长时间,因为不同的"请求应用程序"计算可能会重叠。 2. 在数据库和工人之间创建一个新层(控制按需应用程序的数据库缓存的服务器)。缺点是添加另一层可能会带来显着开销,并且需要大量工作,因为我将不得不重新编写工人的持久性(大量代码)。
我正在考虑第二个解决方案,但对此并不十分自信。是否有更好的想法?我是否设计有误或者遗漏了什么?
当前的架构是基于队列的系统,在该系统中,不同的请求应用程序创建消息,最终由工作程序消耗。每个"请求应用程序"将大型计算分解为较小的部分,这些部分将被发送到队列并由工人处理。当所有部分完成时,源"请求应用程序"将汇总结果。此外,工人从集中式数据库(SQL Server)中消耗信息以处理请求(重要提示:工人不会更改数据库上的任何数据,只会消耗它)。
问题在于我们包含了一个 Web 服务来更新数据库中的信息。这可以随时发生,但是每个源自相同"请求应用程序"的"大型计算"都必须看到数据库上相同的数据。例如:
1. 应用程序 A 生成消息 A1 和 A2,并将其发送到队列。 2. 工人 W1 挑选出消息 A1 进行处理。 3. Web 服务器更新数据库,从状态 S0 更改为 S1。 4. 工人 W2 挑选出消息 A2 进行处理。
我无法允许工人 W2 使用数据库的 S1 状态。为了使整个计算保持一致,它应该使用先前的 S0 状态。
我考虑了两种解决方案:
1. 使用锁定模式来防止 Web 服务器在工人从中消耗信息时更改数据库。缺点是锁可能会持续很长时间,因为不同的"请求应用程序"计算可能会重叠。 2. 在数据库和工人之间创建一个新层(控制按需应用程序的数据库缓存的服务器)。缺点是添加另一层可能会带来显着开销,并且需要大量工作,因为我将不得不重新编写工人的持久性(大量代码)。
我正在考虑第二个解决方案,但对此并不十分自信。是否有更好的想法?我是否设计有误或者遗漏了什么?
- 这是一个庞大的2层遗留系统(使用C#),我们正在尝试将其演变成一种更可扩展的解决方案,尽可能地减少努力。
- 每个工作进程都有可能在不同的服务器上运行。