怎样创建 MongoDB 副本集

介绍

在任务关键型应用程序中部署 MongoDB 数据库时,您可以配置副本集以实现高可用性。 副本集提供冗余和高可用性,从而减少了灾难期间的停机时间,因为没有单点故障。 MongoDB 副本集的最低推荐配置是一个主节点和两个辅助节点,但副本集最多可以有 50 个成员。 您的应用程序仅写入主节点,辅助节点复制数据。 如果主节点发生故障,副本集将举行选举以选择新的主节点。 应用程序可以从辅助节点读取数据,但不能写入它们。

本指南介绍了怎样创建 MongoDB 副本集。 它在 Ubuntu 20.04 上进行了测试,但其他 Linux 发行版的步骤类似。

先决条件

您需要将三台服务器连接到同一个 Vultr VPC。 每台服务器都应该有:

  • 非 root 用户配置为 sudo 特权
  • MongoDB 安装并使用密码保护

  • 为清楚起见,本指南为服务器使用以下主机名和私有 IP 地址。 你应该用你的价值观代替这些。

    • 基本的: 服务器 1 – 10.0.0.1
    • 次要: 服务器 2 – 10.0.0.2
    • 次要: 服务器 3 – 10.0.0.3

1.配置主机文件

MongoDB 建议对副本成员使用 DNS 主机名而不是 IP 地址。 因为 Vultr VPC 是一个没有 DNS 的私有网络,所以将私有 IP 地址和主机名添加到 hosts 文件中。 在每台服务器上重复这些步骤。

  1. 以非 root 用户身份通过​​ SSH 连接到服务器。
  2. 编辑主机文件。

    $ sudo nano /etc/hosts
    
  3. 找到下面的行。

    127.0.0.1 localhost
    
  4. Enter 该行下显示的 IP 地址和主机名。

    127.0.0.1 localhost
    10.0.0.1 server-1
    10.0.0.2 server-2
    10.0.0.3 server-3
    
  5. Save 和 close 文件。

2.设置复制密钥

副本集中的所有服务器共享一个 base64 密钥。 请按照以下步骤安装密钥。

使用 openssl 命令在其中一台服务器上生成新密钥。

$ openssl rand -base64 756

你应该得到一个像这样的块。 复制此 base64 密钥。 您将在以下步骤中使用它。

Yga80PbkHKptRRoONFCPaPzOCFpySgpwNHMA3JS179wyGCOIOYg/FUnDyiIhGe5D
YVQF3o+SliscBiKftsPZ5WBojRREcefAUHOqK7pVBOjT+oYuH6ltMGiDtH26XjVB
... truncated ...
yxJm+UjpN0n8V1pH1LrMJT4FC4Bw3L7vqSnxVbLRnQIiO2Y0ECfyPgepCCNIyuaP
mMSUJ8mmlq4jdfoAKvCspeliSQ/cqaxKfqaTWjzhsLk8eHbU

在每台服务器上重复这些步骤。

  1. 创建一个新的 auth_key 文件。

    $ sudo nano /var/lib/mongodb/auth_key
    
  2. 粘贴您的 base64 密钥。

  3. Save 和 close 文件。
  4. 将权限设置为 400,使文件所有者对文件只读,对所有其他人拒绝访问。

    $ sudo chmod 400 /var/lib/mongodb/auth_key
    
  5. 将所有者和组更改为 mongodb.

    $ sudo chown mongodb:mongodb /var/lib/mongodb/auth_key
    

3.配置MongoDB

在本节中,您将配置共享密钥、网络接口和副本集名称。 在每台服务器上重复这些子部分。

3.1。 配置共享密钥

  1. 打开 mongod.conf 在编辑器中执行以下步骤。

    $ sudo nano /etc/mongod.conf
    
  2. 找出 安全 部分。

    security:
      authorization: enabled
    #operationProfiling:
    
  3. 以下 授权: 行,添加 密钥文件 如图所示。

    security:
      authorization: enabled
      keyFile: /var/lib/mongodb/auth_key
    #operationProfiling:
    

3.2. 配置网络接口

  1. 找出 网络接口 部分。

    # network interfaces
    net:
      port: 27017
      bindIp: 127.0.0.1
    
  2. 在每个服务器的环回接口 (127.0.0.1) 之后添加相应的服务器名称。 为了 example:

    在服务器 1 上:

    # network interfaces
    net:
      port: 27017
      bindIp: 127.0.0.1, server-1
    

    在服务器 2 上:

    # network interfaces
    net:
      port: 27017
      bindIp: 127.0.0.1, server-2
    

    在服务器 3 上:

    # network interfaces
    net:
      port: 27017
      bindIp: 127.0.0.1, server-3
    

3.3. 配置副本集名称

  1. 找出 复制 部分。

    #replication:
    
  2. 从复制行中删除 # 注释。 在此之下,添加 replSetName: "rs0" 如图所示。

    replication:
      replSetName: "rs0"
    
  3. 在主节点上重新启动 MongoDB。

    $ sudo systemctl restart mongod
    
  4. 在辅助节点上重新启动 MongoDB。

    $ sudo systemctl restart mongod
    

4. 引导副本集

在本节中,您会将节点添加到副本集并引导复制过程。

  1. 在主节点上登录 MongoDB。

    $ mongosh -u your_admin_name -p --authenticationDatabase admin
    
  2. Enter 您的密码 admin 帐户并按 ENTER 继续。

  3. 运行以下命令添加副本集成员。

    test> rs.initiate(
          {
          _id: "rs0",
          members: [
              { _id: 0, host: "server-1" },
              { _id: 1, host: "server-2" },
              { _id: 2, host: "server-3" }
              ]
          })
    
  4. 当副本集启动时,您应该得到以下响应。 注意提示更改为 rs0 [direct: secondary] test>.

    { ok: 1 }
    rs0 [direct: secondary] test>
    
  5. 创建示例 公司数据库 数据库。

    rs0 [direct: secondary] test> use company_db
    
  6. 您应该得到以下响应并且提示更改为 rs0 [direct: primary] company_db>. 该成员现在是主节点。

    switched to db company_db
    rs0 [direct: primary] company_db>
    
  7. 将示例记录插入新的 雇员 集合中 公司数据库 数据库。

    rs0 [direct: primary] company_db> db.employees.insertOne({   
                                      "staff_id" : 1,
                                      "staff_name" : "JOHN DOE",
                                      "phone" : "11111111"  
                                      })
    
  8. 你应该得到下面的输出。

    {
      acknowledged: true,
      insertedId: ObjectId("621dcf1abdb5b0c5e59294d9")
    }
    
  9. 在每个辅助节点上登录 MongoDB。

    $ mongosh -u your_admin_name -p --authenticationDatabase admin
    
  10. Enter 您的密码 admin 帐户并按 ENTER 继续。

  11. 您应该会看到下面的提示,显示成员是辅助节点。

    rs0 [direct: secondary] test>
    
  12. 在每个辅助节点上,切换到 公司数据库.

    rs0 [direct: secondary] test> use company_db
    
  13. 您应该得到以下输出。

    switched to db company_db
    
  14. 在每个辅助节点上运行以下命令,允许它们接受读取命令。

    rs0 [direct: secondary] company_db> db.getMongo().setReadPref('primaryPreferred')
    
  15. 列出从 雇员 收藏。

    rs0 [direct: secondary] company_db> db.employees.find()
    
  16. 您应该在每个辅助节点上获得以下输出,这表明副本集将数据复制到每个节点。

    [
      {
        _id: ObjectId("621dcf1abdb5b0c5e59294d9"),
        staff_id: 1,
        staff_name: 'JOHN DOE',
        phone: '11111111'
      }
    ]
    
  17. 尝试在任何辅助节点上添加新员工记录。

    rs0 [direct: secondary] company_db> db.employees.insertOne({   
                                      "staff_id" : 2,
                                      "staff_name" : "MARY ROE",
                                      "phone" : "22222222"  
                                      })
    
  18. 该命令应该失败。 辅助节点是只读的。

    MongoServerError: not primary
    
  19. 如果您停止主服务器或它下线,则副本集会选择一个辅助节点作为新的主节点。

    $ sudo systemctl stop mongod
    

更多资源

为了应用程序的可靠性和数据恢复,请始终考虑 MongoDB 实例的复制。 如果您的 MongoDB 副本集按预期工作,您可以在 MongoDB 文档复制部分.

您还需要考虑怎样在客户端应用程序中处理故障转移。 如解释 在文档中

如果操作因网络错误而失败,则会引发 ConnectionFailure,并且客户端会在后台重新连接。

注:本教程在Vultr VPS上测试通过,如需部署请前往Vultr.com