我不确定这样的设计问题是否适用于此,但根据https://meta.stackexchange.com/questions/41469/is-there-a-stack-overflow-for-design-questions,它并非完全不受限制。
在我的系统中,我有许多节点可以下载大文件并对其进行处理。每个文件都由唯一标签标识。基于该标签,节点可以构建适当的URL并下载相应的文件。文件随时间(通常)发生变化,因此节点必须连续下载并继续处理。
在我目前的架构中,我有不同的标签集(不重叠)分配给不同的节点。但这不是一个理想的解决方案,因为文件的大小会发生变化,因此工作并不总是均匀分布。处理容错也更复杂,因为我需要为每个处理节点进行热备份以进行故障转移。
我考虑的一个可能的解决方案是拥有标签的队列(FIFO),每个节点将从头部获取标签,进行处理,然后将其返回到队列的末尾。 该解决方案解决了工作分配均匀的问题,但又引入了容错的另一个问题。如果节点在处理过程中出现故障,那么我们会丢失标签,这在此特定系统中是不可接受的。现在我们可以有一个监视队列内容的进程,如果它有所有标签的话。
但我正在寻找一种更优雅和完善的解决方案,可以解决工作分配和容错问题,而不会在这个特定系统中产生太多复杂性。有什么想法吗?
答案 0 :(得分:0)
我将继续使用队列方法,但通过确认机制添加容错,例如您在Amazon SQS(请参阅here)或{{3}中找到的机制(见RabbitMQ,"消息确认)。
这个想法是当消费者从队列中提取项目时,该项目不会从队列中删除。只有在消费者确认成功处理该项目后,才会从队列中删除它。如果消费者提取物品并且没有确认某段规定的时间,则该消息因为在队列中再次可用,而另一消费者将处理该消息。
请注意,这可能会产生两次处理相同消息的情况。还行吧。如果你处理动作是幂等的(即两次动作产生与一次动作相同的结果),但如果它不是,那么你需要添加自定义保护来处理这种情况。
简而言之,如果您关注可靠性,请使用上述可用的可靠队列服务之一。