mongodb - MongoClient 连接到多个主机以处理故障转移?
问题描述
我有一个非常简单的 PyMongo 配置,它连接到两个主机:
from pymongo import MongoClient
host = os.getenv('MONGODB_HOST', '127.0.0.1')
port = int(os.getenv('MONGODB_PORT', 27017))
hosts = []
for h in host.split(','):
hosts.append('{}:{}'.format(h, port))
cls.client = MongoClient(host=hosts, replicaset='replicatOne')
MONGODB_HOST
由两个ip组成的列表,如“primary_mongo,secondary_mongo”
它们被配置为复制集。
我注意到的问题是,在当前配置中,如果secondary_mongo
出现故障,我的整个代码将停止工作。
我相信提供主机列表MongoClient
会告诉它“使用有效的主机,从第一个开始”,但它似乎不正确。
出了什么问题,我如何确保MongoClient
正确连接到primary_mongo
第一个,如果它失败,转到secondary_mongo
?
谢谢您的帮助。
解决方案
为了有一个完全运行的 MongoDB ReplicaSet,你必须有一个 PRIMARY 成员。只有当所有成员中的大多数都可用时,才能选出 PRIMARY。2 个中的 1 个不是大多数,因此如果一个节点发生故障,您的 MongoDB ReplicaSet 就会关闭。
当您连接到 MongoDB 时,您可以连接到 ReplicaSet,例如
mongo "mongodb://localhost:27037,localhost:27137,localhost:27237/?replicaSet=repSet"
或者您直接连接,例如
mongo "mongodb://localhost:27037,localhost:27137"
当您连接到 ReplicaSet 并且 PRIMARY 出现故障(或者当它出于任何原因降级到 SECONDARY 时)并且另一个成员成为 PRIMARY 时,通常客户端会自动重新连接到新的 PRIMARY。但是,连接到 ReplicaSet 需要一个 PRIMARY 成员,即大多数成员必须可用。
当您直接连接时,您还可以连接到 SECONDARY 成员并以只读模式使用 MongoDB。但是,如果连接的成员出现故障,您将没有任何故障转移/重新连接功能。
您可以在您的一个节点上创建一个 ARBITER 成员。然后,如果另一个节点出现故障,应用程序仍然完全可用。请记住,通过这种设置,您只能丢失“第二个”主机,但不能丢失其中任何一个。在最好的情况下,您可以在独立的第三个位置配置 ARBITER。
来自MongoDB:Shannon Bradshaw、Eoin Brazil、Kristina Chodorow 的权威指南:第三部分 - 复制,第 9 章 - 设置副本集:
如何设计一套
要规划您的集合,您必须熟悉某些副本集概念。下一章会更详细地介绍这些,但最重要的是副本集都是关于多数的:你需要多数成员来选举主节点,主节点只有达到多数才能保持主节点,并且当写入被复制到多数时,写入是安全的。这个多数被定义为“超过集合中所有成员的一半”,如表 9-1 所示。
集合中的成员数 | 大部分集合 |
---|---|
1 | 1 |
2 | 2 |
3 | 2 |
4 | 3 |
5 | 3 |
6 | 4 |
7 | 4 |
请注意,有多少成员关闭或不可用并不重要,因为大多数成员是基于集合的配置。
例如,假设我们有一个 5 成员集,并且有 3 个成员下降,如图 9-1 所示。还有两个成员。这两个成员无法达到集合的多数(至少三个成员),因此他们无法选举主节点。如果其中一个是主要的,它会在注意到它无法达到多数时立即下台。几秒钟后,您的集合将包含两个辅助节点和三个无法访问的成员。
许多用户对此感到沮丧:为什么剩下的两个成员不能选举一个初选?问题是其他三个成员可能没有宕机,是网络宕机了,如图9-2所示。在这种情况下,左边的三个成员将选出一个主要成员,因为他们可以达到集合的多数(五分之三)。
在网络分区的情况下,我们不希望分区的两边都选举一个主节点:否则该集合将有两个主节点。然后两个主节点都在写入数据,数据集会发散。要求多数人选举或保持初选是避免最终获得多个初选的一种巧妙方法。
以您通常能够拥有一个主要的方式配置您的集合非常重要。例如,在上述五人组中,如果成员 1、2 和 3 位于一个数据中心,而成员 4 和 5 位于另一个数据中心,则第一个数据中心几乎总是可用的多数(更多数据中心之间的网络中断可能比它们内部的中断)。
推荐阅读
- angular - 在 angular7 中,如何从 2 个不同的依赖 http 调用中获得组合响应。第一个 http 调用返回一个对象数组和其他相关数据
- node.js - 节点 - 中间件未应用 req 属性
- python - python中对二维列表元素的内存引用是否连续?
- while-loop - 如何在从文件 B 读取值时剪切文件 A 的每第 n 行?
- go - 缩短 || 或者 Golang 中的 if 语句
- mongodb - 猫鼬放松
- javascript - 如何在更改屏幕尺寸等时让我的 Web 应用程序响应更快?
- optimization - 确定为什么visual studio优化了一个功能?
- javascript - 打字时的 DOM 操作在 iPad 上不起作用但在 iPhone 上起作用
- google-cloud-platform - 安全的 Cloud Run 服务仅接受来自浏览器中域的请求(而不是 Postman / shell 脚本)