作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)
公众号:老苏畅谈运维
欢迎关注本人公众号,更多精彩与您分享。
一、项目背景
由于历史原因,生产环境中MongoDB使用的是单节点。但随着业务增长,考虑到这个同步业务的重要性,避免由于单节点故障造成业务停止,所以需要升级为副本集保证高可用。
下面这架构图是需要实现的MongoDB副本集高可用架构:
Relica Set副本集方式整体大概如图:
二、 升级架构前注意事项
在生产环境中,做单节点升级到集群前,一定要先备份好mongodb的所有数据,避免操作失误导致数据丢失。
并且在保证在升级期间不会有程序连接到MongoDB进行读写操作,建议停服务升级,且在凌晨业务低峰期,进行操作。
–使用mongodump进行全库备份
mongodump -uroot -p123456 --port 27017 --authenticationDatabase admin -j 2 -o /media/backup/full/$(date +%Y%m%d)
三、 原单节点MongoDB配置信息
角色 | IP |
---|---|
单节点 | IP:10.10.10.45 端口:27017 |
该节点配置信息:
# cat /etc/mongod.conf |grep -v '^#'systemLog:destination: filelogAppend: truepath: /var/log/mongodb/mongod.logstorage:dbPath: /var/lib/mongojournal:enabled: trueprocessManagement:timeZoneInfo: /usr/share/zoneinfonet:port: 27017#bindIp: 127.0.0.1 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.bindIp: 0.0.0.0
修改该配置文件增加副本集配置
# cat /etc/mongod.conf |grep -v '^#'systemLog:destination: filelogAppend: truepath: /var/log/mongodb/mongod.logstorage:dbPath: /var/lib/mongojournal:enabled: trueprocessManagement:timeZoneInfo: /usr/share/zoneinfonet:port: 27017#bindIp: 127.0.0.1 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.bindIp: 0.0.0.0replication:oplogSizeMB: 4096replSetName: rs
四、新增节点信息
角色 | IP |
---|---|
新增从节点 | IP:10.10.10.46 端口:27017 |
新增仲裁节点 | IP:10.10.10.47 端口:27017 |
这两个节点配置文件,只需复制PRIMARY节点配置文件,并修改相应的 "bindIp"即可。
从节点配置:
# cat /etc/mongod.conf |grep -v '^#'systemLog:destination: filelogAppend: truepath: /var/log/mongodb/mongod.logstorage:dbPath: /var/lib/mongojournal:enabled: trueprocessManagement:timeZoneInfo: /usr/share/zoneinfonet:port: 27017#bindIp: 127.0.0.1 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.bindIp: 0.0.0.0replication:oplogSizeMB: 4096replSetName: rs
仲裁节点配置:
# cat /etc/mongod.conf |grep -v '^#'systemLog:destination: filelogAppend: truepath: /var/log/mongodb/mongod.logstorage:dbPath: /var/lib/mongojournal:enabled: trueprocessManagement:timeZoneInfo: /usr/share/zoneinfonet:port: 27017#bindIp: 127.0.0.1 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.bindIp: 0.0.0.0replication:oplogSizeMB: 4096replSetName: rs
启动3个节点:要先启动PRIMARY节点,2个SECONDARY节点后面启动。
# systemctl start mongod
五、 初始化副本集
使用mongo shell连接到主节点,执行初始化命令
test> use admin
switched to db admin
admin>
config = {_id : "rs", members : [{_id:0, host:"10.10.10.45:27017"},{_id:1, host:"10.10.10.46:27017"},{_id:2, host:"10.10.10.47:27017", arbiterOnly: true},]
}> rs.initiate(config) //初始化副本集
{ ok: 1 } //返回ok:1成功,返回ok:0失败
• 查看集群状态信息
rs [direct: secondary] admin> rs.status()
{set: 'rs',date: ISODate('2024-07-06T08:56:17.985Z'),myState: 1,term: Long('1'),syncSourceHost: '',syncSourceId: -1,heartbeatIntervalMillis: Long('2000'),majorityVoteCount: 2,writeMajorityCount: 2,votingMembersCount: 3,writableVotingMembersCount: 2,optimes: {lastCommittedOpTime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },lastCommittedWallTime: ISODate('2024-07-06T08:56:09.745Z'),readConcernMajorityOpTime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },appliedOpTime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },durableOpTime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },lastAppliedWallTime: ISODate('2024-07-06T08:56:09.745Z'),lastDurableWallTime: ISODate('2024-07-06T08:56:09.745Z')},lastStableRecoveryTimestamp: Timestamp({ t: 1720256159, i: 1 }),electionCandidateMetrics: {lastElectionReason: 'electionTimeout',lastElectionDate: ISODate('2024-07-06T08:54:19.727Z'),electionTerm: Long('1'),lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 1720256048, i: 1 }), t: Long('-1') },lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1720256048, i: 1 }), t: Long('-1') },numVotesNeeded: 2,priorityAtElection: 1,electionTimeoutMillis: Long('10000'),numCatchUpOps: Long('0'),newTermStartDate: ISODate('2024-07-06T08:54:19.734Z'),wMajorityWriteAvailabilityDate: ISODate('2024-07-06T08:54:20.619Z')},members: [{_id: 0,name: '10.10.10.45:27017',health: 1,state: 1,stateStr: 'PRIMARY',uptime: 449,optime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },optimeDate: ISODate('2024-07-06T08:56:09.000Z'),lastAppliedWallTime: ISODate('2024-07-06T08:56:09.745Z'),lastDurableWallTime: ISODate('2024-07-06T08:56:09.745Z'),syncSourceHost: '',syncSourceId: -1,infoMessage: '',electionTime: Timestamp({ t: 1720256059, i: 1 }),electionDate: ISODate('2024-07-06T08:54:19.000Z'),configVersion: 1,configTerm: 1,self: true,lastHeartbeatMessage: ''},{_id: 1,name: '10.10.10.46:27017',health: 1,state: 2,stateStr: 'SECONDARY',uptime: 129,optime: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },optimeDurable: { ts: Timestamp({ t: 1720256169, i: 1 }), t: Long('1') },optimeDate: ISODate('2024-07-06T08:56:09.000Z'),optimeDurableDate: ISODate('2024-07-06T08:56:09.000Z'),lastAppliedWallTime: ISODate('2024-07-06T08:56:09.745Z'),lastDurableWallTime: ISODate('2024-07-06T08:56:09.745Z'),lastHeartbeat: ISODate('2024-07-06T08:56:17.775Z'),lastHeartbeatRecv: ISODate('2024-07-06T08:56:16.777Z'),pingMs: Long('0'),lastHeartbeatMessage: '',syncSourceHost: '10.10.10.45:27017',syncSourceId: 0,infoMessage: '',configVersion: 1,configTerm: 1},{_id: 2,name: '10.10.10.47:27017',health: 1,state: 7,stateStr: 'ARBITER',uptime: 129,lastHeartbeat: ISODate('2024-07-06T08:56:17.776Z'),lastHeartbeatRecv: ISODate('2024-07-06T08:56:17.775Z'),pingMs: Long('0'),lastHeartbeatMessage: '',syncSourceHost: '',syncSourceId: -1,infoMessage: '',configVersion: 1,configTerm: 1}],ok: 1,'$clusterTime': {clusterTime: Timestamp({ t: 1720256169, i: 1 }),signature: {hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),keyId: Long('0')}},operationTime: Timestamp({ t: 1720256169, i: 1 })
}
查看从库延时信息
rs [direct: primary] admin> rs.printSecondaryReplicationInfo()
source: 10.10.10.46:27017
{syncedTo: 'Sat Jul 06 2024 16:57:29 GMT+0800 (China Standard Time)',replLag: '0 secs (0 hrs) behind the primary '
}
上面看到从库已经完全同步,没有延时。
六、测试数据
–主库插入数据
rs [direct: primary] admin> for(i=0;i<1000;i++){db.log.insert({"uid":i,"name":"mongodb","age":6})};
DeprecationWarning: Collection.insert() is deprecated. Use insertOne, insertMany, or bulkWrite.
{acknowledged: true,insertedIds: { '0': ObjectId('6689087d597863336614a32f') }
}
rs [direct: primary] admin> show tables;
log
mycollection
system.keys
system.users
system.version
–从库上查看数据
rs [direct: secondary] admin> show tables;
log
mycollection
system.keys
system.users
system.version
rs [direct: secondary] admin> db.log.find().count()
1000
由此可以看出,主从节点数据同步正常。
关注我,学习更多数据库知识。