MongoDB在多个AWS实例中进行负载平衡

时间:2014-07-10 07:55:01

标签: mongodb amazon-web-services amazon-ec2 load-balancing database

我们正在将amazon Web服务用于使用node.js服务器和mongodb作为数据库的业务应用程序。目前,node.js服务器正在EC2媒体实例上运行。我们将mongodb数据库保存在一个单独的微实例中。现在我们想在我们的mongodb数据库中部署副本集,这样如果mongodb被锁定或不可用,我们仍然可以运行我们的数据库并从中获取数据。

因此,我们试图将副本集的每个成员保留在不同的实例中,这样即使主要成员的实例关闭,我们也可以从数据库中获取数据。

现在,我想在数据库中添加负载均衡器,这样即使在一次巨大的流量负载下数据库也能正常工作。在这种情况下,我可以通过在replicaSet中添加slaveOK配置来读取数据库的平衡。但是,如果数据库中的写操作存在巨大的流量负载,它就不会对数据库进行负载平衡。

为了解决这个问题,到目前为止我有两个选择。

选项1:我要对数据库进行分片并将每个分片保存在单独的实例中。在每个分片下,将在同一个实例中设置一个reaplica。但是存在一个问题,因为分片将数据库分成多个部分,因此每个分片都不会在其中保留相同的数据。因此,如果一个实例关闭,我们将无法从该实例中的分片访问数据。

为了解决这个问题,我试图在分片中划分数据库,每个分片在不同的实例中都有一个replicaSet。因此,即使一个实例关闭,我们也不会遇到任何问题。但是如果我们有2个分片并且每个分片在replicaSet中有3个成员,那么我需要6个aws实例。所以我认为这不是最佳解决方案。

选项2:我们可以在mongodb中创建一个主 - 主配置,这意味着所有数据库都是主数据库,并且所有数据库都具有读/写访问权限,但我也希望它们每次都能自动同步。经常,所以他们最终都成为彼此的克隆。所有这些主要数据库都将在不同的实例中。但我不知道mongodb是否支持这种结构。

我没有针对这种情况获得任何mongodb doc / blog。所以,请建议我应该解决这个问题的最佳解决方案。

2 个答案:

答案 0 :(得分:5)

到目前为止,这不是一个完整的答案,有太多的细节,我可以像其他许多人一样写一篇关于这个问题的整篇文章,因为我没有那么多的时间,我会添加一些关于我所看到的评论。

  

现在,我想在数据库中添加负载均衡器,这样即使在一次巨大的流量负载下数据库也能正常工作。

副本集的设计并非如此。如果你想加载平衡,你实际上可能正在寻找分片,这将允许你这样做。

复制用于自动故障转移。

  

在这种情况下,我可以通过在replicaSet中添加slaveOK config来读取数据库的平衡。

因为,为了保持最新状态,您的成员将获得与初级操作一样多的操作,似乎这可能没有太大帮助。

实际上,不是让一台服务器有多个连接排队,而是在许多服务器上排队等待陈旧数据的连接很多,因为成员一致性是最终的,不像ACID技术那样直接,但是,据说它们最终只有32-一致奇数ms,这意味着如果主要加载,它们不会滞后以提供适当的吞吐量。

由于读取是并发的,无论您是从主要还是次要读取,都将获得相同的速度。我想你可以延迟一个奴隶来创建一个暂停的OP,但这会带回大量过时的数据。

更不用说MongoDB不是多主机了,你只能写一个节点一次使slaveOK不再是世界上最有用的设置而且我已经看过很多次10gen自己建议你使用分片结束这个设置。

  

选项2:我们可以在mongodb中创建主 - 主配置,

这需要您自己编码。此时您可能需要考虑实际使用支持http://en.wikipedia.org/wiki/Multi-master_replication

的数据库

这是因为你正在寻找的速度很可能实际上是在写入而不是如上所述的读取。

  

选项1:我要对数据库进行分片并将每个分片保存在单独的实例中。

这是推荐的方式,但你已经发现了它的警告。遗憾的是,多主复制应该解决的问题尚未解决,但是,多主复制确实会将自己的瘟疫大鼠添加到欧洲本身,我强烈建议您在考虑之前是否进行了一些认真的研究。 MongoDB目前无法满足您的需求。

你可能真的不担心,因为fsync队列旨在处理IO瓶颈,这会减慢你的写入速度,因为它会在SQL中并且读取是并发的,所以如果你计划你的架构和工作设置,你应该能够得到大量的OP。

事实上,这里有一个关联的问题来自10gen员工,非常好阅读:https://stackoverflow.com/a/17459488/383478它显示了MongoDB在负载下可以实现的吞吐量。

随着新文档级锁定已经在dev分支中,它将很快成长。

答案 1 :(得分:1)

选项1是@Sammaye指出的推荐方式,但您不需要6个实例,可以使用4个实例进行管理。

假设您需要以下配置。

  • 2个分片(S1,S2)
  • 每个分片1个副本(副本集辅助)(RS1,RS2)
  • 每个碎片的1个仲裁器(RA1,RA2)

然后您可以将服务器配置划分如下。

Instance 1 : Runs : S1 (Primary Node)
Instance 2 : Runs : S2 (Primary Node)
Instance 3 : Runs : RS1 (Secondary Node S1) and RA2 (Arbiter Node S2)
Instance 4 : Runs : RS2 (Secondary Node S2) and RA1 (Arbiter Node S1)

您可以与辅助节点一起运行仲裁节点,这有助于您在故障转移期间进行选举。