Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

将自管理副本集转换为分片集群

在此页面上

  • 关于此任务
  • 开始之前
  • 步骤
  • 了解详情

分片集群会根据 分片键在多个服务器上对数据分区。对于具有大数据集和高吞吐量操作的部署,分片集群可提供优于副本集的扩展性。

本教程将把单个三成员副本集转换为具有两个分片的分片集群。新集群中的每个分片均为一个独立的三成员副本集。

对于 MongoDB Atlas 中托管的部署,您可以 在用户界面中将其转换为分片集群

本教程使用以下服务器:

主机名
端口
说明
mongodb0.example.net
27017
承载数据的初始分片的成员 rs0
mongodb1.example.net
27017
承载数据的初始分片的成员 rs0
mongodb2.example.net
27017
承载数据的初始分片的成员 rs0
mongodb3.example.net
27018
第二个承载数据的分片的成员 rs1
mongodb4.example.net
27018
第二个承载数据的分片的成员 rs1
mongodb5.example.net
27018
第二个承载数据的分片的成员 rs1
mongodb6.example.net
27017
mongos,用于连接到分片集群。
mongodb7.example.net
27019
配置服务器副本集的成员。
mongodb8.example.net
27019
配置服务器副本集的成员。
mongodb9.example.net
27019
配置服务器副本集的成员。

本教程中使用的主机名均为示例。将示例命令中使用的主机名替换为您部署中使用的主机名。

重要

要避免因 IP 地址变更而更新配置,请使用 DNS 主机名而非 IP 地址。在配置副本集成员或分片集群成员时,使用 DNS 主机名而非 IP 地址尤为重要。

在水平分割网络配置下,请使用主机名而非 IP 地址来配置集群。从 MongoDB 5.0 开始,仅配置了 IP 地址的节点将无法通过启动验证,因而不会启动。

注意

从MongoDB 8.0开始,您只能在分片上运行某些命令。 如果您尝试直接连接到分分片并运行不受支持的命令, MongoDB将返回错误:

"You are connecting to a sharded cluster improperly by connecting directly
to a shard. Please connect to the cluster via a router (mongos)."

要直接对分片运行不支持的数据库命令,您必须连接到mongos或具有仅维护的directShardOperations角色。

1

要获取现有用户和角色,请运行 mongodump:

mongodump -d=admin --out=adminDump -u <adminUser> -p <password> --host <replicaSetURI> --dumpDbUsersAndRoles
2

为配置服务器部署一个三成员副本集。在此示例中,配置服务器使用以下主机:

  • mongodb7.example.net

  • mongodb8.example.net

  • mongodb9.example.net

  1. 配置配置服务器

    在每个配置服务器主机上配置一个 mongod 实例。在每个 mongod 实例的配置文件中指定以下选项:

    选项
    configReplSet
    configsvr
    localhost,然后是 mongod 应在其上侦听客户端连接的任何其他主机名。
    replication:
    replSetName: configReplSet
    sharding:
    clusterRole: configsvr
    net:
    bindIp: localhost,<hostname(s)>

    根据您的部署包含其他合适的选项。

  2. 启动配置服务器

    使用指定配置部署 mongod

    mongod --config <PATH_TO_CONFIG_FILE>

    配置服务器使用默认数据目录 /data/configdb 和默认端口 27019

  3. 连接到一台配置服务器。

    使用 mongosh 连接到其中一个配置服务器。例如:

    mongosh "mongodb://mongodb7.example.net:27019"
  4. 启动配置服务器副本集。

    要启动复制集,请运行 rs.initiate()

    rs.initiate( {
    _id: "configReplSet",
    configsvr: true,
    members: [
    { _id: 0, host: "mongodb7.example.net:27019" },
    { _id: 1, host: "mongodb8.example.net:27019" },
    { _id: 2, host: "mongodb9.example.net:27019" }
    ]
    } )

    前面的命令使用本地主机例外情况来执行管理操作,而不进行身份验证。

    重要

    仅在副本集的一个 mongod 实例上运行 rs.initiate()

3

恢复您在运行 mongodump 时获得的现有用户和角色。

mongorestore ./adminDump --nsInclude "admin.*" --host <configPrimaryURI>

前面的命令使用本地主机例外情况来执行管理操作,而不进行身份验证。

运行此命令的输出可能如下所示:

0 document(s) restored successfully

此消息并不表示存在问题。此输出意味着,除用户和角色之外的 0 文档已恢复。

4

重新配置并重新启动配置服务器副本集。

  1. 重新配置配置服务器

    选择身份验证机制的标签页:

    在以下每个主机上重新启动 mongod 实例:

    • mongodb7.example.net

    • mongodb8.example.net

    • mongodb9.example.net

    在每个 mongod 实例的配置文件中指定以下选项:

    选项
    用于初始副本集的密钥文件的路径。
    security:
    keyFile: <PATH_TO_KEYFILE>
    replication:
    replSetName: configReplSet
    sharding:
    clusterRole: configsvr
    net:
    bindIp: localhost,<hostname(s)>

    根据您的部署包含其他合适的选项。

    在以下每个主机上重新启动 mongod 实例:

    • mongodb7.example.net

    • mongodb8.example.net

    • mongodb9.example.net

    除了已配置的选项外,还可以在每个 mongod 实例的配置文件 中指定以下选项:

    选项
    x509
    requireTLS
    同时包含 TLS 证书和密钥的 .pem 文件的绝对路径。
    包含来自证书颁发机构的根证书链的 .pem 文件的绝对路径。

    localhost,然后是 mongod 应在其上侦听客户端连接的任何其他主机名。

    警告:在将实例绑定到可公开访问的IP解决之前,必须保护集群免遭未经授权的访问权限。有关安全建议的完整列表,请参阅自托管部署的安全检查清单。至少应考虑启用身份验证并强化网络基础架构。

    sharding:
    clusterRole: configsvr
    replication:
    replSetName: configReplSet
    security:
    clusterAuthMode: x509
    net:
    tls:
    mode: requireTLS
    certificateKeyFile: <FILE_WITH_COMBINED_CERT_AND_KEY>
    CAFile: <CA_FILE>
    bindIp: localhost,<hostname(s)>

    根据您的部署包含其他合适的选项,例如,如果您的 TLS 证书密钥文件使用密码加密,则包含 net.tls.certificateKeyFilePassword

  2. 重启 MongoDB

    使用您指定的配置重新启动 mongod

    mongod --config <PATH_TO_CONFIG_FILE> --shutdown
    mongod --config <PATH_TO_CONFIG_FILE>
5

mongos 提供客户端应用程序与分片群集之间的接口。

  1. 为 mongos 创建配置文件。

    mongos 配置文件中指定以下选项:

    选项
    configReplSet,后跟斜杠 / 以及至少一个配置服务器的主机名和端口。
    用于初始副本集的密钥文件的路径。
    localhost,然后是 mongos 应在其上侦听客户端连接的任何其他主机名。
    sharding:
    configDB: configReplSet/mongodb7.example.net:27019,mongodb8.example.net:27019,mongodb9.example.net:27019
    security:
    keyFile: <PATH_TO_KEYFILE>
    net:
    bindIp: localhost,<hostname(s)>

    根据您的部署包含其他合适的选项。

    mongos 配置文件中指定以下选项:

    选项
    configReplSet,后跟斜杠 / 以及至少一个配置服务器的主机名和端口。
    x509
    requireTLS
    同时包含 TLS 证书和密钥的 .pem 文件的绝对路径。
    包含来自证书颁发机构的根证书链的 .pem 文件的绝对路径。
    localhost,然后是 mongos 应在其上侦听客户端连接的任何其他主机名。
    sharding:
    configDB: configReplSet/mongodb7.example.net:27019,mongodb8.example.net:27019,mongodb9.example.net:27019
    security:
    clusterAuthMode: x509
    net:
    tls:
    mode: requireTLS
    certificateKeyFile: <FILE_WITH_COMBINED_CERT_AND_KEY>
    CAFile: <CA_FILE>
    bindIp: localhost,<hostname(s)>

    根据您的部署包含任何其他合适的选项。

  2. 部署 mongos。

    使用指定配置部署 mongos

    mongos --config <PATH_TO_CONFIG_FILE>
6

在此示例中,初始副本集为一个三成员副本集。此步骤会更新初始副本集,以便可将其作为分片添加到分片集群中。

副本集在以下主机上运行:

  • mongodb0.example.net:27017

  • mongodb1.example.net:27017

  • mongodb2.example.net:27017

对于分片集群,您必须将分片中每个 mongod 实例的角色设置为 shardsvr。要指定服务器角色,请在 mongod 配置文件中进行 sharding.clusterRole 设置。

注意

具有 shardsvr 角色的 mongod 实例的默认端口为 27018。要使用其他端口,请指定 net.port 设置。

  1. 连接到初始副本集的某一成员。

    使用 mongosh 连接到初始副本集的一个成员。

    mongosh "mongodb://<username>@mongodb0.example.net:27017"

    如果您的部署使用 x.509 身份验证,请指定这些 mongosh 选项:

    例如:

    mongosh "mongodb://<username>@mongodb0.example.net:27017" --tls --tlsCAFile <CA_FILE> --tlsCertificateKeyFile <filename>
  2. 确定副本集的主节点和从节点。

    运行 rs.status() 以确定主节点和从节点:

    rs.status()

    在命令输出中,replSetGetStatus.members[n].stateStr 字段表示哪一成员为主节点,哪些成员为从节点。

  3. 使用 --shardsvr 选项重启这些从节点。

    警告

    对于连接到副本集从节点的应用程序,此步骤需要一些停机时间。

    重新启动从从节点(secondary node from replica set)后,连接到该从节点的所有应用程序从节点(secondary node from replica set)返回CannotVerifyAndSignLogicalTime错误,直到您执行将初始副本集添加为分片中的步骤。

    您也可重新启动应用程序,使其不再收到 CannotVerifyAndSignLogicalTime 错误。

    1. 连接到从节点。

      使用 mongosh 连接到其中一个从节点。

      mongosh "mongodb://<username>@<host>:<port>"
    2. 关闭从节点。

      运行以下命令:

      use admin
      db.shutdownServer()
    3. 编辑从节点的配置文件。

      在从节点的配置文件中,将 sharding.clusterRole 设置为 shardsvr

      security:
      keyFile: <PATH_TO_KEYFILE>
      replication:
      replSetName: rs0
      sharding:
      clusterRole: shardsvr
      net:
      port: 27017
      bindIp: localhost,<hostname(s)>

      根据您的部署包含其他合适的选项。

    4. 将从节点作为分片服务器重启。

      在包含从节点的主机上运行以下命令:

      mongod --config <PATH_TO_CONFIG_FILE>
    5. 对另一个从节点重复关闭和重启步骤。

    1. 连接到从节点。

      使用 mongosh 连接到其中一个从节点。

      如果您的部署使用 x.509 身份验证,请指定这些 mongosh 选项:

      mongosh "mongodb://<username>@<host>:<port>" --tls --tlsCAFile <CA_FILE> --tlsCertificateKeyFile <filename>
    2. 关闭从节点。

      运行以下命令:

      use admin
      db.shutdownServer()
    3. 编辑从节点的配置文件。

      在从节点的配置文件中,将 sharding.clusterRole 设置为 shardsvr

      replication:
      replSetName: rs0
      sharding:
      clusterRole: shardsvr
      security:
      clusterAuthMode: x509
      net:
      port: 27017
      tls:
      mode: requireTLS
      certificateKeyFile: <FILE_WITH_COMBINED_CERT_AND_KEY>
      CAFile: <CA_FILE>
      bindIp: localhost,<hostname(s)>

      根据您的部署包含其他合适的选项,例如,如果您的 TLS 证书密钥文件使用密码加密,则包含 net.tls.certificateKeyFilePassword

    4. 将从节点作为分片服务器重启。

      在包含从节点的主机上运行以下命令:

      mongod --config <PATH_TO_CONFIG_FILE>
    5. 对另一个从节点重复关闭和重启步骤。

7

警告

对于连接到副本集主节点的应用程序,此步骤需要一些停机时间。

重新启动主节点 (primary node in the replica set)后,连接到主节点 (primary node in the replica set)节点的任何应用程序都会返回CannotVerifyAndSignLogicalTime错误,直到您执行将初始副本集添加为分片中的步骤。

您也可重新启动应用程序,使其不再收到 CannotVerifyAndSignLogicalTime 错误。

  1. 连接到主节点。

    使用 mongosh 连接到主节点:

    mongosh "mongodb://<username>@<host>:<port>"
  2. 从主节点降级。

    运行以下命令:

    rs.stepDown()
  3. 验证已完成降级。

    运行 rs.status() 以确认您所连接到的节点已降级并且现在是从节点:

    rs.status()
  4. 关闭以前的主节点。

    运行以下命令:

    use admin
    db.shutdownServer()

    等待关闭操作完成。

  5. 编辑主节点的配置文件。

    在主节点的配置文件中,将 sharding.clusterRole 设置为 shardsvr

    security:
    keyFile: <PATH_TO_KEYFILE>
    replication:
    replSetName: rs0
    sharding:
    clusterRole: shardsvr
    net:
    port: 27017
    bindIp: localhost,<hostname(s)>

    根据您的部署包含其他合适的选项。

  6. 重新启动主节点以作为分片服务器。

    在包含主节点的主机上运行以下命令:

    mongod --config <PATH_TO_CONFIG_FILE>
  1. 连接到主节点。

    使用 mongosh 连接到其中一个从节点。

    如果您的部署使用 x.509 身份验证,请指定这些 mongosh 选项:

    如果您的部署使用 x.509 身份验证,请指定这些 mongosh 选项:

    mongosh "mongodb://<username>@<host>:<port>" --tls --tlsCAFile <CA_FILE> --tlsCertificateKeyFile <filename>
  2. 从主节点降级。

    运行以下命令:

    rs.stepDown()
  3. 验证已完成降级。

    运行 rs.status() 以确认您所连接到的节点已降级并且现在是从节点:

    rs.status()
  4. 关闭以前的主节点。

    运行以下命令:

    use admin
    db.shutdownServer()

    等待关闭操作完成。

  5. 编辑主节点的配置文件。

    在主节点的配置文件中,将 sharding.clusterRole 设置为 shardsvr

    replication:
    replSetName: rs0
    sharding:
    clusterRole: shardsvr
    security:
    clusterAuthMode: x509
    net:
    port: 27017
    tls:
    mode: requireTLS
    certificateKeyFile: <FILE_WITH_COMBINED_CERT_AND_KEY>
    CAFile: <CA_FILE>
    bindIp: localhost,<hostname(s)>

    根据您的部署包含其他合适的选项,例如,如果您的 TLS 证书密钥文件使用密码加密,则包含 net.tls.certificateKeyFilePassword

  6. 重新启动主节点以作为分片服务器。

    在包含主节点的主机上运行以下命令:

    mongod --config <PATH_TO_CONFIG_FILE>
8

将初始副本集 (rs0) 转换为分片后,将其添加到分片集群中。

  1. 以集群的管理用户身份连接到 mongos

    mongos 实例正在主机 mongodb6.example.net 上运行。

    要将 mongosh 连接到 mongos,请运行以下命令:

    mongosh "mongodb://admin01@mongodb6.example.net:27017"

    如果您的部署使用 x.509 身份验证,请指定这些 mongosh 选项:

    如果您的部署使用 x.509 身份验证,请指定这些 mongosh 选项:

    mongosh "mongodb://admin01@mongodb6.example.net:27017" --tls --tlsCAFile <CA_FILE> --tlsCertificateKeyFile <filename>

    此命令将验证您作为您在分片集群上创建的 admin01 用户的身份。输入命令后,输入用户的密码。

  2. 添加分片。

    若要将分片添加到集群,请运行 sh.addShard() 方法:

    sh.addShard( "rs0/mongodb0.example.net:27017,mongodb1.example.net:27017,mongodb2.example.net:27017" )

    警告

    激活新分片后,mongosh 和其他客户端必须始终连接到 mongos 实例。请勿直接连接到 mongod 实例。如果您的客户端会直接连接到分片,则可能会造成数据或元数据不一致。

9

将第一个分片添加到集群后,将应用程序所用的连接字符串更新为分片集群的连接字符串。然后,重新启动您的应用程序。

10

部署名为 rs1 的新副本集。副本集的成员 rs1 位于以下主机上:

  • mongodb3.example.net

  • mongodb4.example.net

  • mongodb5.example.net

  1. 启动副本集的每个成员。

    对于副本集中的每个 mongod 实例,创建一个包含以下选项的配置文件:

    选项
    用于初始副本集的密钥文件的路径。
    rs1
    shardsvr
    localhost,然后是 mongod 应在其上侦听客户端连接的任何其他主机名。
    security:
    keyFile: <PATH_TO_KEYFILE>
    replication:
    replSetName: rs1
    sharding:
    clusterRole: shardsvr
    net:
    bindIp: localhost,<hostname(s)>

    根据您的部署包含其他合适的选项。

    为每个节点启动一个 mongod 实例,设置如下:

    选项
    rs1
    shardsvr
    x509
    requireTLS
    同时包含 TLS 证书和密钥的 .pem 文件的绝对路径。
    包含来自证书颁发机构的根证书链的 .pem 文件的绝对路径。
    localhost,然后是 mongod 应在其上侦听客户端连接的任何其他主机名。
    replication:
    replSetName: rs1
    sharding:
    clusterRole: shardsvr
    security:
    clusterAuthMode: x509
    net:
    tls:
    mode: requireTLS
    certificateKeyFile: <FILE_WITH_COMBINED_CERT_AND_KEY>
    CAFile: <CA_FILE>
    bindIp: localhost,<hostname(s)>

    使用指定配置部署 mongod

    mongod --config <PATH_TO_CONFIG_FILE>

    注意

    当您为 mongod 实例指定了 --shardsvr 选项,该实例将默认在端口 27018 上运行。

  2. 启动副本集的每个成员。

  3. 连接到某一副本集成员。

    使用 mongosh 连接到副本集成员之一。例如:

    mongosh "mongodb://mongodb3.example.net:27018"
    mongosh "mongodb://mongodb3.example.net:27018" --tls --tlsCAFile <CA_FILE> --tlsCertificateKeyFile <filename>
  4. 启动新副本集。

    mongosh 中,运行 rs.initiate() 方法以启动包含当前成员的副本集:

    rs.initiate( {
    _id : "rs1",
    members: [
    { _id: 0, host: "mongodb3.example.net:27018" },
    { _id: 1, host: "mongodb4.example.net:27018" },
    { _id: 2, host: "mongodb5.example.net:27018" }
    ]
    } )

    前面的命令需要本地主机异常才能在不进行身份验证的情况下执行管理操作。

    重要

    仅在副本集的一个 mongod 实例上运行 rs.initiate()

  5. 为此副本集添加管理用户。

    部署副本集后,使用本地主机异常创建副本集的第一个用户。

    1. 确定副本集主节点。

      要确定主节点,请运行 rs.status()

      rs.status()

      在命令输出中,replSetGetStatus.members[n].stateStr 字段会表明哪一成员为主节点。

    2. 连接到副本集主节点。

      使用 mongosh 连接到副本集主节点。例如,如果主节点为 mongodb4.example.net,则运行以下命令:

      mongosh "mongodb://mongodb4.example.net:27018"
    3. 创建管理用户。

      运行以下 db.createUser() 方法,创建名为 rs1Admin 的用户,并具有 userAdmin 角色:

      use admin
      db.createUser(
      {
      user: "rs1Admin",
      pwd: passwordPrompt(),
      roles: [
      { role: "userAdmin", db: "admin" }
      ]
      }
      )

      运行该命令后,数据库会提示您为 rs1Admin 用户输入密码。

11

将新副本集 rs1 添加到分片集群。

  1. mongosh 连接到 mongos

    从命令行运行以下命令以连接到主机 mongodb6.example.net 上所运行的 mongos 实例:

    mongosh "mongodb://admin01@mongodb6.example.net:27017/admin"
    mongosh "mongodb://admin01@mongodb6.example.net:27017/admin" --tls --tlsCAFile <CA_FILE> --tlsCertificateKeyFile <filename>

    此命令将验证您作为您在分片集群上创建的 admin01 用户的身份。输入命令后,输入用户的密码。

  2. 添加第二个分片。

    连接到 mongos 后,使用 sh.addShard() 方法将副本集 rs1 作为分片添加到集群中:

    sh.addShard( "rs1/mongodb3.example.net:27018,mongodb4.example.net:27018,mongodb5.example.net:27018" )
12

该过程的最后一步是对分片集群中的集合进行分片。

  1. 确定分片键。

    确定集合的分片键。分片键指示 MongoDB 如何在分片之间分配文档。好的分片键:

    • 在所有文档中具有均匀分布的值。

    • 将经常同时访问的文档分组为连续数据段。

    • 允许在各分片之间有效分配活动。

    有关更多信息,请参阅选择分片键。

    此过程将 number 字段用作 test_collection 集合的分片键。

  2. 为分片的键创建索引。

    在对非空集合进行分片之前,请对此分片键创建索引:

    use test
    db.test_collection.createIndex( { "number" : 1 } )
  3. 对集合进行分片。

    test 数据库中,对 test_collection 进行分片。将 number 指定为分片键。

    sh.shardCollection( "test.test_collection", { "number" : 1 } )

    下次运行负载均衡器时,它会在各分片之间重新分配文档数据段。当客户端向此集合插入更多文档时,mongos 会将这些文档路由到相应的分片。

    负载均衡器重新分发数据块时,可能会对应用程序的性能产生负面影响。为最大限度降低对性能的影响,您可以指定何时运行负载均衡器,以免其在高峰时段运行。要了解详情,请参阅安排负载均衡窗口。

要查看更多分片教程和操作方法,请参阅以下页面:

后退

将分片集群转换为副本集