我在我的架构规划中处于分支状态,并且没有足够的生产经验与Redis,Aerospike或RabbitMQ知道如何继续。
有3个以上的生产者和15个以上的工人。系统的可变负载范围在0-10k req / s之间。我有四个要求:
以下是架构以过度简化的术语运作的方式:
当一个新的客户端请求到达时,生产者互斥锁会锁定该请求令牌以及工作人员将使用的资源,它可以立即发送任务以说“此生产者负责这些数据”。生产者将动态生成的任务推送到队列中。各种工人从队列中弹出并执行。如果工作程序失败,则另一个工作程序在超时后选择相同的任务。当工人完成时,它存储其结果然后向所有生产者发布“任务ID完成”。 (稍后将详细介绍)如果工作人员需要额外的用户输入,则会存储其会话,然后向所有生产者发布“任务ID需要更多信息”。假设生产者的一个工人要求更多信息(通过订阅接收)并且生产者仍然有客户端连接,它打包并将数据请求发送到客户端,该客户端结束与生产者的HTTP连接。生产者现在解锁请求令牌,因为它没有连接。其他工作人员可能仍处于这种“无头”状态,但同一生产者可能仍会向队列发出更多任务,因为其他工作人员完成任务并满足依赖关系。 (只要客户端仍然没有重新连接到任何生产者)现在当客户端重新建立HTTP连接时,它可能不会重新连接到同一个生产者。因此,接收连接的生产者发布给其他生产者“我得到了令牌X的恢复客户端连接”。这将告诉任何其他生产者可能仍然锁定资源并发出新任务以停止处理工作人员结果和发布新任务。然后,这个具有客户端连接的新生产者将锁定请求令牌以及将由现在未阻止的工作人员使用的资源。 (以及处理积压的工作人员结果,如果有的话)生产者确定新客户信息可以解除阻止的依赖关系,并开始发出更多任务,直到所有工作完成。然后捆绑结果,保存到Postgres,在S3中存档并将最终响应发送给客户端。
这让我陷入困境。我可以将Redis用于我的所有四个简单要求,但是我听说如果主要版本失败,集群很容易丢失写入。另外因为我总是需要新数据,所以我的工人和生产者都不能从奴隶那里读书。所以我真的要使用Redis集群复制到热备用。 (没有分片要求)
更复杂但更安全的替代方案似乎是使用RabbitMQ进行“pub / sub”的排队和主题交换。使用Aerospike进行数据交换和互斥锁定。
我在使用NodeJS时遇到了错误的经验,而且Python过去能够保持与RabbitMQ的稳定AMQP连接,这让我很难再次尝试。 (这个替换的系统使用Redis + RabbitMQ)但我 真的 就像只使用Redis一样简单。
那么你们是否认为我可以安全地使用AWS Elasticache Redis集群而不必担心如果主服务器失败可能会丢失写入或读取陈旧数据?或者你认为使用RabbitMQ + Aerospike的复杂性增加会更容错并且让我长期头痛吗?
提前致谢并花时间阅读那段文字。