如何在UbuntuVPS上的MongoDB中实现复制集
状态: 已弃用
本文介绍了不再受支持的 Ubuntu 版本。 如果您当前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议您升级或迁移到受支持的 Ubuntu 版本:
原因: Ubuntu 12.04 已于 2017 年 4 月 28 日终止生命周期 (EOL) and no longer receives security patches or updates. This guide is no longer maintained.
请参阅: 本指南可能仍可用作参考,但可能不适用于其他 Ubuntu 版本。 如果可用,我们强烈建议使用为您正在使用的 Ubuntu 版本编写的指南。 您可以使用页面顶部的搜索功能来查找更新的版本。
介绍
MongoDB 是一个非常流行的 NoSQL 数据库。 它通常用于存储和管理应用程序数据和网站信息。 MongoDB 拥有动态模式设计、易于扩展和易于以编程方式访问的数据格式。
在本指南中,我们将讨论如何设置数据复制以确保数据的高可用性并创建强大的故障转移系统。 这在数据库出现故障会对您的组织或业务产生负面影响的任何生产环境中都很重要。
我们将假设您已经在系统上安装了 MongoDB。 有关 如何在 Ubuntu 12.04 上安装 MongoDB 的信息,请单击此处。
什么是 MongoDB 复制集?
MongoDB 通过称为“复制集”的实现来处理复制。 基本形式的复制集有点类似于主从配置中的节点。 单个主要成员用作将更改应用于次要成员的基础。
复制集和主从复制之间的区别在于,复制集具有内在的自动故障转移机制,以防主成员不可用。
主成员:主成员是复制集事务的默认访问点。 它是唯一可以接受写操作的成员。
每个复制集一次只能有一个主要成员。 这是因为复制是通过复制主节点的“oplog”(操作日志)并在辅助节点的数据集上重复更改而发生的。 多个接受写操作的原色会导致数据冲突。
次要成员:一个复制集可以包含多个次要成员。 次要成员根据自己的数据从 oplog 复制更改。
尽管默认情况下应用程序会查询主要成员的读取和写入操作,但您可以将设置配置为从一个或多个次要成员中读取。 如果主要成员离线或退出,次要成员可以成为主要成员。
注意:由于数据是异步传输的,从辅助节点读取可能会导致提供旧数据。 如果这是您的用例所关心的问题,则不应启用此功能。
Arbiter:仲裁器是复制集的可选成员,不参与实际复制过程。 它被添加到复制设置中,仅参与一个有限的功能:在选举中充当打决犯。
如果主要成员不可用,则会在辅助节点之间进行自动选举过程以选择新的主要成员。 如果辅助成员池包含偶数个节点,这可能导致由于投票僵局而无法选出新的主成员。 仲裁者在这些情况下投票以确保做出决定。
如果复制集只有一个辅助成员,则需要仲裁器。
次要成员自定义选项
在某些情况下,您可能不希望所有次要成员都受制于复制集的标准规则。 一个复制集最多可以有 12 个成员,在选举情况下最多有 7 个成员投票。
优先级 0 复制成员
在某些情况下,将某些集合成员选为主要位置可能会对应用程序的性能产生负面影响。
例如,如果您正在将数据复制到远程数据中心,或者特定成员的硬件不足以作为该集合的主要访问点,则将优先级设置为 0 可以确保该成员不会成为主要成员,但可以继续复制数据。
隐藏的复制成员
在某些情况下,您需要将客户可访问和可见的主要成员集与具有不同目的且不应干扰的背景成员分开。
例如,您可能需要一个辅助成员作为分析工作的基础,这将受益于最新的数据集,但会对工作成员造成压力。 通过将此成员设置为隐藏,它不会干扰复制集的一般操作。
隐藏成员必须设置为优先级 0 以避免成为主要成员,但他们确实在选举中投票。
延迟复制成员
通过设置次要成员的延迟选项,您可以控制次要等待执行从主要操作日志复制的每个操作的时间。
如果您想防止意外删除或从破坏性操作中恢复,这很有用。 例如,如果您将辅助服务器延迟半天,它不会立即对其自己的数据集执行意外操作,并且可以用于恢复更改。
延迟成员不能成为主要成员,但可以在选举中投票。 在绝大多数情况下,它们应该被隐藏以防止进程读取过时的数据。
如何配置复制集
为了演示如何配置复制集,我们将配置一个包含一个主节点和两个从节点的简单集。 这意味着您将需要三个 VPS 实例来跟进。 我们将使用 Ubuntu 12.04 机器。
您将需要在将成为该集合成员的每台机器上安装 MongoDB。 您可以按照本教程学习 如何在 Ubuntu 12.04 上安装 MongoDB。
在所有三个服务器实例上安装 MongoDB 后,我们需要配置一些允许我们的 Droplet 相互通信的东西。
以下步骤假设您以 root 用户身份登录。
设置 DNS 解析
为了让我们的 MongoDB 实例能够有效地相互通信,我们需要配置我们的机器来为每个成员解析正确的主机名。 您可以通过 为每个复制成员 配置子域或通过编辑每台计算机上的 /etc/hosts
文件来完成此操作。
从长远来看,使用子域可能会更好,但为了快速起步,我们将通过 hosts 文件来做到这一点。
在每个即将复制的成员上,编辑 /etc/hosts
文件:
nano /etc/hosts
在配置 localhost 的第一行之后,您应该为每个复制集成员添加一个条目。 这些条目采用以下形式:
IP地址 mongohost0.example.com
您可以在 DigitalOcean 控制面板中获取您的集合成员的 IP 地址。 您选择作为该计算机主机名的名称是任意的,但应该是描述性的。
对于我们的示例,我们的 /etc/hosts
看起来像这样:
127.0.0.1 本地主机mongo0 123.456.789.111 mongo0.example.com 123.456.789.222 mongo1.example.com 123.456.789.333 mongo2.example.com
这个文件应该(大部分)在你的集合中的所有主机上都是相同的。 保存并关闭每个成员的文件。
接下来,您需要设置 Droplet 的主机名以反映这些新更改。 每个 VPS 上的命令将反映您在 /etc/hosts
文件中为该特定机器指定的名称。 您应该在每台服务器上发出一个命令,如下所示:
主机名mongo0.example.com
在每台服务器上修改此命令以反映您在文件中为其选择的名称。
编辑 /etc/hostname
文件以反映这一点:
纳米 /etc/主机名
mongo0.example.com
这些步骤应该在每个节点上执行。
在 MongoDB 配置文件中准备复制
开始 MongoDB 配置我们需要做的第一件事是停止每台服务器上的 MongoDB 进程。
在每台服务器上,键入:
service mongodb stop
现在,我们需要配置一个用于存储数据的目录。 使用以下命令创建目录:
mkdir /mongo-metadata
现在我们已经创建了数据目录,我们可以修改配置文件以反映我们新的复制集配置:
nano /etc/mongodb.conf
在这个文件中,我们需要指定一些参数。 首先,调整dbpath
变量指向我们刚刚创建的目录:
dbpath=/mongo-metadata
去掉端口号规范前面的注释,确保在默认端口上启动:
port = 27017
在文件的底部,删除 replSet
参数前面的注释形式。 将此变量的值更改为您易于识别的值。
replSet = rs0
最后,您应该创建进程 fork,以便在生成服务器实例后使用您的 shell。 将此添加到文件的底部:
fork = true
保存并关闭文件。 通过发出以下命令启动复制成员:
mongod --config /etc/mongodb.conf
必须在复制集的每个成员上重复这些步骤。
启动复制集并添加成员
现在您已经配置了复制集的每个成员并在每台机器上启动了 mongod
进程,您可以启动复制并添加每个成员。
在您的一个成员上,键入:
mongo
这将为您提供当前成员的 MongoDB 提示。
通过输入以下命令启动复制集:
rs.initiate()
这将启动复制集并将您当前连接的服务器添加为该集的第一个成员。 您可以通过键入以下内容来查看:
rs.conf()
{ "_id" : "rs0" "version" : 1, "members" : [ { "_id" : 0, "host" "mongo0.example.com:27017" } ] }
现在,您可以通过引用您在 /etc/hosts
文件中提供的主机名将其他节点添加到复制集中:
rs.add("mongo1.example.com")
{ "ok" : 1 }
对每个剩余的复制成员执行此操作。 您的复制集现在应该已启动并正在运行。
结论
通过为每个数据存储目标正确配置复制集,您的数据库将在一定程度上受到保护,免受不可用和硬件故障的影响。 这对于任何生产系统都是必不可少的。
复制集提供了与应用程序的无缝接口,因为它们对外部基本上是不可见的。 所有复制机制都在内部处理。 如果您计划实现 MongoDB 分片,最好为每个分片服务器组件实现复制集。