mongodb复制集+认证踩坑记录
目标
两个实例上的(mongodb)数据同步,从主实例写入数据,可以从任意实例读取。当任意实例挂了后,另外一个实例可以变成主实例,可以读写。
需求
mongodb有效复制集至少需要3个实例才能达到完整效果。但是为了节约资源,我们可以用2个实例+1个仲裁实例来实现差不多的效果。仲裁实例甚至可以和某个实例在同一个服务器,只是这样的话可靠性会下降很多。
3台服务器,上面有版本一致的mongodb(我使用的版本为3.4),服务器之间可以互通。
创建一个公有的密钥,为方便我直接使用的ssh的公钥(需要处理,只截取中间的base64编码后的密钥)。也可以自己生成,生成方式于此。建议使用x.509证书方式,上ssl加密,安全系数更高。
初始化
-
非主实例需要首先清空数据,建议直接删掉对应配置的
storage.dbPath
目录,否则有多个实例有数据,无法并入复制集。 -
配置中必须有这几个字段:
net:
port: 27017
bindIp: 0.0.0.0
security:
keyFile: /etc/mongo.key
replication:
replSetName: "test" -
在主实例分配帐号,设置权限。复制集生效后,其他实例会同步用户信息。
-
密钥文件用户组需要改成
mongo:mongo
,权限400,否则实例无法启动。
部署
-
启动所有实例
-
仲裁实例需要手动启动,
mongod --config /etc/mongodarb.conf &
。仲裁实例端口和存储目录需要独立 -
进入主实例,登录(帐号需要有
clusterAdmin
权限)。此时实例由于没有复制集配置,处于不可用状态。 -
主实例执行
rs.initiate( {
_id : "test",
members: [
{ _id: 0, host: "192.168.0.2:27017",priority:10 },#主实例
{ _id: 1, host: "192.168.0.3:27017",priority:1 }
]
})
rs.addArb('192.168.0.3:27018') -
执行
rs.status()
确认复制集正常运行。完成 -
如需要在非主实例查看数据,要先在对应实例执行
rs.slaveOk(true)
。非主实例可能会有2秒左右延迟。
其他
数据库热切换需要应用支持。如PHP,连接数据库时需要指定复制集内实例地址,具体见文档。