为啥 MongoDB 配置服务器必须只有一个或三个?

Posted

技术标签:

【中文标题】为啥 MongoDB 配置服务器必须只有一个或三个?【英文标题】:Why MongoDB config servers must be one or three only?为什么 MongoDB 配置服务器必须只有一个或三个? 【发布时间】:2013-04-20 08:48:55 【问题描述】:

在阅读了 MongoDB 分片架构的官方文档后,我还没有发现为什么你需要一个或三个配置服务器,而不是另一个数字。

MongoDB documentation on Config Servers 说:

“如果一个或两个配置服务器不可用,集群的元数据将变为只读。您仍然可以从分片读取和写入数据,但在所有三个服务器都可用之前不会发生块迁移或拆分。”

因此反思:一台服务器相当于单点故障,但两台服务器的行为与三台服务器相同,对吧?

那么,为什么绝对是三个服务器,而不是两个或更多?

因为文档还说:

配置服务器不作为副本集运行。

【问题讨论】:

注意:我最初发布了一个答案,说这是因为副本集的投票行为,但删除它是因为 MongoDB 配置服务器似乎不作为副本集运行。 @sephiroth66,你可能想编辑你的帖子,以防万一其他人有同样的想法。 【参考方案1】:

配置服务器协议

MongoDB 3.0 及更早版本仅支持单一类型的配置服务器部署协议,该协议在 MongoDB 3.2 中称为旧版 SCCC(同步集群连接配置)。 SCCC 部署有 1 个配置服务器(仅限开发)或 3 个配置服务器(生产)。

MongoDB 3.2 弃用了 SCCC 协议并支持新的部署类型:将服务器配置为副本集 (CSRS)。 CSRS 部署与标准副本集具有相同的限制,在 MongoDB 3.2 中可以有 1 个配置服务器(仅限开发)或多达 50 个服务器(生产)。建议至少使用 3 个 CSRS 服务器以在生产部署中实现高可用性,但额外的服务器可能对地理分布的部署有用。

SCCC(同步集群连接配置)

使用 SCCC,配置服务器使用 two-phase commit 协议进行更新,该协议需要多个服务器的共识才能进行交易。您可以将单个配置服务器用于测试/开发目的,但在生产使用中您应该始终拥有 3 个。为什么不能在 MongoDB 中仅使用 2 个(或超过 3 个)服务器的一个实际答案是 MongoDB 代码库 支持 1 或 3 个配置服务器用于 SCCC 配置。

三台服务器比两台服务器提供更强的一致性保证,并允许在一台配置服务器上进行维护活动(例如备份),同时仍有两台服务器可供您的mongos 查询。超过三台服务器会增加跨所有服务器提交数据所需的时间。

分片集群的元数据需要在所有配置服务器中保持一致,并由 MongoDB 分片实现维护。元数据包括当前哪些分片保存一系列文档的基本细节(又名chunks)。在 SCCC 配置中,配置服务器不是副本集,因此如果一个或多个配置服务器离线,则配置数据将是只读的 - 否则无法将数据传播到离线配置服务器恢复在线时。

显然 1 个配置服务器不提供冗余或备份。对于 2 台配置服务器,潜在的故障情况是服务器可用但服务器上的数据不一致(例如,其中一台服务器有一些数据损坏)。使用 3 台配置服务器,您可以改进之前的场景:2/3 台服务器可能是一致的,您可以识别出奇怪的服务器。

CSRS(配置服务器作为副本集)

MongoDB 3.2 不赞成使用三个镜像的 mongod 实例作为配置服务器,并且从 3.2 开始,配置服务器(默认情况下)部署为副本集。副本集配置服务器必须使用 WiredTiger 3.2+ 存储引擎(或其他支持新的readConcern 读取隔离语义的存储引擎)。 CSRS 还禁止某些不适合分片集群元数据用例的非默认副本集配置选项(例如 arbiterOnlybuildIndexesslaveDelay)。

CSRS 部署提高了配置服务器的一致性和可用性,因为 MongoDB 可以利用标准副本集读取和写入协议来分片配置数据。此外,这允许分片集群拥有超过 3 个配置服务器,因为副本集最多可以有 50 个成员(如 MongoDB 3.2)。

在 CSRS 部署中,写入可用性取决于维持可以查看副本集当前主节点的成员法定人数。例如,一个 3 节点副本集将需要 2 个可用成员来维护一个主节点。可以添加其他成员以改进fault tolerance,但与普通副本集相同的election rules。 majorityreadConcernmongos 使用,以确保分片集群元数据只有在提交给大多数副本集成员后才能读取,并且 nearestreadPreference 用于将请求路由到最近的配置服务器。

【讨论】:

所以据我了解,配置服务器是一个单点故障,在 3.2 之前的 MongoDB 中我们无能为力,因为那里不支持 4+ .对还是错? 你是说配置服务器应该单独在一个实例上,然后我们为它创建副本? mongos 呢,它们应该在单个实例上吗? @LiviuChircu 配置服务器不是单点故障。使用 SCCC,您应该始终在生产部署中拥有 3 台服务器;使用 CSRS,您至少有 3 个配置服务器,但总共最多可以添加 50 个。只要您至少有 1 台配置服务器在线,您的分片集群仍然可用于读/写数据访问。使用 SCCC,所有 3 台服务器都必须处于健康状态才能提交对分片集群元数据的更改(例如,块拆分/迁移或新的分片集合);使用 CSRS,大多数投票配置服务器都需要健康。 @Lamar 配置服务器通常部署在单独的实例上,与 SCCC 或 CSRS 配置无关。根据手册中的Sharded Cluster 概述,mongos 进程通常与应用程序服务器位于同一位置。为了进一步讨论,我建议发布一个新问题,因为 cmets 很容易错过。有关如何设置配置服务器和新分片集群的教程,请参阅您的 MongoDB 版本的文档中的 Deploy a Sharded Cluster。

以上是关于为啥 MongoDB 配置服务器必须只有一个或三个?的主要内容,如果未能解决你的问题,请参考以下文章

mongodb--选举失败

[Database] MongoDB 副本集配置

MongoDB:即使查询的所有字段都被索引,为啥我的扫描对象值很高?

为啥在 mongodb 中没有更新 system.profile 集合?

为啥垃圾被添加到我的 mongodb 中?

为啥垃圾被添加到我的 mongodb 中?