Parallel processing 跟踪消息队列中的因果关系

Parallel processing 跟踪消息队列中的因果关系,parallel-processing,architecture,rabbitmq,queue,amqp,Parallel Processing,Architecture,Rabbitmq,Queue,Amqp,我正在开发一个系统,在这个系统中,我必须处理多条消息,但要保持这些消息的部分顺序。我有一个RabbitMQ队列,其中包含两种类型的消息:项创建和项更新 假设我们有一个包含6条消息的队列: CREATE1 CREATE2 UPDATE1 UPDATE2 UPDATE1 UPDATE1 如果我一个接一个地处理它们,那就完全可以了,但是速度非常慢,因为我有很多消息 如果我将它们读入某个缓冲区,那么我可以并行处理它们,但我可以处理第一个尚未创建的项的UPDATE1。更糟糕的是,上一次更新可能在上一次

我正在开发一个系统,在这个系统中,我必须处理多条消息,但要保持这些消息的部分顺序。我有一个RabbitMQ队列,其中包含两种类型的消息:项创建和项更新

假设我们有一个包含6条消息的队列:

CREATE1 CREATE2 UPDATE1 UPDATE2 UPDATE1 UPDATE1
  • 如果我一个接一个地处理它们,那就完全可以了,但是速度非常慢,因为我有很多消息

  • 如果我将它们读入某个缓冲区,那么我可以并行处理它们,但我可以处理第一个尚未创建的项的
    UPDATE1
    。更糟糕的是,上一次更新可能在上一次更新之前处理,因此会删除最新的项目状态

我可以在消息中创建一些额外的字段,或将其放入带有一些额外标题的队列中,例如
消息ID:10
,以确保一个项目的所有消息都具有相同的
消息ID
。问题是我不知道该怎么处理它

如何在不破坏消息之间的因果关系的情况下一次从队列读取多个项目


我认为这个任务的伪代码可能是:

const prefetchItemsCount = 20
let buffer = new Message[prefetchItemsCount]
let set = new Set()
foreach item in queue
    if !set.Contains(item.MessageId)
         set.Add(item.MessageId)
         buffer.Add(item)
         if set.Count == buffer.Count
             break
return buffer
因此,在我们的示例中,它将返回以下项目序列:

CREATE1 CREATE2
UPDATE1 UPDATE2
UPDATE1
UPDATE1
这使得它几乎快了一倍

如何一次从队列中读取多个项目,而不破坏消息之间的因果关系

真是个好案子

如果确实以期望的方式执行,“立即”的时域奇异性主要与表示为“因果关系”的隐藏形态相违背

与队列入口端一起给出,根据定义,它是一个纯的-
[SERIAL]
(任何事情都不可能同时发生,只是一个纯的一个接着一个,即使是“just”
[CONCURENT]
调度可能暴露于外部代理,内部队列管理遵循消息内部流和传递的纯顺序(也参考时间戳、持久性和其他人工制品)

因果关系还意味着一些事件的
因果关系
顺序,无论是在关系的抽象因果关系意义上,还是在事情实际发生的实时流程中,因此实际上是一种反模式“立即

最后,但并非最不重要的一点是,因果关系还必须处理另一个范例,即
原因->
->效应
之间的延迟(通常Finite-State-Automata,通常比一系列事件具有更丰富的状态空间

结果如何

虽然人们可以使用某种程度的进程调度来“读取”,但FSA/因果关系条件主要避免移动到传递的事件消息的主要纯后处理之外

如果消息传递框架没有代理,并且没有保证对丢失的消息/消息排序/消息真实性/消息内容的健壮性,那么更多的需求就会出现


在那里,魔鬼开始与您尝试构建一致、分布式事务处理、健壮、分布式FSA:o)的尝试作对。

请参见编辑。当我想并行预取时,我添加了我想象的内容,但没有破坏因果关系。