如何配置 MongoDB 副本集

MongoDB 已经成为市面上最知名的 NoSQL 数据库。MongoDB 是面向文档的,它的无模式设计使得它在各种各样的WEB 应用当中广受欢迎。最让我喜欢的特性之一是它的副本集(Replica Set),副本集将同一数据的多份拷贝放在一组 mongod 节点上,从而实现数据的冗余以及高可用性。

如何配置 MongoDB 副本集

这篇教程将向你介绍如何配置一个 MongoDB 副本集。

副本集的最常见配置需要一个主节点以及多个副节点。这之后启动的复制行为会从这个主节点到其他副节点。副本集不止可以针对意外的硬件故障和停机事件对数据库提供保护,同时也因为提供了更多的节点从而提高了数据库客户端数据读取的吞吐量。

 

配置环境

这个教程里,我们会配置一个包括一个主节点以及两个副节点的副本集。

如何配置 MongoDB 副本集

为了达到这个目的,我们使用了3个运行在 VirtualBox 上的虚拟机。我会在这些虚拟机上安装 Ubuntu 14.04,并且安装 MongoDB 官方包。

我会在一个虚拟机实例上配置好所需的环境,然后将它克隆到其他的虚拟机实例上。因此,选择一个名为 master 的虚拟机,执行以下安装过程。

首先,我们需要给 apt 增加一个 MongoDB 密钥:

  1. <span class="pln">$ sudo apt</span><span class="pun">-</span><span class="pln">key adv </span><span class="pun">--</span><span class="pln">keyserver hkp</span><span class="pun">:</span><span class="com">//keyserver.ubuntu.com:80 --recv 7F0CEB10</span>

然后,将官方的 MongoDB 仓库添加到 source.list 中:

  1. <span class="pln">$ sudo su</span>
  2. <span class="com"># echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list</span>

接下来更新 apt 仓库并且安装 MongoDB。

  1. <span class="pln">$ sudo apt</span><span class="pun">-</span><span class="kwd">get</span><span class="pln"> update</span>
  2. <span class="pln">$ sudo apt</span><span class="pun">-</span><span class="kwd">get</span><span class="pln"> install </span><span class="pun">-</span><span class="pln">y mongodb</span><span class="pun">-</span><span class="pln">org</span>

现在对 /etc/mongodb.conf 做一些更改

  1. <span class="pln">auth </span><span class="pun">=</span><span class="kwd">true</span>
  2. <span class="pln">dbpath</span><span class="pun">=</span><span class="str">/var/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">mongodb</span>
  3. <span class="pln">logpath</span><span class="pun">=</span><span class="str">/var/</span><span class="pln">log</span><span class="pun">/</span><span class="pln">mongodb</span><span class="pun">/</span><span class="pln">mongod</span><span class="pun">.</span><span class="pln">log</span>
  4. <span class="pln">logappend</span><span class="pun">=</span><span class="kwd">true</span>
  5. <span class="pln">keyFile</span><span class="pun">=</span><span class="str">/var/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">mongodb</span><span class="pun">/</span><span class="pln">keyFile</span>
  6. <span class="pln">replSet</span><span class="pun">=</span><span class="pln">myReplica</span>

第一行的作用是表明我们的数据库需要验证才可以使用。keyfile 配置用于 MongoDB 节点间复制行为的密钥文件。replSet 为副本集设置一个名称。

接下来我们创建一个用于所有实例的密钥文件。

  1. <span class="pln">$ echo </span><span class="pun">-</span><span class="pln">n </span><span class="str">"MyRandomStringForReplicaSet"</span><span class="pun">|</span><span class="pln"> md5sum </span><span class="pun">></span><span class="pln"> keyFile</span>

这将会创建一个含有 MD5 字符串的密钥文件,但是由于其中包含了一些噪音,我们需要对他们清理后才能正式在 MongoDB 中使用。

  1. <span class="pln">$ echo </span><span class="pun">-</span><span class="pln">n </span><span class="str">"MyReplicaSetKey"</span><span class="pun">|</span><span class="pln"> md5sum</span><span class="pun">|</span><span class="pln">grep </span><span class="pun">-</span><span class="pln">o </span><span class="str">"[0-9a-z]\+"</span><span class="pun">></span><span class="pln"> keyFile</span>

grep 命令的作用的是把将空格等我们不想要的内容过滤掉之后的 MD5 字符串打印出来。

现在我们对密钥文件进行一些操作,让它真正可用。

  1. <span class="pln">$ sudo cp keyFile </span><span class="pun">/</span><span class="kwd">var</span><span class="pun">/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">mongodb</span>
  2. <span class="pln">$ sudo chown mongodb</span><span class="pun">:</span><span class="pln">nogroup keyFile</span>
  3. <span class="pln">$ sudo chmod </span><span class="lit">400</span><span class="pln"> keyFile</span>

接下来,关闭此虚拟机。将其 Ubuntu 系统克隆到其他虚拟机上。

如何配置 MongoDB 副本集

这是克隆后的副节点1和副节点2。确认你已经将它们的MAC地址重新初始化,并且克隆整个硬盘。

如何配置 MongoDB 副本集

请注意,三个虚拟机示例需要在同一个网络中以便相互通讯。因此,我们需要它们弄到“互联网"上去。

这里推荐给每个虚拟机设置一个静态 IP 地址,而不是使用 DHCP。这样它们就不至于在 DHCP 分配IP地址给他们的时候失去连接。

像下面这样编辑每个虚拟机的 /etc/networks/interfaces 文件。

在主节点上:

  1. <span class="kwd">auto</span><span class="pln"> eth1</span>
  2. <span class="pln">iface eth1 inet </span><span class="kwd">static</span>
  3. <span class="pln">address </span><span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.2</span>
  4. <span class="pln">netmask </span><span class="lit">255.255</span><span class="pun">.</span><span class="lit">255.0</span>

在副节点1上:

  1. <span class="kwd">auto</span><span class="pln"> eth1</span>
  2. <span class="pln">iface eth1 inet </span><span class="kwd">static</span>
  3. <span class="pln">address </span><span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.3</span>
  4. <span class="pln">netmask </span><span class="lit">255.255</span><span class="pun">.</span><span class="lit">255.0</span>

在副节点2上:

  1. <span class="kwd">auto</span><span class="pln"> eth1</span>
  2. <span class="pln">iface eth1 inet </span><span class="kwd">static</span>
  3. <span class="pln">address </span><span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.4</span>
  4. <span class="pln">netmask </span><span class="lit">255.255</span><span class="pun">.</span><span class="lit">255.0</span>

由于我们没有 DNS 服务,所以需要设置设置一下 /etc/hosts 这个文件,手工将主机名称放到此文件中。

在主节点上:

  1. <span class="lit">127.0</span><span class="pun">.</span><span class="lit">0.1</span><span class="pln"> localhost primary</span>
  2. <span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.2</span><span class="pln"> primary</span>
  3. <span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.3</span><span class="pln"> secondary1</span>
  4. <span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.4</span><span class="pln"> secondary2</span>

在副节点1上:

  1. <span class="lit">127.0</span><span class="pun">.</span><span class="lit">0.1</span><span class="pln"> localhost secondary1</span>
  2. <span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.2</span><span class="pln"> primary</span>
  3. <span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.3</span><span class="pln"> secondary1</span>
  4. <span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.4</span><span class="pln"> secondary2</span>

在副节点2上:

  1. <span class="lit">127.0</span><span class="pun">.</span><span class="lit">0.1</span><span class="pln"> localhost secondary2</span>
  2. <span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.2</span><span class="pln"> primary</span>
  3. <span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.3</span><span class="pln"> secondary1</span>
  4. <span class="lit">192.168</span><span class="pun">.</span><span class="lit">50.4</span><span class="pln"> secondary2</span>

使用 ping 命令检查各个节点之间的连接。

  1. <span class="pln">$ ping primary</span>
  2. <span class="pln">$ ping secondary1</span>
  3. <span class="pln">$ ping secondary2</span>

 

配置副本集

验证各个节点可以正常连通后,我们就可以新建一个管理员用户,用于之后的副本集操作。

在主节点上,打开 /etc/mongodb.conf 文件,将 auth 和 replSet 两项注释掉。

  1. <span class="pln">dbpath</span><span class="pun">=</span><span class="str">/var/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">mongodb</span>
  2. <span class="pln">logpath</span><span class="pun">=</span><span class="str">/var/</span><span class="pln">log</span><span class="pun">/</span><span class="pln">mongodb</span><span class="pun">/</span><span class="pln">mongod</span><span class="pun">.</span><span class="pln">log</span>
  3. <span class="pln">logappend</span><span class="pun">=</span><span class="kwd">true</span>
  4. <span class="com">#auth = true</span>
  5. <span class="pln">keyFile</span><span class="pun">=</span><span class="str">/var/</span><span class="pln">lib</span><span class="pun">/</span><span class="pln">mongodb</span><span class="pun">/</span><span class="pln">keyFile</span>
  6. <span class="com">#replSet=myReplica</span>

在一个新安装的 MongoDB 上配置任何用户或副本集之前,你需要注释掉 auth 行。默认情况下,MongoDB 并没有创建任何用户。而如果在你创建用户前启用了 auth,你就不能够做任何事情。你可以在创建一个用户后再次启用 auth。

修改 /etc/mongodb.conf 之后,重启 mongod 进程。

  1. <span class="pln">$ sudo service mongod restart</span>

现在连接到 MongoDB master:

  1. <span class="pln">$ mongo </span><span class="pun"><</span><span class="pln">master</span><span class="pun">-</span><span class="pln">ip</span><span class="pun">-</span><span class="pln">address</span><span class="pun">>:</span><span class="lit">27017</span>

连接 MongoDB 后,新建管理员用户。

  1. <span class="pun">></span><span class="kwd">use</span><span class="pln"> admin</span>
  2. <span class="pun">></span><span class="pln"> db</span><span class="pun">.</span><span class="pln">createUser</span><span class="pun">({</span>
  3. <span class="pln">user</span><span class="pun">:</span><span class="str">"admin"</span><span class="pun">,</span>
  4. <span class="pln">pwd</span><span class="pun">:</span><span class="str">"</span>
  5. <span class="str">})</span>

重启 MongoDB:

  1. <span class="pln">$ sudo service mongod restart</span>

再次连接到 MongoDB,用以下命令将 副节点1 和副节点2节点添加到我们的副本集中。

  1. <span class="pun">></span><span class="kwd">use</span><span class="pln"> admin</span>
  2. <span class="pun">></span><span class="pln"> db</span><span class="pun">.</span><span class="pln">auth</span><span class="pun">(</span><span class="str">"admin"</span><span class="pun">,</span><span class="str">"myreallyhardpassword"</span><span class="pun">)</span>
  3. <span class="pun">></span><span class="pln"> rs</span><span class="pun">.</span><span class="pln">initiate</span><span class="pun">()</span>
  4. <span class="pun">></span><span class="pln"> rs</span><span class="pun">.</span><span class="pln">add </span><span class="pun">(</span><span class="str">"secondary1:27017"</span><span class="pun">)</span>
  5. <span class="pun">></span><span class="pln"> rs</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(</span><span class="str">"secondary2:27017"</span><span class="pun">)</span>

现在副本集到手了,可以开始我们的项目了。参照 官方驱动文档 来了解如何连接到副本集。如果你想要用 Shell 来请求数据,那么你需要连接到主节点上来插入或者请求数据,副节点不行。如果你执意要尝试用副本集操作,那么以下错误信息就蹦出来招呼你了。

  1. <span class="pln">myReplica</span><span class="pun">:</span><span class="pln">SECONDARY</span><span class="pun">></span>
  2. <span class="pln">myReplica</span><span class="pun">:</span><span class="pln">SECONDARY</span><span class="pun">></span><span class="pln"> show databases</span>
  3. <span class="lit">2015</span><span class="pun">-</span><span class="lit">05</span><span class="pun">-</span><span class="lit">10T03</span><span class="pun">:</span><span class="lit">09</span><span class="pun">:</span><span class="lit">24.131</span><span class="pun">+</span><span class="lit">0000</span><span class="pln"> E QUERY </span><span class="typ">Error</span><span class="pun">:</span><span class="pln"> listDatabases failed</span><span class="pun">:{</span><span class="str">"note"</span><span class="pun">:</span><span class="str">"from execCommand"</span><span class="pun">,</span><span class="str">"ok"</span><span class="pun">:</span><span class="lit">0</span><span class="pun">,</span><span class="str">"errmsg"</span><span class="pun">:</span><span class="str">"not master"</span><span class="pun">}</span>
  4. <span class="pln">at </span><span class="typ">Error</span><span class="pun">()</span>
  5. <span class="pln">at </span><span class="typ">Mongo</span><span class="pun">.</span><span class="pln">getDBs </span><span class="pun">(</span><span class="pln">src</span><span class="pun">/</span><span class="pln">mongo</span><span class="pun">/</span><span class="pln">shell</span><span class="pun">/</span><span class="pln">mongo</span><span class="pun">.</span><span class="pln">js</span><span class="pun">:</span><span class="lit">47</span><span class="pun">:</span><span class="lit">15</span><span class="pun">)</span>
  6. <span class="pln">at shellHelper</span><span class="pun">.</span><span class="pln">show </span><span class="pun">(</span><span class="pln">src</span><span class="pun">/</span><span class="pln">mongo</span><span class="pun">/</span><span class="pln">shell</span><span class="pun">/</span><span class="pln">utils</span><span class="pun">.</span><span class="pln">js</span><span class="pun">:</span><span class="lit">630</span><span class="pun">:</span><span class="lit">33</span><span class="pun">)</span>
  7. <span class="pln">at shellHelper </span><span class="pun">(</span><span class="pln">src</span><span class="pun">/</span><span class="pln">mongo</span><span class="pun">/</span><span class="pln">shell</span><span class="pun">/</span><span class="pln">utils</span><span class="pun">.</span><span class="pln">js</span><span class="pun">:</span><span class="lit">524</span><span class="pun">:</span><span class="lit">36</span><span class="pun">)</span>
  8. <span class="pln">at </span><span class="pun">(</span><span class="pln">shellhelp2</span><span class="pun">):</span><span class="lit">1</span><span class="pun">:</span><span class="lit">1</span><span class="pln"> at src</span><span class="pun">/</span><span class="pln">mongo</span><span class="pun">/</span><span class="pln">shell</span><span class="pun">/</span><span class="pln">mongo</span><span class="pun">.</span><span class="pln">js</span><span class="pun">:</span><span class="lit">47</span>

如果你要从 shell 连接到整个副本集,你可以安装如下命令。在副本集中的失败切换是自动的。

  1. <span class="pln">$ mongo primary</span><span class="pun">,</span><span class="pln">secondary1</span><span class="pun">,</span><span class="pln">secondary2</span><span class="pun">:</span><span class="lit">27017</span><span class="pun">/?</span><span class="pln">replicaSet</span><span class="pun">=</span><span class="pln">myReplica</span>

如果你使用其它驱动语言(例如,JavaScript、Ruby 等等),格式也许不同。

希望这篇教程能对你有所帮助。你可以使用Vagrant来自动完成你的本地环境配置,并且加速你的代码。

MongoDB 的详细介绍:请点这里
MongoDB 的下载地址:请点这里


via: How to set up a Replica Set on MongoDB

作者:Christopher Valerio 译者:mr-ping 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

相关推荐