我对Celery/AMQP还很陌生,正在尝试提出一个任务/队列/工作程序设计来满足以下要求。
我有多种类型的"每用户"任务:例如,任务A、任务B、任务C。这些"每个用户"任务中的每一个都为系统中的一个特定用户读取/写入数据。因此,在任何给定的时间,我可能需要创建任务User1_TaskA、User1_TaskB、User1_TaskC、User2_TaskA、User2_TaskB等。我需要确保,对于每个用户,没有任何任务类型的两个任务同时执行。我想要一个系统,在该系统中,任何工作人员都不能在执行User1_TaskB或User1_TaskC的同时执行User1_TaskA,但当User1_TaskA正在执行时,不应阻止其他工作人员同时执行User2_TaskA、User3_TaskA等。
我意识到这可以使用某种外部锁定机制(例如,在DB中)来实现,但我希望有一个更优雅的任务/队列/工作者设计可以工作。
我想一个可能的解决方案是将队列实现为用户bucket,这样,当worker启动时,就会有一个config指定要创建多少bucket,并且每个"bucket worker"都绑定到一个bucket。然后,一个"中间工作者"会从主任务队列中提取任务,并通过散列/mod方案将它们分配到带区块的队列中。因此,UserA的任务总是在同一个队列中结束,而UserA的多个任务将相互备份。我不喜欢这种方法,因为它需要提前定义bucket的数量,而且似乎可以(轻松地)动态添加工人。在我看来,肯定有更好的方法——建议将不胜感激。
使用外部锁定机制有什么不好的地方?它足够简单、直接和高效。您可以在Celery中找到分布式任务锁定的示例。通过为每个用户创建一个锁来扩展它,就完成了!