环境介绍:

ip 端口 ⻆色
192.168.1.153 27018 primary
192.168.1.154 27018 secondary
192.168.1.155 27018 secondary

副本集最多有 12 个成员(从 3.0 版本后最多支持 50 个成员),但最多 7个成员有投票权。

一、复制集部署

1.1 系统优化

echo "never" >/sys/kernel/mm/transparent_hugepage/enabled
echo "never" >/sys/kernel/mm/transparent_hugepage/defrag

1.2 下载文件:

cd /data/download
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-6.0.16.tgz
tar zxvf mongodb-linux-x86_64-rhel70-6.0.16.tgz
mkdir -p /data/mongodb/mongodb_repl
cp -r /data/download/mongodb-linux-x86_64-rhel70-6.0.16/bin /data/mongodb/mongodb_repl/bin

1.3 新建mongo目录

cd /data/mongodb/mongodb_repl
mkdir -p {auth,conf,data,log}

1.4 生产key认证文件

echo "mongodb123456" > /data/mongodb/mongodb_repl/auth/keyfile.key
cd /data/mongodb/mongodb_repl
chmod 400 auth/keyfile.key   #设置文件的权限为400,不然服务无法启动

1.5 配置生成

配置文件

根据需求修改相应参数:

# cat > /data/mongodb/mongodb_repl/conf/mongo_27018.conf <<EOF
systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/mongodb_repl/log/mongo_27018.log
storage:
  dbPath: /data/mongodb/mongodb_repl/data
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
      directoryForIndexes: true
      cacheSizeGB: 1
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /data/mongodb/mongodb_repl/mongo_27018.pid
  timeZoneInfo: /usr/share/zoneinfo
net:
  port: 27018
  bindIp: 0.0.0.0
  #bindIpAll: true
  maxIncomingConnections: 5000
  unixDomainSocket:
    enabled: true
    pathPrefix: /data/mongodb/mongodb_repl/data
    filePermissions: 0700
security:
  keyFile: /data/mongodb/mongodb_repl/auth/keyfile.key
  authorization: enabled
replication:
  replSetName: repl
EOF

1.6 修改权限:

useradd mongodb
chown -R mongodb:mongodb /data/mongodb

1.7 集群启动

# chown -R mongodb.mongodb mongodb/
# su - mongodb
# /data/mongodb/mongodb_repl/bin/mongod -f /data/mongodb/mongodb_repl/conf/mongo_27018.conf

1.8 初始化存储集群 ,配置为 replica set

该方式配置完后,arbiter节点无密码,primary和secondary有密码且密码一致

--初始化存储集群
--登录
[root@vm-test01 conf]# mongo --port=27018
# 配置
> config = { _id:"repl",members:[{_id:0,host:"192.168.1.153:27018"},{_id:1,host:"192.168.1.154:27018"},{_id:2,host:"192.168.1.155:27018",arbiterOnly:true}] }
#初始化
> rs.initiate(config)
{ "ok" : 1 }

结果输出如上,说明集群初始化成功,可以通过 rs.status()命令查看集群状态(88为 primary,89为 secondary,90为 arbiter)

1.9 账号开通

也可以在登录数据库时就进行认证

--管理账号
use admin
db.createUser(
  {
    user: "root",
    pwd: "root123456",
    roles: [ { role: "root", db: "admin" } ]
  }
)
[mongo@HEl ~]$ mongo 127.0.0.1:27018/admin -uroot -proot123456
-- 使用副本集方式登录
[mongo@HEl ~]$ mongo --host repl/192.168.1.153:27018,192.168.1.154:27018,192.168.1.155:27018 -uroot -proot123456 --authenticationDatabase admin

能够看到副本集状态己经完成,其中 192.168.1.153:27018 PRIMARY, 192.168.1.154:27018 192.168.1.155:27018 arbitor:

repl:PRIMARY> rs.status()
{
  "set" : "repl",
  "date" : ISODate("2022-10-17T06:38:56.687Z"),
  "myState" : 1,
  "term" : NumberLong(1),
  "syncSourceHost" : "",
  "syncSourceId" : -1,
  "heartbeatIntervalMillis" : NumberLong(2000),
  "majorityVoteCount" : 2,
  "writeMajorityCount" : 2,
  "votingMembersCount" : 3,
  "writableVotingMembersCount" : 2,
  "members" : [
    {
      "_id" : 0,
      "name" : "192.168.1.153:27018",  //name是副本集节点的ip和端口信息
      "health" : 1,    //副本集中该节点是否正常,0表示不正常,1表示正常
      "state" : 1,
      "stateStr" : "PRIMARY",
      "uptime" : 1001,  //从成员可到达一直到现在经历的时间,单位是秒。
      "optime" : {
        "ts" : Timestamp(1665988735, 1),
        "t" : NumberLong(1)
      },
      "optimeDate" : ISODate("2022-10-17T06:38:55Z"),  //每个成员oplog最后一次操作发生的时间,这个时间是心跳报上来的,因此可能会存在延迟
      "lastAppliedWallTime" : ISODate("2022-10-17T06:38:55.494Z"),
      "lastDurableWallTime" : ISODate("2022-10-17T06:38:55.494Z"),
      "syncSourceHost" : "",
      "syncSourceId" : -1,
      "infoMessage" : "",
      "electionTime" : Timestamp(1665988655, 1),
      "electionDate" : ISODate("2022-10-17T06:37:35Z"),
      "configVersion" : 1,
      "configTerm" : 1,
      "self" : true, //这个信息出现在执行rs.status()函数的成员信息中
      "lastHeartbeatMessage" : ""
    },
    {
      "_id" : 1,
      "name" : "192.168.1.154:27018",
      "health" : 1,
      "state" : 2,
      "stateStr" : "SECONDARY",
      "uptime" : 91,
      "optime" : {
        "ts" : Timestamp(1665988716, 4),
        "t" : NumberLong(1)
      },
      "optimeDurable" : {
        "ts" : Timestamp(1665988716, 4),
        "t" : NumberLong(1)
      },
      "optimeDate" : ISODate("2022-10-17T06:38:36Z"),
      "optimeDurableDate" : ISODate("2022-10-17T06:38:36Z"),
      "lastAppliedWallTime" : ISODate("2022-10-17T06:38:55.494Z"),
      "lastDurableWallTime" : ISODate("2022-10-17T06:38:55.494Z"),
      "lastHeartbeat" : ISODate("2022-10-17T06:38:55.465Z"),  //当前服务器最后一次收到其他成员心跳的时间,如果网络故障等可能这个时间会大于2秒
      "lastHeartbeatRecv" : ISODate("2022-10-17T06:38:54.964Z"),
      "pingMs" : NumberLong(0), //心跳从当前服务器达到某个成员所花费的平均时间
      "lastHeartbeatMessage" : "",
      "syncSourceHost" : "192.168.1.153:27018",
      "syncSourceId" : 0,
      "infoMessage" : "",
      "configVersion" : 1,
      "configTerm" : 1
    },
    {
      "_id" : 2,
      "name" : "192.168.1.155:27018",
      "health" : 1,
      "state" : 7,
      "stateStr" : "ARBITER",
      "uptime" : 91,
      "lastHeartbeat" : ISODate("2022-10-17T06:38:55.464Z"),
      "lastHeartbeatRecv" : ISODate("2022-10-17T06:38:55.485Z"),
      "pingMs" : NumberLong(0),
      "lastHeartbeatMessage" : "",
      "syncSourceHost" : "",
      "syncSourceId" : -1,
      "infoMessage" : "",
      "configVersion" : 1,
      "configTerm" : 1
    }
  ],
  "ok" : 1,
  "$clusterTime" : {
    "clusterTime" : Timestamp(1665988735, 1),
    "signature" : {
      "hash" : BinData(0,"EB8KP7QOkyeGHwCI6yhRu7K/Tk0="),
      "keyId" : NumberLong("7155366788732026884")
    }
  },
  "operationTime" : Timestamp(1665988735, 1)
}

二、复制集测试

repl:PRIMARY> user test
repl:PRIMARY> db.movies.insert([ { "title" : "Jaws", "year" : 1975, "imdb_rating" : 8.1 },{ "title" : "Batman", "year" : 1989, "imdb_rating" : 7.6 }] );
--从节点查看数据
--注:在 mongodb复制集当中,默认从库不允许读写。
$ /data/mongodb/mongodb_repl/bin/mongo 192.168.1.154:27018/admin -uroot -proot123456
repl:SECONDARY> rs.secondaryOk()
repl:SECONDARY> show tables;
movies
repl:SECONDARY> db.movies.find()
{ "_id" : ObjectId("634cfcf73eb072ed9bcfb1ac"), "title" : "Batman", "year" : 1989, "imdb_rating" : 7.6 }
{ "_id" : ObjectId("634cfcf73eb072ed9bcfb1ab"), "title" : "Jaws", "year" : 1975, "imdb_rating" : 8.1 }

2.1 查看复制集的从库状态信息(延迟、成员):

repl:PRIMARY> rs.printSecondaryReplicationInfo()
source: 192.168.1.154:27018
  syncedTo: Mon Oct 17 2023 14:54:15 GMT+0800 (CST)
  0 secs (0 hrs) behind the primary

2.2 查看复制集 oplog信息:

repl:PRIMARY> rs.printReplicationInfo()
configured oplog size:  1166.24609375MB
log length start to end: 1031secs (0.29hrs)
oplog first event time:  Mon Oct 17 2023 14:37:24 GMT+0800 (CST)
oplog last event time:  Mon Oct 17 2023 14:54:35 GMT+0800 (CST)
now:           Mon Oct 17 2023 14:54:41 GMT+0800 (CST)

三、复制集管理操作

(1)查看复制集状态:

rs.status();   //查看整体复制集状态
rs.isMaster(); // 查看当前是否是主节点

(2)添加删除节点

rs.add("ip:port"); // 新增从节点
rs.addArb("ip:port"); // 新增仲裁节点
rs.remove("ip:port"); // 删除一个节点

(3)特殊从节点的配置

  • 优先级( priority 参数: 0-1000):

优先级越高的节点越优先成为主节点。

优先级为 0的节点无法成为主节点;

  • 隐藏( hidden 参数):复制数据,但对应用不可⻅。隐藏节点可以具有投票仅,但优先级必须为 0;
  • 延迟( slaveDelay 参数):复制 n 秒之前的数据,保持与主节点的时间差。

配置延时节点(一般延时节点也配置成 hidden)

cfg=rs.conf()
cfg.members[1].priority=0
cfg.members[1].slaveDelay=120
cfg.members[1].hidden=true
rs.reconfig(cfg)

改回来:

cfg=rs.conf()
cfg.members[2].priority=1
cfg.members[2].slaveDelay=0
cfg.members[2].hidden=0
cfg.members[2].votes=0
rs.reconfig(cfg)

配置成功后,通过以下命令查询配置后的属性

rs.conf();

(4)副本集其他常用操作命令

admin> rs.config()
admin> rs.status()
admin> rs.stepDown()
admin> rs.freeze(300) //锁定从,使其不会转变成主库
admin> rs.slaveOk()
repl:PRIMARY> rs.printSecondaryReplicationInfo()
source: 192.168.1.154:27018
  syncedTo: Mon Oct 17 2023 15:10:25 GMT+0800 (CST)
  0 secs (0 hrs) behind the primary

注:freeze()和 stepDown单位都是秒。