更改副本集中的主机名
在本页面
对于大多数replica sets,members[n].host字段中的主机名永远不会更改。但是,如果组织需求发生变化,则可能需要迁移部分或全部主机名。
Note
在副本集配置中,始终将可解析的主机名用作members[n].host字段的值,以避免混淆和复杂性。
Overview
本文档提供了两个单独的过程来更改members[n].host字段中的主机名。使用以下两种方法之一:
- 更改主机名而不中断可用性。这种方法可确保您的应用程序始终能够将数据读取和写入副本集,但是这种方法可能会花费很长时间,并且可能导致应用程序层停机。
如果使用第一个过程,则必须将应用程序配置为同时连接到旧位置和新位置的副本集,这通常需要在应用程序层重新启动和重新配置,这可能会影响应用程序的可用性。重新配置应用程序超出了本文档的范围。
- 一次停止所有在旧主机名上运行的成员。这种方法的维护周期较短,但是副本集在操作过程中将不可用。
See also
Assumptions
给定一个具有三个成员的replica set:
-
database0.example.com:27017
(primary) -
database1.example.com:27017
-
database2.example.com:27017
并具有以下rs.conf()输出:
{
"_id" : "rs",
"version" : 3,
"members" : [
{
"_id" : 0,
"host" : "database0.example.com:27017"
},
{
"_id" : 1,
"host" : "database1.example.com:27017"
},
{
"_id" : 2,
"host" : "database2.example.com:27017"
}
]
}
以下过程按如下方式更改成员的主机名:
-
mongodb0.example.net:27017
(主要的) -
mongodb1.example.net:27017
-
mongodb2.example.net:27017
使用最适合您的部署过程。
更改主机名,同时保持副本集可用性
此过程使用上面的assumptions。
-
对于副本集中的每个secondary,执行以下操作序列:
-
停止辅助服务器。
-
在新位置重新启动辅助服务器。
-
打开连接到副本集主数据库的mongo shell。在我们的示例中,主要数据库在端口
27017
上运行,因此您将发出以下命令:
-
mongo --port 27017
- 使用rs.reconfig()使用新的主机名更新副本集配置文档。
例如,以下命令序列在副本集配置文档中的members
数组(即members[1]
)的数组索引1
处更新辅助服务器的主机名:
cfg = rs.conf()
cfg.members[1].host = "mongodb1.example.net:27017"
rs.reconfig(cfg)
有关更新配置文档的更多信息,请参见Examples。
- 确保您的 Client 端应用程序能够在新位置访问集合,并且辅助服务器有机会赶上集合的其他成员。
对集合中的每个非主要成员重复上述步骤。
- 打开连接到主要数据库的mongo shell,然后使用rs.stepDown()方法退出主要数据库:
rs.stepDown()
副本集选举另一个成员成为主要成员。
例如,如果旧的主数据库位于位置0
,而新的主数据库的主机名是mongodb0.example.net:27017
,则应运行:
cfg = rs.conf()
cfg.members[0].host = "mongodb0.example.net:27017"
rs.reconfig(cfg)
您的输出应类似于:
{
"_id" : "rs",
"version" : 4,
"members" : [
{
"_id" : 0,
"host" : "mongodb0.example.net:27017"
},
{
"_id" : 1,
"host" : "mongodb1.example.net:27017"
},
{
"_id" : 2,
"host" : "mongodb2.example.net:27017"
}
]
}
同时更改所有主机名
此过程使用上面的assumptions。
Prerequisites
以下过程读取并更新local
数据库中的system.replset
集合。
如果您的部署强制执行access control,则执行此过程的用户必须对system.replset
集合具有find和update特权操作。
要创建提供必要特权的角色,请执行以下操作:
- 以具有 Management 用户和角色权限的用户身份登录,例如具有userAdminAnyDatabase角色的用户。以下过程使用在Enable Auth中创建的
myUserAdmin
。
mongo --port 27017 -u myUserAdmin --authenticationDatabase 'admin' -p
- 创建一个用户角色,为
local
数据库中的system.replset
集合提供必要的特权:
db.adminCommand( {
createRole: "systemreplsetRole",
privileges: [
{ resource: { db: "local", collection: "system.replset" }, actions: ["find","update"] }
],
roles: []
} );
- 将角色授予将执行重命名过程的用户。例如,以下假设
admin
数据库中已有一个用户"userPerformingRename"
。
use admin
db.grantRolesToUser( "userPerformingRename", [ { role: "systemreplsetRole", db: "admin" } ] );
Procedure
-
停止replica set中的所有成员。
-
使用--replSet运行时选项在不同的端口上并且没有重启每个成员。在维护期间更改端口号可防止 Client 端在执行维护时连接到该主机。使用成员常用的--dbpath,在此示例中为
/data/db1
。使用类似于以下内容的命令:
Warning
绑定到非 localhost(例如可公开访问)的 IP 地址之前,请确保已保护群集免受未经授权的访问。有关安全建议的完整列表,请参见Security Checklist。至少考虑enabling authentication和加强网络基础设施。
mongod --dbpath /data/db1/ --port 37017 --bind_ip localhost,<ip address of the mongod host>
mongo --port 37017
如果使用访问控制运行,请以具有适当特权的用户身份连接。参见Prerequisites。
mongo --port 37017 -u userPerformingRename --authenticationDatabase=admin -p
- 手动编辑副本集配置。副本集配置是
local
数据库中system.replset
集合中的唯一文档。使用新的主机名编辑副本集配置,并为副本集的所有成员纠正端口。请考虑以下命令序列,以更改三人组中的主机名:
use local
cfg = db.system.replset.findOne( { "_id": "rs" } )
cfg.members[0].host = "mongodb0.example.net:27017"
cfg.members[1].host = "mongodb1.example.net:27017"
cfg.members[2].host = "mongodb2.example.net:27017"
db.system.replset.update( { "_id": "rs" } , cfg )
Warning
绑定到非 localhost(例如可公开访问)的 IP 地址之前,请确保已保护群集免受未经授权的访问。有关安全建议的完整列表,请参见Security Checklist。至少考虑enabling authentication和加强网络基础设施。
mongod --dbpath /data/db1/ --port 27017 --replSet rs --bind_ip localhost,<ip address of the mongod host>
mongo --port 27017
您的输出应类似于:
{
"_id" : "rs",
"version" : 4,
"members" : [
{
"_id" : 0,
"host" : "mongodb0.example.net:27017"
},
{
"_id" : 1,
"host" : "mongodb1.example.net:27017"
},
{
"_id" : 2,
"host" : "mongodb2.example.net:27017"
}
]
}