6

我目前正在编写一个 Node 应用程序,并且正在考虑扩展。据我了解,水平扩展是扩展应用程序以处理更多并发请求的更简单方法之一。我的工作副本目前在后端使用 MongoDb。

因此,我的问题是:我有一个类似于链表的数据结构,需要严格维护顺序。我(想象中的)担心的是,当通过多个节点实例对数据库存在竞争条件时,链表的解析可能会不正确。

举个例子:想象一下服务器有这个列表 a->b。实例 1 与对象 c 一起出现,实例 2 与对象 d 一起出现。可能存在竞争条件,其中两个实例都读取 a->b 并决定将自己的对象附加到列表中。然后实例 1 会认为它的插入是 a->b->c,而实例 2 认为它是 a->b->d,而数据库实际保存的是 a->b->c->d。

一般来说,这听起来像是乐观锁定的工作,但是,据我了解,MongoDB 或 Redis(我正在考虑的另一个数据库)都不会以 SQL 方式进行事务。

因此,我认为解决方案是以下之一:

  1. 使用标志在 MongoDB 中实现我自己的事务。客户端对锁变量执行 findAndModify,如果成功,则执行操作。如果不成功,客户端会在特定超时后重试。

  2. 使用 Redis 事务和 pubsub 可以达到相同的效果。我还不完全确定如何做到这一点,但听起来它可能是合理的。

  3. 实施某种智能负载平衡。如果多个客户端对同一个项目进行操作,请将它们路由到同一个实例。由于JS是单线程的,所以问题就解决了。不幸的是,我没有找到一个简单的解决方案。

我确信存在一种更好、更优雅的方式来实现上述目标,我很想听听任何解决方案或建议。谢谢!

4

3 回答 3

0

您希望 mongodb 上的 findAndModify 命令在返回新修改的文​​档时保证原子修改。由于更改是串行的,原子实例 1 将具有 a->b->c,而实例 2 将具有 a->b->c->d

干杯

于 2012-05-07T07:41:14.600 回答
0

如果我理解正确,并且列表被存储为一个文档,那么您可能正在查看行版本控制。因此,向将处理版本的文档添加一个属性,当您更新时,您会增加(或更改)版本并进行有条件的更新:

//更新(条件,值)

更新({版本:whateverYouReceivedWhenYouDidFind},newValue)

希望能帮助到你。格斯

于 2012-05-24T17:42:05.120 回答
0

如果您所做的只是向列表中添加新元素,则可以使用 Redis 列表并将时间包含在您添加的每个值中。该列表可能在 redis 上未排序,但在检索时应该可以快速排序。

于 2012-05-07T15:38:50.190 回答