官方参考文档:https://docs.mongodb.com/v3.2/tutorial/deploy-replica-set/
1 安装 mongod,指定副本集名称
安装步骤和单节点一样,这里就不在赘述了。只需要在配置文件中额外添加 replication 模块的配置。
需要注意的是: 在同一个副本集中的所有节点的 replSetName
必须相同。
有需要了解 MongoDB 单节点安装步骤的,可以参考前面的文档:MongoDB 单节点安装
systemLog:
#verbosity: 0
quiet: false
destination: file
logAppend: true
path: /usr/local/mongodb/log/mongod.log
#timeStampFormat: iso8601-local
processManagement:
fork: true
pidFilePath: /usr/local/mongodb/temp/mongod.pid
net:
port: 27017
bindIp: 192.168.10.141,127.0.0.1
maxIncomingConnections: 65536
wireObjectCheck: true
ipv6: false
storage:
dbPath: /mongodb_data
indexBuildRetry: true
journal:
enabled: true
commitIntervalMs: 100
directoryPerDB: false
engine: wiredTiger
syncPeriodSecs: 60
wiredTiger:
engineConfig:
cacheSizeGB: 4
journalCompressor: snappy
directoryForIndexes: false
collectionConfig:
blockCompressor: snappy
indexConfig:
prefixCompression: true
operationProfiling:
slowOpThresholdMs: 100
mode: off
replication:
oplogSizeMB: 10240
replSetName: rs0
secondaryIndexPrefetch: all
enableMajorityReadConcern: false
2 启动副本集
#进入mongod
[root@mongodb111 mongodb]# mongo
MongoDB shell version: 3.2.22
......
#启动副本集
MongoDB Enterprise > rs.initiate()
{
"info2" : "no configuration specified. Using a default configuration for the set",
"me" : "192.168.10.140:27017",
"ok" : 1
}
3 验证初始副本集配置
MongoDB Enterprise rs0:PRIMARY> rs.conf()
{
"_id" : "rs0",
"version" : 1,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "192.168.10.140:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("608051a8cfb573598bf0de3a")
}
}
4 为副本集添加新成员
注意:如果是为正在运行的副本集添加新成员时,只能在主节点(primary)上添加;新部署的副本集,在哪个上面进行了副本集初始化"rs.initiate()"
,哪台就会成为主节点。
PS:
如果不知道哪个是主节点(primary)的话,可以使用 “db.isMaster()” 查看哪个是主节点
MongoDB Enterprise rs0:PRIMARY> db.isMaster()
{
"hosts" : [
"192.168.10.140:27017"
],
"setName" : "rs0",
"setVersion" : 1,
"ismaster" : true,
"secondary" : false,
"primary" : "192.168.10.140:27017",
"me" : "192.168.10.140:27017",
"electionId" : ObjectId("7fffffff0000000000000001"),
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2021-04-21T11:25:32.898Z"),
"maxWireVersion" : 4,
"minWireVersion" : 0,
"ok" : 1
}
MongoDB Enterprise rs0:PRIMARY> rs.add( { host: "192.168.10.141:27017", priority: 0, votes: 0 } )
{ "ok" : 1 }
MongoDB Enterprise rs0:PRIMARY> rs.add( { host: "192.168.10.142:27017", priority: 0, votes: 0 } )
{ "ok" : 1 }
5 使用 “rs.status()” 查看副本集状态
确保新成员已达到 SECONDARY 状态
MongoDB Enterprise rs0:PRIMARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2021-04-24T05:32:18.149Z"),
"myState" : 1,
"term" : NumberLong(6),
"heartbeatIntervalMillis" : NumberLong(2000),
"members" : [
{
"_id" : 0,
"name" : "192.168.10.140:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 97339,
"optime" : {
"ts" : Timestamp(1619232645, 355),
"t" : NumberLong(6)
},
"optimeDate" : ISODate("2021-04-24T02:50:45Z"),
"electionTime" : Timestamp(1619232080, 1),
"electionDate" : ISODate("2021-04-24T02:41:20Z"),
"configVersion" : 4,
"self" : true
},
{
"_id" : 1,
"name" : "192.168.10.141:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 10278,
"optime" : {
"ts" : Timestamp(1619232645, 355),
"t" : NumberLong(6)
},
"optimeDate" : ISODate("2021-04-24T02:50:45Z"),
"lastHeartbeat" : ISODate("2021-04-24T05:32:17.338Z"),
"lastHeartbeatRecv" : ISODate("2021-04-24T05:32:17.572Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "192.168.10.140:27017",
"configVersion" : 4
},
{
"_id" : 2,
"name" : "192.168.10.142:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 10278,
"optime" : {
"ts" : Timestamp(1619232645, 355),
"t" : NumberLong(6)
},
"optimeDate" : ISODate("2021-04-24T02:50:45Z"),
"lastHeartbeat" : ISODate("2021-04-24T05:32:16.489Z"),
"lastHeartbeatRecv" : ISODate("2021-04-24T05:32:16.958Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "192.168.10.140:27017",
"configVersion" : 4
}
],
"ok" : 1
}
6 配置副本集成员的优先级
当新成员过渡到 SECONDARY 状态后,就可以使用 “rs.reconfig()” 更新它的优先级(priority)和投票权(votes)了。
MongoDB Enterprise rs0:PRIMARY> cfg = rs.conf()
MongoDB Enterprise rs0:PRIMARY> cfg.members[0].priority=30
MongoDB Enterprise rs0:PRIMARY> cfg.members[1].priority=20
MongoDB Enterprise rs0:PRIMARY> cfg.members[2].priority=10
MongoDB Enterprise rs0:PRIMARY> rs.reconfig(cfg)
查看是否配置成功
MongoDB Enterprise rs0:PRIMARY> rs.conf()
{
"_id" : "rs0",
"version" : 4,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "192.168.10.140:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 30,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "192.168.10.141:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 20,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "192.168.10.142:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 10,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("6082313c333fd3f5243544dd")
}
}
7 测试数据同步是否正常
在主节点上写入数据
#创建库
MongoDB Enterprise rs0:PRIMARY> use test
#写入数据(10000条)
MongoDB Enterprise rs0:PRIMARY> for(var i=0;i<10000;i++){db.test.insert({"id":i,"name":"wpf","addr":"不黑","date":new Date()})}
#查看数据是否写入成功
MongoDB Enterprise rs0:PRIMARY> db.test.count()
10000
在从节点(secondary)上查看,数据是否同步
需要注意的是:默认情况下,副本集中的 secondary 成员是没有读权限的,在连接 mongodb 后,需要执行 "rs.slaveOk()"
才可以读。
为了不用每次登陆之后都执行 "rs.slaveOk()"
,我们可以将它写入到登陆用户家目录下的".mongorc.js"
文件中:echo "rs.slaveOk()" > .mongorc.js
#查看有哪些数据库
MongoDB Enterprise rs0:SECONDARY> show dbs
test 0.000GB
local 0.003GB
#进入 test 数据库
MongoDB Enterprise rs0:SECONDARY> use test
switched to db test
#查看有多少条数据
MongoDB Enterprise rs0:SECONDARY> db.test.count()
10000
至此,一个简单地 MongoDB 副本集就配置完了
附加:
为副本集添加仲裁者
仲裁者不需要专用硬件,可部署在资源较少的服务器。
仲裁者服务器可以将storage.journal.enabled
配置为 false,以尽量减少默认的数据创建;当然,也需要指定副本集名称。
MongoDB Enterprise rs0:PRIMARY> rs.addArb("192.168.10.142:27017")
{ "ok" : 1 }
为副本集配置隐藏成员
如果 settings.chainingAllowed
设置为 true (默认为true),表示允许辅助成员与其他辅助成员进行同步。默认情况下,MongoDB 在选择同步目标时会优先选择非隐藏成员而不是隐藏成员。所以,隐藏节点最常见的用途是支持延迟的成员。
配置隐藏成员,只需将 priority
设置为 0,hidden
设置为 true。例如:
MongoDB Enterprise rs0:PRIMARY> rs.status()
{
......
"members" : [
{
"_id" : 0,
"name" : "192.168.10.140:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
......
{
"_id" : 1,
"name" : "192.168.10.141:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
......
{
"_id" : 2,
"name" : "192.168.10.142:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
......
修改 “192.168.10.141” 为隐藏成员
cfg = rs.conf()
cfg.members[1].priority = 0
cfg.members[1].hidden = true
rs.reconfig(cfg)
配置为隐藏成员后,不会在 "db.isMaster()"
输出中显示
MongoDB Enterprise rs0:PRIMARY> db.isMaster()
{
"hosts" : [
"192.168.10.140:27017"
],
"arbiters" : [
"192.168.10.142:27017"
],
"setName" : "rs0",
"setVersion" : 4,
"ismaster" : true,
"secondary" : false,
"primary" : "192.168.10.140:27017",
"me" : "192.168.10.140:27017",
......
为副本集配置延迟成员
配置延迟成员,只需将 priority
设置为 0,hidden
设置为 true,并将其 slaveDelay
设置为要延迟的秒数。例如:
cfg = rs.conf()
cfg.members[1].priority = 0
cfg.members[1].hidden = true
cfg.members[1].slaveDelay = 3600
rs.reconfig(cfg)
查看副本集配置
MongoDB Enterprise rs0:PRIMARY> rs.conf()
......
{
"_id" : 1,
"host" : "192.168.10.141:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : true,
"priority" : 0,
"tags" : {
},
"slaveDelay" : NumberLong(3600),
"votes" : 0
},
......
删除副本集成员
使用 “rs.remove()” 删除
MongoDB Enterprise rs0:PRIMARY> rs.remove("192.168.10.141:27017");
{ "ok" : 1 }
使用 “rs.reconfig()” 删除
MongoDB Enterprise rs0:PRIMARY> var cfg = rs.conf()
MongoDB Enterprise rs0:PRIMARY> cfg.members.splice(1)
MongoDB Enterprise rs0:PRIMARY> rs.reconfig(cfg)
{ "ok" : 1 }