(消息传递)队列如何可扩展?
How can (messaging) queue be scalable?
我经常在软件架构中看到队列,尤其是那些被称为 "scalable" 的队列,具有来自 Akka.io 多角色平台的 Actor 的突出代表。但是,如果我们必须同步将消息放入队列(因此在单线程与多线程中操作)并再次同步从队列中取出消息(以确保该消息恰好被取出一次),那么队列如何可扩展?它变得更加复杂,当这些消息可以改变(参与者)系统的状态时——在这种情况下,即使从队列中取出消息后,它也不能进行负载平衡,但仍然在单线程中处理。
- 消息入队列必须同步,对吗?
- 消息出队列是否必须同步?
- 如果 1 或 2 是正确的,那么队列如何扩展?同步到单线程不会立即造成瓶颈吗?
- 如果(参与者)系统是有状态的,它如何可扩展?
- statefull actor/bean 是否意味着我必须在单线程中按顺序处理消息?
- 全状态是否意味着每个整个系统我必须有一个 bean/actor 副本?
- 如果 6 为假,那么如何在实例之间共享此状态?
- 当我尝试将我的新 P2P 节点连接到网络时,我相信我必须有一些 "server" 会告诉我,谁是其他节点,这是正确的吗?当我尝试下载 torrent 时,我必须连接到跟踪器 - 如果有 "server" 那么我们称它为 P2P 吗?如果此跟踪器出现故障,那么我将无法连接到对等设备,对吗?
- 同步和全状态是否会破坏可伸缩性?
- Is it correct, that putting messages in queue must be synchronized?
- Is it correct, that putting messages out of queue must be synchronized?
没有
假设我们谈论的是 synchronized
java 关键字,那么这是对象上的可重入互斥锁。只要 contention 低,即使是多个线程访问该锁也可以很快。而且每个对象都有自己的锁,所以有很多锁,每个锁只需要很短的时间,即是细粒度锁定。
但即使有,也不需要通过互斥锁来实现队列。 Lock-free and even wait-free 存在队列数据结构。这意味着仅仅存在锁并不会自动暗示单线程执行。
您的其余问题应单独提出,因为它们与消息队列无关。
当然你是对的,因为单个队列是不可扩展的。 Actor 模型的要点是您可以拥有数百万个 Actors,因此可以将负载分布到数百万个队列上——如果您的集群中有这么多核心。永远记住 Carl Hewitt 所说的话:
One Actor is no actor. Actors come in systems.
每个单独的参与者都是一个完全顺序的单线程计算单元。不过,整个模型的构造使其非常适合描述分布;这意味着您可以根据需要创建尽可能多的演员。
我经常在软件架构中看到队列,尤其是那些被称为 "scalable" 的队列,具有来自 Akka.io 多角色平台的 Actor 的突出代表。但是,如果我们必须同步将消息放入队列(因此在单线程与多线程中操作)并再次同步从队列中取出消息(以确保该消息恰好被取出一次),那么队列如何可扩展?它变得更加复杂,当这些消息可以改变(参与者)系统的状态时——在这种情况下,即使从队列中取出消息后,它也不能进行负载平衡,但仍然在单线程中处理。
- 消息入队列必须同步,对吗?
- 消息出队列是否必须同步?
- 如果 1 或 2 是正确的,那么队列如何扩展?同步到单线程不会立即造成瓶颈吗?
- 如果(参与者)系统是有状态的,它如何可扩展?
- statefull actor/bean 是否意味着我必须在单线程中按顺序处理消息?
- 全状态是否意味着每个整个系统我必须有一个 bean/actor 副本?
- 如果 6 为假,那么如何在实例之间共享此状态?
- 当我尝试将我的新 P2P 节点连接到网络时,我相信我必须有一些 "server" 会告诉我,谁是其他节点,这是正确的吗?当我尝试下载 torrent 时,我必须连接到跟踪器 - 如果有 "server" 那么我们称它为 P2P 吗?如果此跟踪器出现故障,那么我将无法连接到对等设备,对吗?
- 同步和全状态是否会破坏可伸缩性?
- Is it correct, that putting messages in queue must be synchronized?
- Is it correct, that putting messages out of queue must be synchronized?
没有
假设我们谈论的是 synchronized
java 关键字,那么这是对象上的可重入互斥锁。只要 contention 低,即使是多个线程访问该锁也可以很快。而且每个对象都有自己的锁,所以有很多锁,每个锁只需要很短的时间,即是细粒度锁定。
但即使有,也不需要通过互斥锁来实现队列。 Lock-free and even wait-free 存在队列数据结构。这意味着仅仅存在锁并不会自动暗示单线程执行。
您的其余问题应单独提出,因为它们与消息队列无关。
当然你是对的,因为单个队列是不可扩展的。 Actor 模型的要点是您可以拥有数百万个 Actors,因此可以将负载分布到数百万个队列上——如果您的集群中有这么多核心。永远记住 Carl Hewitt 所说的话:
One Actor is no actor. Actors come in systems.
每个单独的参与者都是一个完全顺序的单线程计算单元。不过,整个模型的构造使其非常适合描述分布;这意味着您可以根据需要创建尽可能多的演员。