集群类型
- 单机模式:一台机器对外提供服务;
- 集群模式:多台机器对外提供同一服务;
- 伪集群模式:单台机器上启动多个实例,模拟多机器场景对外提供服务。
规划
操作系统 | 节点IP | 端口 | 作用 | Mongo版本 | 数据目录 | 日志目录 | 配置目录 |
---|---|---|---|---|---|---|---|
rocky9.4 | 192.168.0.238 | 27017 | 主节点 | 8.0.1 | /data/mongo/data | /data/mongo/logs | /data/mongo/conf |
rocky9.4 | 192.168.0.239 | 27017 | 副本节点 | 8.0.1 | /data/mongo/data | /data/mongo/logs | /data/mongo/conf |
rocky9.4 | 192.168.0.240 | 27017 | 仲裁节点 | 8.0.1 | /data/mongo/data | /data/mongo/logs | /data/mongo/conf |
搭建
-
所有节点均需执行:
mkdir /data/mongo/{data,logs,conf} -p dnf install libcurl openssl xz-libs cd /usr/local/src wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel93-8.0.1.tgz tar xzvf mongodb-linux-x86_64-rhel93-8.0.1.tgz cd mongodb-linux-x86_64-rhel93-8.0.1 cp bin/{mongod,mongos} /usr/local/bin/
-
主节点配置文件准备:
# 主节点操作 vim /data/mongo/conf/mongo-master.conf # MongoDB日志存储相关配置 systemLog: # 将所有日志写到指定文件中 destination: file # 记录所有日志信息的文件路径 path: "/data/mongo/logs/mongo.log" # 当服务重启时,将新日志以追加形式写到现有日志尾部 logAppend: true storage: # 指定MongoDB存储数据的目录 dbPath: "/data/mongo/data" processManagement: # 以后台进程方式运行MongoDB服务 fork: true # 指定保存mongo进程ID的文件位置 pidFilePath: "/data/mongo/mongo.pid" net: # 绑定服务实例的IP,默认是localhost,这里换成本机IP bindIp: 192.168.0.238 #绑定的端口,默认是27017 port: 27017 replication: # 指定副本集群的名称 replSetName: mongo-set
-
启动主节点服务
# 主节点操作 mongod -f /data/mongo/conf/mongo-master.conf # 这里死活执行不成功,报Illegal instruction (core dumped),更换7.0.15 8.0.3版本均无效,原因为mongo5.x后需要avx指令集,查询cpu后发现支持, # 但pve虚拟化默认为x86-64-v2-AES模式,此模式默认不会将新的指令集开放给虚拟机。需要关闭虚拟机对cpu模式进行修改,修改为host模式。 # 查看端口是否被监听 netstat -lanp | grep 27017 echo 'mongod -f /data/mongo/conf/mongo-master.conf' >> /etc/rc.local
-
从节点配置文件准备
# 从节点操作 vim /data/mongo/conf/mongo-slave.conf # MongoDB日志存储相关配置 systemLog: # 将所有日志写到指定文件中 destination: file # 记录所有日志信息的文件路径 path: "/data/mongo/logs/mongo.log" # 当服务重启时,将新日志以追加形式写到现有日志尾部 logAppend: true storage: # 指定MongoDB存储数据的目录 dbPath: "/data/mongo/data" processManagement: # 以后台进程方式运行MongoDB服务 fork: true # 指定保存mongo进程ID的文件位置 pidFilePath: "/data/mongo/mongo.pid" net: # 绑定服务实例的IP,默认是localhost,这里换成本机IP bindIp: 192.168.0.239 #绑定的端口,默认是27017 port: 27017 replication: # 指定副本集群的名称 replSetName: mongo-set
-
启动从节点服务
# 从节点操作 mongod -f /data/mongo/conf/mongo-slave.conf # 查看端口是否被监听 netstat -lanp | grep 27017 echo 'mongod -f /data/mongo/conf/mongo-slave.conf' >> /etc/rc.local
-
仲裁节点配置文件准备
# 仲裁节点操作 vim /data/mongo/conf/mongo-arbit.conf # MongoDB日志存储相关配置 systemLog: # 将所有日志写到指定文件中 destination: file # 记录所有日志信息的文件路径 path: "/data/mongo/logs/mongo.log" # 当服务重启时,将新日志以追加形式写到现有日志尾部 logAppend: true storage: # 指定MongoDB存储数据的目录 dbPath: "/data/mongo/data" processManagement: # 以后台进程方式运行MongoDB服务 fork: true # 指定保存mongo进程ID的文件位置 pidFilePath: "/data/mongo/mongo.pid" net: # 绑定服务实例的IP,默认是localhost,这里换成本机IP bindIp: 192.168.0.240 #绑定的端口,默认是27017 port: 27017 replication: # 指定副本集群的名称 replSetName: mongo-set
-
启动仲裁节点服务
# 从节点操作 mongod -f /data/mongo/conf/mongo-arbit.conf # 查看端口是否被监听 netstat -lanp | grep 27017 echo 'mongod -f /data/mongo/conf/mongo-arbit.conf' >> /etc/rc.local
-
初始化
通过mongosh客户端工具连接主节点,初始化副本集群# 主节点操作 wget https://downloads.mongodb.com/compass/mongosh-2.3.3-linux-x64.tgz tar xzvf mongosh-2.3.3-linux-x64.tgz cd mongosh-2.3.3-linux-x64/bin [root@rocky238 bin]# ./mongosh 192.168.0.238:27017 Current Mongosh Log ID: 67370968a68cd32f6dc1c18b Connecting to: mongodb://192.168.0.238:27017/?directConnection=true&appName=mongosh+2.3.3 Using MongoDB: 8.0.1 Using Mongosh: 2.3.3 For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/ To help improve our products, anonymous usage data is collected and sent to MongoDB periodically (https://www.mongodb.com/legal/privacy-policy). You can opt-out by running the disableTelemetry() command. ------ The server generated these startup warnings when booting 2024-11-15T16:06:51.332+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted 2024-11-15T16:06:51.332+08:00: You are running this process as the root user, which is not recommended 2024-11-15T16:06:51.332+08:00: Soft rlimits for open file descriptors too low 2024-11-15T16:06:51.332+08:00: For customers running the current memory allocator, we suggest changing the contents of the following sysfsFile 2024-11-15T16:06:51.332+08:00: For customers running the current memory allocator, we suggest changing the contents of the following sysfsFile 2024-11-15T16:06:51.332+08:00: We suggest setting the contents of sysfsFile to 0. 2024-11-15T16:06:51.332+08:00: Your system has glibc support for rseq built in, which is not yet supported by tcmalloc-google and has critical performance implications. Please set the environment variable GLIBC_TUNABLES=glibc.pthread.rseq=0 2024-11-15T16:06:51.332+08:00: We suggest setting swappiness to 0 or 1, as swapping can cause performance problems. ------ test> rs.initiate(); { info2: 'no configuration specified. Using a default configuration for the set', me: '192.168.0.238:27017', ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1731660169, i: 1 }), signature: { hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0), keyId: Long('0') } }, operationTime: Timestamp({ t: 1731660169, i: 1 }) } # 添加从节点 mongo-set [direct: secondary] test> rs.add("192.168.0.239:27017") { ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1731660268, i: 1 }), signature: { hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0), keyId: Long('0') } }, operationTime: Timestamp({ t: 1731660268, i: 1 }) } # 修改写关注级别 mongo-set [direct: primary] test> db.adminCommand({ ... "setDefaultRWConcern" : 1, ... "defaultWriteConcern" : { ... "w" : "majority" ... } ... }); { defaultReadConcern: { level: 'local' }, defaultWriteConcern: { w: 'majority', wtimeout: 0 }, updateOpTime: Timestamp({ t: 1731660359, i: 1 }), updateWallClockTime: ISODate('2024-11-15T08:46:04.016Z'), defaultWriteConcernSource: 'global', defaultReadConcernSource: 'implicit', localUpdateWallClockTime: ISODate('2024-11-15T08:46:04.032Z'), ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1731660364, i: 2 }), signature: { hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0), keyId: Long('0') } }, operationTime: Timestamp({ t: 1731660364, i: 2 }) } # 添加仲裁节点 mongo-set [direct: primary] test> rs.addArb("192.168.0.240:27017") { ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1731660394, i: 1 }), signature: { hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0), keyId: Long('0') } }, operationTime: Timestamp({ t: 1731660394, i: 1 }) } # 查看集群状态 mongo-set [direct: primary] test> rs.conf() { _id: 'mongo-set', version: 4, term: 1, members: [ { _id: 0, host: '192.168.0.238:27017', arbiterOnly: false, buildIndexes: true, hidden: false, priority: 1, tags: {}, secondaryDelaySecs: Long('0'), votes: 1 }, { _id: 1, host: '192.168.0.239:27017', arbiterOnly: false, buildIndexes: true, hidden: false, priority: 1, tags: {}, secondaryDelaySecs: Long('0'), votes: 1 }, { _id: 2, host: '192.168.0.240:27017', arbiterOnly: true, buildIndexes: true, hidden: false, priority: 0, tags: {}, secondaryDelaySecs: Long('0'), votes: 1 } ], protocolVersion: Long('1'), writeConcernMajorityJournalDefault: true, settings: { chainingAllowed: true, heartbeatIntervalMillis: 2000, heartbeatTimeoutSecs: 10, electionTimeoutMillis: 10000, catchUpTimeoutMillis: -1, catchUpTakeoverDelayMillis: 30000, getLastErrorModes: {}, getLastErrorDefaults: { w: 1, wtimeout: 0 }, replicaSetId: ObjectId('6737098922b6337a0182820d') } } mongo-set [direct: primary] test> rs.status() { set: 'mongo-set', date: ISODate('2024-11-15T08:47:56.103Z'), myState: 1, term: Long('1'), syncSourceHost: '', syncSourceId: -1, heartbeatIntervalMillis: Long('2000'), majorityVoteCount: 2, writeMajorityCount: 2, votingMembersCount: 3, writableVotingMembersCount: 2, optimes: { lastCommittedOpTime: { ts: Timestamp({ t: 1731660469, i: 1 }), t: Long('1') }, lastCommittedWallTime: ISODate('2024-11-15T08:47:49.824Z'), readConcernMajorityOpTime: { ts: Timestamp({ t: 1731660469, i: 1 }), t: Long('1') }, appliedOpTime: { ts: Timestamp({ t: 1731660469, i: 1 }), t: Long('1') }, durableOpTime: { ts: Timestamp({ t: 1731660469, i: 1 }), t: Long('1') }, writtenOpTime: { ts: Timestamp({ t: 1731660469, i: 1 }), t: Long('1') }, lastAppliedWallTime: ISODate('2024-11-15T08:47:49.824Z'), lastDurableWallTime: ISODate('2024-11-15T08:47:49.824Z'), lastWrittenWallTime: ISODate('2024-11-15T08:47:49.824Z') }, lastStableRecoveryTimestamp: Timestamp({ t: 1731660469, i: 1 }), electionCandidateMetrics: { lastElectionReason: 'electionTimeout', lastElectionDate: ISODate('2024-11-15T08:42:49.770Z'), electionTerm: Long('1'), lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 1731660169, i: 1 }), t: Long('-1') }, lastSeenWrittenOpTimeAtElection: { ts: Timestamp({ t: 1731660169, i: 1 }), t: Long('-1') }, lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1731660169, i: 1 }), t: Long('-1') }, numVotesNeeded: 1, priorityAtElection: 1, electionTimeoutMillis: Long('10000'), newTermStartDate: ISODate('2024-11-15T08:42:49.805Z'), wMajorityWriteAvailabilityDate: ISODate('2024-11-15T08:42:49.877Z') }, members: [ { _id: 0, name: '192.168.0.238:27017', health: 1, state: 1, stateStr: 'PRIMARY', uptime: 2466, optime: { ts: Timestamp({ t: 1731660469, i: 1 }), t: Long('1') }, optimeDate: ISODate('2024-11-15T08:47:49.000Z'), optimeWritten: { ts: Timestamp({ t: 1731660469, i: 1 }), t: Long('1') }, optimeWrittenDate: ISODate('2024-11-15T08:47:49.000Z'), lastAppliedWallTime: ISODate('2024-11-15T08:47:49.824Z'), lastDurableWallTime: ISODate('2024-11-15T08:47:49.824Z'), lastWrittenWallTime: ISODate('2024-11-15T08:47:49.824Z'), syncSourceHost: '', syncSourceId: -1, infoMessage: '', electionTime: Timestamp({ t: 1731660169, i: 2 }), electionDate: ISODate('2024-11-15T08:42:49.000Z'), configVersion: 4, configTerm: 1, self: true, lastHeartbeatMessage: '' }, { _id: 1, name: '192.168.0.239:27017', health: 1, state: 2, stateStr: 'SECONDARY', uptime: 207, optime: { ts: Timestamp({ t: 1731660469, i: 1 }), t: Long('1') }, optimeDurable: { ts: Timestamp({ t: 1731660469, i: 1 }), t: Long('1') }, optimeWritten: { ts: Timestamp({ t: 1731660469, i: 1 }), t: Long('1') }, optimeDate: ISODate('2024-11-15T08:47:49.000Z'), optimeDurableDate: ISODate('2024-11-15T08:47:49.000Z'), optimeWrittenDate: ISODate('2024-11-15T08:47:49.000Z'), lastAppliedWallTime: ISODate('2024-11-15T08:47:49.824Z'), lastDurableWallTime: ISODate('2024-11-15T08:47:49.824Z'), lastWrittenWallTime: ISODate('2024-11-15T08:47:49.824Z'), lastHeartbeat: ISODate('2024-11-15T08:47:54.476Z'), lastHeartbeatRecv: ISODate('2024-11-15T08:47:54.475Z'), pingMs: Long('0'), lastHeartbeatMessage: '', syncSourceHost: '192.168.0.238:27017', syncSourceId: 0, infoMessage: '', configVersion: 4, configTerm: 1 }, { _id: 2, name: '192.168.0.240:27017', health: 1, state: 7, stateStr: 'ARBITER', uptime: 81, lastHeartbeat: ISODate('2024-11-15T08:47:54.489Z'), lastHeartbeatRecv: ISODate('2024-11-15T08:47:54.490Z'), pingMs: Long('0'), lastHeartbeatMessage: '', syncSourceHost: '', syncSourceId: -1, infoMessage: '', configVersion: 4, configTerm: 1 } ], ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1731660469, i: 1 }), signature: { hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0), keyId: Long('0') } }, operationTime: Timestamp({ t: 1731660469, i: 1 }) }
-
账号密码配置
需要开启认证权限控制:用于自管理部署的运行时数据库配置 - MongoDB 手册 v8.0
mongo-set [direct: primary] test> use admin; switched to db admin mongo-set [direct: primary] admin> db.createUser({"user":"root", "pwd":"YOUR_PASSWORD", "roles":["root"]}); { ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1731660809, i: 5 }), signature: { hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0), keyId: Long('0') } }, operationTime: Timestamp({ t: 1731660809, i: 5 }) }