跨多个不同地理区域的 Rails/Mongo

跨多个不同地理区域的 Rails/Mongo

我有一个系统,该系统必然需要在三个或更多不同的位置进行物理存在,我需要一些建议,以便我的数据库能够及时复制,而不会出现可怕的延迟。当应用服务器尝试与未物理共置的节点通信时,我发现 mysql 访问和复制速度非常慢。在这种情况下,我使用的是 mongodb。

  • 堆栈是linux/passenger/ruby/rails/mongodb。
  • 数据库写入繁重,读取较少。
  • 基础设施是 Amazon EC2
  • 应用层必须物理上位于 3 个或更多不同的位置。我无法进一步证明这一要求是合理的,因为它是一项要求。但是,如果可以从其他位置快速写入数据库,则数据库不需要位于多个位置。

从阅读 mongo 的文档来看,mongo 复制似乎比分片更适合,因为我的数据存储区并不大。但是,我没有看到任何可以解决服务器远距离通信速度问题的方法,因为这些服务器可能存在高延迟。

答案1

您的延迟体验有些令人担忧。在我自己对本地快速网络的测试中,我注意到 Mongo 和 MySQL 在延迟方面存在一些差异:

  • 对于小项目,MySQL 请求往返时间通常低于 5 毫秒。有时低至 2。
  • MongoDB 请求 RTT 大约慢 3 倍,约为 15 毫秒。

MongoDB 时间的一部分是由于 TCP 连接设置时间,而 MySQL 使用的是预先存在的(池化)连接。在这两种情况下,数据库都没有被复制或分片,因此这些可以被认为是最佳情况(对于我的网络而言)。

Mongo 副本集可以在这里为您提供帮助,但前提是您的应用程序能够容忍松散收敛1。为了实现最大速度,您必须将 mongo 写入配置为仅在 mongodb 服务器报告已收到写入时返回,并将您的应用服务器配置为仅使用 AZ-local Mongo 实例。读取将需要使用 SlaveOK,以便它们可以从该 AZ-local 副本读取,这将显示本地写入以及迄今为止已收敛的其他节点的复制写入。这意味着每个 AZ 对整个数据库的视图都会略有不同;过去 X 分钟只会有本地更改,但深度历史记录将会收敛。

此设置将在应用服务器和数据库服务器之间提供较低的(相同可用区)延迟。但是,应用服务器的数据视图将根据应用消费者访问的可用区而有所不同。此架构是否适合您的应用程序只能由您决定。

但是,这样做有一个非常大的问题:MongoDB 不支持多主2复制,所有写入都必须发送到单个 Master。

目前(v2.2)无法配置 MongoDB 以允许写入从属服务器,因此“写入繁重”应用程序中的所有写入都必须转到副本集的单个主服务器。您没有提到读取延迟是否是一个问题,但如果是,那么 SlaveOK 读取将要抓住本地 Mongo 副本成员;但与上面不同的是,它可能尚未收到来自主服务器的所有更新,因此在写入提交和显示本地从服务器之间肯定会存在滞后。

Mongo 有几种不同的写入类型。默认情况下,Mongo 服务器一旦完全收到写入,就会返回 OK。下一步是仅在将写入提交到日志时才返回 OK 的模式。最偏执的(因此是具有副本的 Mongo 中最慢的)是仅在以下情况下才返回 OK指定数量的副本报告写入其日志中。默认模式是最快的,但是最后一种模式可以确保本地副本具有写入(严格一致性)。

如果该主服务器与应用服务器不在同一个可用区中,那么即使采用默认的写入方式,延迟也可能对您来说是无法承受的。如果是这种情况,mongo 将无法为你工作,因为你的应用程序现在存在. 您将必须认真思考如何改变您的应用程序以降低写入时的延迟敏感度,或者使用可以进行松散收敛的多主非 Mongo 数据库。

Mongo 最接近多主配置的方式是通过分片。如果您的应用服务器知道其地理位置,则可以将地理位置数据包含在 Mongo Shard-Key 中。然后,当您连接到 MongoS 进行写入时,所有写入都会转到本地分片的副本集。读取可以轮询整个数据库(从非本地分片中提取时会相应地变慢),因此这将保持一致性。但是,这完全取决于位置是否是您的分片键。


1:松散融合,分布式或复制数据库达到统一状态的时间就是收敛时间。松散收敛间隔较长。紧密收敛间隔较短。2
多主控,一个可以接受多个副本的数据库。可以执行此操作的数据库示例包括 Active Directory、OpenLDAP 和一些 MySQL 配置。

相关内容