【问题标题】:Mongodb cluster and reading from secondary when primary is downMongodb集群并在主节点关闭时从辅助节点读取
【发布时间】:2017-12-09 21:04:31
【问题描述】:

这不是仅仅询问 mongo 集群的基本问题。我认为这不是重复的 我有一个 mongodb 3 节点集群,我的 url 在 PlayFramework conf 文件中如下所示

mongodb.uri = "mongodb://mongodb1:27017,mongodb2:27017,mongodb3:27017/myproj"

默认情况下,配置副本时,所有读取和写入都只发生在主节点上,这就是我想要的。但是,我希望在没有主节点时读取到辅助节点,即当 2 个节点关闭时,不会有主节点,只有一个辅助节点。

我不想修改我的代码来为每个读取查询实现这一点。我在辅助节点上尝试了以下操作,但没有帮助

db.getMongo().setReadPref('primaryPreferred')

我需要做些什么才能完成这项工作?

【问题讨论】:

  • 如果“三个”节点中的“两个”出现故障,那么在进一步干预之前,副本集将根本无法用于操作。整个主题有大量的手册部分。索引于Replication
  • 不完全正确。副本集不会同意主要是,我知道。二级将仍然存在。如果我盲目地标记 rs.slaveOK(),我仍然可以读取它,但我不想这样做。我希望剩余的次要仅在没有主要时才允许读取
  • 从您的“应用程序代码”的角度来看,这是真的。该主题的其他所有内容都需要 DBA 干预。因此成为更适合dba.stackexchange.com 的问题,因为这与应用程序代码无关。以类似的方式,您也可以手动“提升”剩余节点。但同样,DBA 问题。 “代码”的答案是“它不应该关心”。
  • 要么你不清楚我在问什么,要么我需要重新表达我的问题。目的不是使用手动干预,而是使用 ?readPreference=secondary&maxStalenessSeconds=
  • 你被告知你不能。您“必须”手动干预。怎么这么难理解?您应该关注的真正事情是首先不要让大多数节点停机。

标签: mongodb mongodb-query


【解决方案1】:

我不想修改我的代码来为每个读取查询实现这一点。我在辅助节点上尝试了以下操作,但没有帮助:

db.getMongo().setReadPref('primaryPreferred')

您的阅读偏好设置正确,但需要在您的连接字符串或驱动程序中进行设置。在mongo shell 中设置读取首选项只会影响当前的 shell 会话,对远程连接没有影响。

mongodb.uri = "mongodb://mongodb1:27017,mongodb2:27017,mongodb3:27017/myproj"

您需要根据MongoDB的Connecting String URI Format添加一些额外的参数:

  • (必需)replicaSet=... 选项指示驱动程序应使用“副本集”连接模式,而不是默认的直接连接模式。此参数启用副本集监控、读取首选项和拓扑更改发现。提供的副本集名称必须与为您的部署配置的 replica set name 匹配。有关官方支持的 MongoDB 驱动程序预期的连接行为的完整详细信息,请参阅Server Discovery and Monitoring (SDAM) 规范。规范的rationale 部分包含对所选方法的常见问题的解答。
  • (必需)readPreference=primaryPreferred 选项表示首选从主数据库读取,但如果没有可用的主数据库,则使用辅助数据库。
  • (可选)在 MongoDB 3.4+ 中,您可以指定 maxStalenessSeconds=... 选项,以限制使用辅助读取首选项时的最大复制延迟(或陈旧性)。默认情况下,没有最大陈旧性,因此驱动程序在根据读取首选项选择辅助节点时不会考虑复制延迟。如果您打算使用primaryPreferred 作为读取的故障转移选项,我会谨慎设置最大陈旧性:您需要确保至少有一个具有可接受陈旧性的辅助节点。

因此,假设副本集名称为 mongocluster,数据库为 myproj,建议的连接字符串为:

mongodb://mongodb1:27017,mongodb2:27017,mongodb3:27017/mypr‌oj?replicaSet=‌mongocluster&readPreference=primaryPreferred

【讨论】:

  • 嗨@Stennie,我在我的游戏日志中看到了这个,这是否意味着我不走运? reactivemongo.api.MongoDriver - 一些选项被忽略,因为它们不受支持(还):replicaSet 另外,我尝试阅读链接以了解为什么真的需要replicaSet,但不是很清楚为什么。无论哪种方式,我都会假设您的建议是强制性的,但游戏框架是否忽略了它?
  • @curiousengineer 您使用的是什么 MongoDB 驱动程序和版本,Play Framework 的版本是什么?关于副本集连接,区别在于驱动程序如何发现和监控拓扑。 SDAM 规范读起来很重要,但在高层次上,连接拓扑分为三类(独立、副本集或分片)。如果没有replicaSet 参数,您通常会以Standalone 模式连接到指定的第一个主机(即没有发现或监控副本集配置,也不支持读取首选项)。
  • 我使用的是 Mongodb 3.4(docker 容器镜像)。我的播放版本是 addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.10") 所以我猜它是 2.5.10 当你说 Mongodb 驱动版本时,我不知道我怎么知道那。但是由于我们使用响应式 mongo,因此这里是那个 "org.reactivemongo" %% "play2-reactivemongo" % "0.12.0" 的依赖项
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-10
相关资源
最近更新 更多