MongoDB 自带功能强大的主从,配置也很简单,从零开始花了30分钟搞定
3台以上机器IP: 192.168.1.24, 192.168.1.25, 192.168.1.26, 192.168.1.27(只读),每台服务器安装好mongodb。
启动副本集(副本集id:mySet)
参考文档 replication Options
通过命令启动: /path/mongod [其他参数] --replSet=mySet
通过配置文件: /path/mongod -f /path/mongo.conf
# mongo.conf 内容
replcation:
replSetName: mySet
初始化 rs.initiate(configuration)
文档参考 rs.initiate
进入mongo客户端
rs.conf() // 会提示未进行初始化 rs.initiate()
rs.initiate({
_id: "mySet", // 副本集名称
version: 1,
members: [
{ _id: 0, host: "192.168.1.24:27017", priority: 1},
{ _id: 1, host: "192.168.1.25:27017", priority: 1},
{ _id: 2, host: "192.168.1.26:27017", priority: 1},
{ _id: 3, host: "192.168.1.27:27017", hidden: true, priority: 0}, //只读
//{ _id: 99, host: "192.168.1.99", arbiterOnly: true}, // 仲裁机,不复制数据,无法做主机
]
})
配置完成后会自动选举出一台 PRIMARY
副本集动态扩展
文档参考 rs.add
新增加的机器配置同一个副本集名称(mySet)并启动,在PRIMARY主机进行操作:
rs.add({_id:4, host: "192.168.1.28", priority: 1})
新机器会自动进行数据同步,同步完成后变成SECONDARY
开启权限控制
文档参考 Enforce Keyfile Access Control in a Replica Set
+. 权限控制包括两个层面:副本集互相认证,客户机的权限认证
+. 可以通过 bindIp: host1,host2,host3
选项在网络层进行过滤
+. 配置步骤
1). 创建 keyfile ,keyfile可以任意创建,只要是合法的base64字符,长度6-1024,unix系统权限必须为600或400. 拷贝到副本集每一个成员中
2). 关闭所有mongodb成员实例,增加keyfile选项启动 --keyfile <path-to-keyfile>
,或者修改mongodb.conf
security:
keyFile: <path-to-keyfile>
3). 连接primary(rs.status()查看primary,然后切换),创建管理用户
admin = db.getSiblingDB("admin")
admin.createUser(
{
user: "root",
pwd: "PassWord123",
roles: [ { role: "root", db: "admin" } ]
}
)
官方说这里创建的用户权限必须至少高于userAdminAnyDatabase,不然会导致副本集无法访问
4). 创建其他用户,另外可以选择创建 clusterAdmin 角色,这个角色可以修改其他副本集成员的动作
db.getSiblingDB("admin").createUser(
{
"user" : "username",
"pwd" : "PassWord321",
roles: [ { "role" : "readWrite", "db" : "db_name" } ]
}
)
使用 mongodb.js 连接
const mongoCli = require("mongodb").MongoClient;
let db = yield mongoCli.connect("mongodb://192.168.1.24:27017,192.168.1.24:27017,192.168.1.24:27017/db_name?replcaSet=mySet");
// yield mongoCli.connect("mongodb://192.168.1.24:27017,192.168.1.24:27017,192.168.1.24:27017/db_name?replcaSet=mySet", function(err, client){db = client.db(db_name)});
从 SECONDARY 读取数据
主从的延迟默认是0,通过配置项自行设置。
从机需要开启 SlaveOk 才可以读取,一般的读取流程为:
use mydb
mydb.setSlaveOk()
mydb.col.find() // ...