将自管理副本集转换为分片集群
分片集群会根据 分片键在多个服务器上对数据分区。对于具有大数据集和高吞吐量操作的部署,分片集群可提供优于副本集的扩展性。
本教程将把单个三成员副本集转换为具有两个分片的分片集群。新集群中的每个分片均为一个独立的三成员副本集。
对于 MongoDB Atlas 中托管的部署,您可以 在用户界面中将其转换为分片集群。
关于此任务
本教程中的某些步骤会导致部署停机。个别步骤提到了何时会出现停机。
本教程适用于已启用身份验证的部署。
在本教程中,您部署的分片集群将包含 10 台服务器:
服务器架构
本教程使用以下服务器:
主机名 | 端口 | 说明 |
---|---|---|
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 地址的节点将无法通过启动验证,因而不会启动。
开始之前
要完成本教程,您必须拥有使用密钥文件或 x.509 证书身份验证的副本集。要部署使用这些身份验证方法之一的安全副本集,请参阅:
本教程使用默认数据目录
/data/db
和/data/configdb
。要使用其他路径,请在配置文件中配置storage.dbPath
设置。
步骤
部署配置服务器副本集
为配置服务器部署一个三成员副本集。在此示例中,配置服务器使用以下主机:
mongodb7.example.net
mongodb8.example.net
mongodb9.example.net
配置配置服务器
在每个配置服务器主机上配置一个
mongod
实例。在每个mongod
实例的配置文件中指定以下选项:选项值configReplSet
configsvr
localhost
,然后是mongod
应在其上侦听客户端连接的任何其他主机名。replication: replSetName: configReplSet sharding: clusterRole: configsvr net: bindIp: localhost,<hostname(s)> 根据您的部署包含其他合适的选项。
启动配置服务器
使用指定配置部署
mongod
:mongod --config <PATH_TO_CONFIG_FILE> 配置服务器使用默认数据目录
/data/configdb
和默认端口27019
。连接到一台配置服务器。
使用
mongosh
连接到其中一个配置服务器。例如:mongosh "mongodb://mongodb7.example.net:27019" 启动配置服务器副本集。
要启动复制集,请运行
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()
。
将现有用户和角色恢复到新配置
恢复您在运行 mongodump
时获得的现有用户和角色。
mongorestore ./adminDump --nsInclude "admin.*" --host <configPrimaryURI>
前面的命令使用本地主机例外情况来执行管理操作,而不进行身份验证。
运行此命令的输出可能如下所示:
0 document(s) restored successfully
此消息并不表示存在问题。此输出意味着,除用户和角色之外的 0 文档已恢复。
安全配置服务器副本集
重新配置并重新启动配置服务器副本集。
重新配置配置服务器
选择身份验证机制的标签页:
在以下每个主机上重新启动
mongod
实例:mongodb7.example.net
mongodb8.example.net
mongodb9.example.net
选项值用于初始副本集的密钥文件的路径。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
。重启 MongoDB
使用您指定的配置重新启动
mongod
:mongod --config <PATH_TO_CONFIG_FILE> --shutdown mongod --config <PATH_TO_CONFIG_FILE>
部署 mongos
mongos
提供客户端应用程序与分片群集之间的接口。
为 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)> 根据您的部署包含任何其他合适的选项。
部署 mongos。
使用指定配置部署
mongos
:mongos --config <PATH_TO_CONFIG_FILE>
将初始副本集重新启动为分片
在此示例中,初始副本集为一个三成员副本集。此步骤会更新初始副本集,以便可将其作为分片添加到分片集群中。
副本集在以下主机上运行:
mongodb0.example.net:27017
mongodb1.example.net:27017
mongodb2.example.net:27017
对于分片集群,您必须将分片中每个 mongod
实例的角色设置为 shardsvr
。要指定服务器角色,请在 mongod
配置文件中进行 sharding.clusterRole
设置。
连接到初始副本集的某一成员。
使用
mongosh
连接到初始副本集的一个成员。mongosh "mongodb://<username>@mongodb0.example.net:27017" 如果您的部署使用 x.509 身份验证,请指定这些
mongosh
选项:例如:
mongosh "mongodb://<username>@mongodb0.example.net:27017" --tls --tlsCAFile <CA_FILE> --tlsCertificateKeyFile <filename> 确定副本集的主节点和从节点。
运行
rs.status()
以确定主节点和从节点:rs.status() 在命令输出中,
replSetGetStatus.members[n].stateStr
字段表示哪一成员为主节点,哪些成员为从节点。使用
--shardsvr
选项重启这些从节点。警告
对于连接到副本集从节点的应用程序,此步骤需要一些停机时间。
重新启动从从节点(secondary node from replica set)后,连接到该从节点的所有应用程序从节点(secondary node from replica set)返回
CannotVerifyAndSignLogicalTime
错误,直到您执行将初始副本集添加为分片中的步骤。您也可重新启动应用程序,使其不再收到
CannotVerifyAndSignLogicalTime
错误。连接到从节点。
使用
mongosh
连接到其中一个从节点。mongosh "mongodb://<username>@<host>:<port>" 关闭从节点。
运行以下命令:
use admin db.shutdownServer() 编辑从节点的配置文件。
在从节点的配置文件中,将
sharding.clusterRole
设置为shardsvr
:security: keyFile: <PATH_TO_KEYFILE> replication: replSetName: rs0 sharding: clusterRole: shardsvr net: port: 27017 bindIp: localhost,<hostname(s)> 根据您的部署包含其他合适的选项。
将从节点作为分片服务器重启。
在包含从节点的主机上运行以下命令:
mongod --config <PATH_TO_CONFIG_FILE> 对另一个从节点重复关闭和重启步骤。
连接到从节点。
使用
mongosh
连接到其中一个从节点。如果您的部署使用 x.509 身份验证,请指定这些
mongosh
选项:mongosh "mongodb://<username>@<host>:<port>" --tls --tlsCAFile <CA_FILE> --tlsCertificateKeyFile <filename> 关闭从节点。
运行以下命令:
use admin db.shutdownServer() 编辑从节点的配置文件。
在从节点的配置文件中,将
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
。将从节点作为分片服务器重启。
在包含从节点的主机上运行以下命令:
mongod --config <PATH_TO_CONFIG_FILE> 对另一个从节点重复关闭和重启步骤。
使用 选项重新启动主节点 (primary node--shardsvr
in the replica set)节点。
警告
对于连接到副本集主节点的应用程序,此步骤需要一些停机时间。
重新启动主节点 (primary node in the replica set)后,连接到主节点 (primary node in the replica set)节点的任何应用程序都会返回CannotVerifyAndSignLogicalTime
错误,直到您执行将初始副本集添加为分片中的步骤。
您也可重新启动应用程序,使其不再收到 CannotVerifyAndSignLogicalTime
错误。
连接到主节点。
使用
mongosh
连接到主节点:mongosh "mongodb://<username>@<host>:<port>" 从主节点降级。
运行以下命令:
rs.stepDown() 验证已完成降级。
运行
rs.status()
以确认您所连接到的节点已降级并且现在是从节点:rs.status() 关闭以前的主节点。
运行以下命令:
use admin db.shutdownServer() 等待关闭操作完成。
编辑主节点的配置文件。
在主节点的配置文件中,将
sharding.clusterRole
设置为shardsvr
:security: keyFile: <PATH_TO_KEYFILE> replication: replSetName: rs0 sharding: clusterRole: shardsvr net: port: 27017 bindIp: localhost,<hostname(s)> 根据您的部署包含其他合适的选项。
重新启动主节点以作为分片服务器。
在包含主节点的主机上运行以下命令:
mongod --config <PATH_TO_CONFIG_FILE>
连接到主节点。
使用
mongosh
连接到其中一个从节点。如果您的部署使用 x.509 身份验证,请指定这些
mongosh
选项:如果您的部署使用 x.509 身份验证,请指定这些
mongosh
选项:mongosh "mongodb://<username>@<host>:<port>" --tls --tlsCAFile <CA_FILE> --tlsCertificateKeyFile <filename> 从主节点降级。
运行以下命令:
rs.stepDown() 验证已完成降级。
运行
rs.status()
以确认您所连接到的节点已降级并且现在是从节点:rs.status() 关闭以前的主节点。
运行以下命令:
use admin db.shutdownServer() 等待关闭操作完成。
编辑主节点的配置文件。
在主节点的配置文件中,将
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
。重新启动主节点以作为分片服务器。
在包含主节点的主机上运行以下命令:
mongod --config <PATH_TO_CONFIG_FILE>
将初始副本集添加为分片
将初始副本集 (rs0
) 转换为分片后,将其添加到分片集群中。
以集群的管理用户身份连接到
mongos
。mongos
实例正在主机mongodb6.example.net
上运行。此命令将验证您作为您在分片集群上创建的
admin01
用户的身份。输入命令后,输入用户的密码。添加分片。
若要将分片添加到集群,请运行
sh.addShard()
方法:sh.addShard( "rs0/mongodb0.example.net:27017,mongodb1.example.net:27017,mongodb2.example.net:27017" ) 警告
激活新分片后,
mongosh
和其他客户端必须始终连接到mongos
实例。请勿直接连接到mongod
实例。如果您的客户端会直接连接到分片,则可能会造成数据或元数据不一致。
更新应用程序连接string
将第一个分片添加到集群后,将应用程序所用的连接字符串更新为分片集群的连接字符串。然后,重新启动您的应用程序。
部署第二个副本集
部署名为 rs1
的新副本集。副本集的成员 rs1
位于以下主机上:
mongodb3.example.net
mongodb4.example.net
mongodb5.example.net
启动副本集的每个成员。
为每个节点启动一个
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
上运行。启动副本集的每个成员。
连接到某一副本集成员。
使用
mongosh
连接到副本集成员之一。例如:mongosh "mongodb://mongodb3.example.net:27018" mongosh "mongodb://mongodb3.example.net:27018" --tls --tlsCAFile <CA_FILE> --tlsCertificateKeyFile <filename> 启动新副本集。
在
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()
。为此副本集添加管理用户。
部署副本集后,使用本地主机异常创建副本集的第一个用户。
确定副本集主节点。
要确定主节点,请运行
rs.status()
:rs.status() 在命令输出中,
replSetGetStatus.members[n].stateStr
字段会表明哪一成员为主节点。连接到副本集主节点。
使用
mongosh
连接到副本集主节点。例如,如果主节点为mongodb4.example.net
,则运行以下命令:mongosh "mongodb://mongodb4.example.net:27018" 创建管理用户。
运行以下
db.createUser()
方法,创建名为rs1Admin
的用户,并具有userAdmin
角色:use admin db.createUser( { user: "rs1Admin", pwd: passwordPrompt(), roles: [ { role: "userAdmin", db: "admin" } ] } ) 运行该命令后,数据库会提示您为
rs1Admin
用户输入密码。
将第二个副本集作为分片添加到集群
将新副本集 rs1
添加到分片集群。
将
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
用户的身份。输入命令后,输入用户的密码。添加第二个分片。
连接到
mongos
后,使用sh.addShard()
方法将副本集rs1
作为分片添加到集群中:sh.addShard( "rs1/mongodb3.example.net:27018,mongodb4.example.net:27018,mongodb5.example.net:27018" )
将集合分片
该过程的最后一步是对分片集群中的集合进行分片。
确定分片键。
确定集合的分片键。分片键指示 MongoDB 如何在分片之间分配文档。好的分片键:
在所有文档中具有均匀分布的值。
将经常同时访问的文档分组为连续数据段。
允许在各分片之间有效分配活动。
有关更多信息,请参阅选择分片键。
此过程将
number
字段用作test_collection
集合的分片键。为分片的键创建索引。
在对非空集合进行分片之前,请对此分片键创建索引:
use test db.test_collection.createIndex( { "number" : 1 } ) 对集合进行分片。
在
test
数据库中,对test_collection
进行分片。将number
指定为分片键。sh.shardCollection( "test.test_collection", { "number" : 1 } ) 下次运行负载均衡器时,它会在各分片之间重新分配文档数据段。当客户端向此集合插入更多文档时,
mongos
会将这些文档路由到相应的分片。负载均衡器重新分发数据块时,可能会对应用程序的性能产生负面影响。为最大限度降低对性能的影响,您可以指定何时运行负载均衡器,以免其在高峰时段运行。要了解详情,请参阅安排负载均衡窗口。
了解详情
要查看更多分片教程和操作方法,请参阅以下页面: