1

我正在使用大规模分布式元胞自动机开发模拟。单元模拟分布在节点之间,并使用 ZooKeeper 进行协调。持久性数据存储在 Riak 中。元胞自动机本身是用 Python 编写的。

如果一个单元可以将少量(例如每秒几到几十个)消息(可能是键值对)传递给它的直接邻居(曼哈顿社区),这对我的模拟将非常方便。然而,对于数百万个单元格的模拟,天真的方法最终会产生数百万个小邮箱,每个单元格一个,并且缓慢地将消息涓涓细流到每个盒子中。这让 ZooKeeper 或 RabbitMQ 屈服了!有人推荐我 DDS,但它似乎非常企业化,而且我找不到任何 Python 绑定。

我是分布式系统开发的新手——这实际上只是一个爱好项目,看看我能走多远。我不禁觉得我走错了路,为每个小单元的邮箱转向了一个单一的消息总线。一个细胞很容易确定它的邻居和它在世界上的位置,所以看起来消息传递应该容易受到某种分块的影响。然而,这个区域演员的设计以及它如何与单个细胞进行交流却让我无法理解。我看到单元如何通过消息总线将消息传递给块,但是块如何将消息传递回单元?

我是否正在接近这个问题的真正解决方案?分布式节点将少量消息传递给其邻居的正确方法是什么?

4

2 回答 2

1

我不确定您需要这些消息的持久性;根据您的描述,您似乎对来自不同单元格的消息没有任何排序限制。我认为您确实希望对从同一单元格 a 发送到同一单元格 b 的所有消息进行总排序。

ZooKeeper 被淹没了,因为它提供了所有消息的全局总排序。我不确定您的系统需要通过 Zookeeper 进行哪种类型的协调,但它最适合粗粒度的协调,而不是细粒度的协调。(在我工作的地方,我们分别称之为角色锁定和资源锁定以阐明意图。工作人员承担角色而不是锁定资源。)

所以,这里有一些关于我所掌握信息的想法。

如果消息不需要持久,最好的方法是保持与邻居的连接并将消息直接发送给他们。我假设是 2D 或 3D,所以(曼哈顿)邻居的数量很少。

其余的将假设您需要耐用性。

单个消息队列系统应该能够处理数百万条消息;但如果对它们进行一些分区,它们会获得更好的性能。

首先,尝试将所有消息发送到同一个队列。让一些工作人员(由 ZooKeeper 选择)将消息从队列中拉出并将它们发送到它们的目标单元(在确认队列之前需要单元的确认)。您还可以让一组工作人员接收来自单元的消息以放入队列中。基本上,这有助于解决队列中的争用。

[  Router ]--->[ Queue ]--->[  Router  ]
 ^   ^   ^                   |   |   |
 |   |   |                   V   V   V
[A] [B] [C]                 [D] [E] [F]

现在您可以概括一下,并为每个区域设置一个队列。(当需要处理的消息较少时,队列会更好地工作。)每个区域有一个或多个路由器。

        ,----->[ QueueA ]<------.
        |                       |   (Note which arrows are bi-directional)
        V                       |
[ RouterA ]--->[ QueueB ]<--->[ RouterB ]
 ^   ^   ^                     ^   ^   ^
 |   |   |                     |   |   |
 V   V   V                     V   V   V
[A] [B] [C]                   [D] [E] [F]

如果消息系统仍然被淹没,您可以将上图中的队列替换为整个消息队列系统

这些是一些简单的想法,不知道实际的领域,希望能为您指明一个好的方向。

顺便说一句,您可能想研究 Twitter 的架构(过去和现在),因为它们基本上有数百万个邮箱,每个邮箱对应一个元胞自动机(也称为人)。

于 2013-03-16T06:04:00.343 回答
0

我正在玩弄的一个想法:

我在几个地方读到过有人使用 ZooKeeper 作为内部系统的 DNS 的替代品。由于模拟工作进程已经向 ZooKeeper 注册了他们负责的单元模拟,我想注册一个他们将响应的 IP 和端口,然后使用 ZeroMQ 设置单元之间的 P2P 消息传递应该不会太远。这仍然是一个粗略的草图。

于 2013-03-17T21:37:49.030 回答