本篇文章主要介绍在麒麟服务操作系统上安装mongodb7.0.6集群,服务采用3个节点安装方式,一主两从,正常应该在3台服务器上各安装一个节点,文章里使用两台服务器。

安装准备
服务器配置:
| 主机 | ip | 服务 |
|---|---|---|
| 服务器A | 192.168.215.23 | 主节点(30000) |
| 服务器B | 192.168.215.24 | 两个从节点(30000、30001) |
安装包:mongodb-linux-x86_64-rhel80-7.0.6.tgz, mongosh-1.6.0-linux-x64.tgz
注:这里选择rhel80的安装包,如选择其它版本请在安全前确认好系统的OpenSSL库版本与mongodb的OpenSSL库版本一致
开始安装
服务器A新建目录/opt/software/mongodb,将mongodb-linux-x86_64-rhel80-7.0.6.tgz, mongosh-1.6.0-linux-x64.tgz拷入服务器A的/opt/software/mongodb目录下并解压,在当前目录新建如下目录:
log: 日志文件路径conf: 配置文件路径key: 存放密钥的目录db30000:数据库路径
/opt/software/mongodb/conf内容:
#复制集
configsvr=true
# 数据库目录
dbpath=/opt/software/mongodb/db30000
# 日志文件
logpath=/opt/software/mongodb/log/db30000.log
# 进程描述文件
#pidfilepath=log\db50001.pid
bind_ip=192.168.215.23
# 为数据库自动提供重定向
directoryperdb=true
# 日志追加写入
logappend=true
# 复制集名称,一个复制集中的多个节点命名一致
replSet=cmdReplSet
# 端口
port=30000
# 操作日志容量(MB)
oplogSize=10000
# 后台启动
#fork=true
# 预分配方式 默认false
#noprealloc=true
# 默认存储引擎,提供高性能、高并发
storageEngine=wiredTiger
# 使用内存
wiredTigerCacheSizeGB=4
# 最大连接数
maxConns=2000
# 证书
#keyFile=/opt/software/mongodb/key/access.key
# 权限验证
#auth=true
新建/opt/software/mongodb/db30000.sh文件作为启动脚本,后续可以配置成服务启动:
shell
./mongodb-linux-x86_64-rhel80-7.0.6/bin/mongod --config ./conf/db30000.conf
指定权限为755(rwxr-xr-x):
shell
chmod 755 db30000.sh
关闭防火墙:
shell
sudo systemctl status firewalld
sudo systemctl stop firewalld
sudo systemctl disable firewalld
在服务器B 上新建目录/opt/software/mongodb1和/opt/software/mongodb2重复以上操作 ,mongosh可以不需要拷贝到服务器B上,需要修改配置文件中的:数据库目录、日志文件目录、ip地址,启动脚本中的路径。
在服务器A和服务器B上分别执行启动脚本:./db30000.sh,./db30000.sh, ./db30001.sh,通过ps -ef | grep mongod,服务器B上会显示两个进程。
进入/opt/software/mongodb/mongosh-1.6.0-linux-x64/bin使用mongosh创建集群:
shell
./mongosh --host 192.168.215.23 --port 30000
由于上面配置文件中没有开启权限认证这里可以直接进入,等把所需用户创建好之后再开启权限认证
shell
use admin
rs.initiate(
{ _id:"cmdReplSet", members:[
{_id:0,host:'192.168.215.23:30000', priority: 2},
{_id:1,host:'192.168.215.24:30000', priority: 1},
{_id:2,host:'192.168.215.24:30001', priority: 1}
]
}
);
# mongo根据priority的优先级选举主节点,越高优先级越高
# 创建两个用户,一个是系统用户,一个是指定是testdb的数据库用户
db.createUser({user:"mongo_system", pwd:"321123@123456",roles:[{role:"__system",db:"admin"}],mechanisms:["SCRAM-SHA-1"]});
db.createUser({user:"mongo_user1", pwd:"321123@123456",roles:[{role:"readWrite",db:"test"},{role:"dbAdmin",db:"test"}],mechanisms:["SCRAM-SHA-1"] } );
# 授予集群监控权限
db.grantRolesToUser("mongo_system", [ "clusterMonitor" ])
db.grantRolesToUser("mongo_user1", [ "clusterMonitor" ])
# 创建完用户可以登录查看集群状态,看是否可以正常使用
db.auth("myroot", "password")
查看集群状态:
shell
rs.status()
结果如下:
json
{
set: 'cmdReplSet',
date: 2025-12-12T16:27:48.730Z,
myState: 1,
term: Long('8'),
syncSourceHost: '',
syncSourceId: -1,
configsvr: true,
heartbeatIntervalMillis: Long('2000'),
majorityVoteCount: 2,
writeMajorityCount: 2,
votingMembersCount: 3,
writableVotingMembersCount: 3,
optimes: {
lastCommittedOpTime: { ts: Timestamp({ t: 1765556868, i: 1 }), t: Long('8') },
lastCommittedWallTime: 2025-12-12T16:27:48.494Z,
readConcernMajorityOpTime: { ts: Timestamp({ t: 1765556868, i: 1 }), t: Long('8') },
appliedOpTime: { ts: Timestamp({ t: 1765556868, i: 1 }), t: Long('8') },
durableOpTime: { ts: Timestamp({ t: 1765556868, i: 1 }), t: Long('8') },
lastAppliedWallTime: 2025-12-12T16:27:48.494Z,
lastDurableWallTime: 2025-12-12T16:27:48.494Z
},
lastStableRecoveryTimestamp: Timestamp({ t: 1765556822, i: 1 }),
electionCandidateMetrics: {
lastElectionReason: 'priorityTakeover',
lastElectionDate: 2025-12-12T15:39:12.105Z,
electionTerm: Long('8'),
lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 1765553951, i: 1 }), t: Long('7') },
lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1765553951, i: 1 }), t: Long('7') },
numVotesNeeded: 2,
priorityAtElection: 2,
electionTimeoutMillis: Long('10000'),
priorPrimaryMemberId: 1,
numCatchUpOps: Long('0'),
newTermStartDate: 2025-12-12T15:39:12.124Z,
wMajorityWriteAvailabilityDate: 2025-12-12T15:39:12.173Z
},
members: [
{
_id: 0,
name: '192.168.215.23:30000',
health: 1,
state: 1,
stateStr: 'PRIMARY',
uptime: 2930,
optime: [Object],
optimeDate: 2025-12-12T16:27:48.000Z,
lastAppliedWallTime: 2025-12-12T16:27:48.494Z,
lastDurableWallTime: 2025-12-12T16:27:48.494Z,
syncSourceHost: '',
syncSourceId: -1,
infoMessage: '',
electionTime: Timestamp({ t: 1765553952, i: 1 }),
electionDate: 2025-12-12T15:39:12.000Z,
configVersion: 1,
configTerm: 8,
self: true,
lastHeartbeatMessage: ''
},
{
_id: 1,
name: '192.168.215.24:30000',
health: 1,
state: 2,
stateStr: 'SECONDARY',
uptime: 2927,
optime: [Object],
optimeDurable: [Object],
optimeDate: 2025-12-12T16:27:47.000Z,
optimeDurableDate: 2025-12-12T16:27:47.000Z,
lastAppliedWallTime: 2025-12-12T16:27:48.494Z,
lastDurableWallTime: 2025-12-12T16:27:48.494Z,
lastHeartbeat: 2025-12-12T16:27:47.546Z,
lastHeartbeatRecv: 2025-12-12T16:27:47.741Z,
pingMs: Long('1'),
lastHeartbeatMessage: '',
syncSourceHost: '192.168.215.23:30000',
syncSourceId: 0,
infoMessage: '',
configVersion: 1,
configTerm: 8
},
{
_id: 2,
name: '192.168.215.24:30001',
health: 1,
state: 2,
stateStr: 'SECONDARY',
uptime: 2832,
optime: [Object],
optimeDurable: [Object],
optimeDate: 2025-12-12T16:27:47.000Z,
optimeDurableDate: 2025-12-12T16:27:47.000Z,
lastAppliedWallTime: 2025-12-12T16:27:48.494Z,
lastDurableWallTime: 2025-12-12T16:27:48.494Z,
lastHeartbeat: 2025-12-12T16:27:47.552Z,
lastHeartbeatRecv: 2025-12-12T16:27:47.101Z,
pingMs: Long('1'),
lastHeartbeatMessage: '',
syncSourceHost: '192.168.215.24:30000',
syncSourceId: 1,
infoMessage: '',
configVersion: 1,
configTerm: 8
}
],
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1765556868, i: 1 }),
signature: {
hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
keyId: Long('0')
}
},
operationTime: Timestamp({ t: 1765556868, i: 1 })
}
关键字段说明:
members: 集群成员列表stateStr: 节点状态(PRIMARY/SECONDARY/ARBITER)health: 健康状态(1表示健康,0表示异常)lastHeartbeat: 最后一次心跳时间pingMs: 心跳延迟(毫秒)
查看集群配置:
shell
rs.conf()
关键字段说明:
_id: 节点IDhost: 节点地址priority: 优先级值(默认为1,范围0-1000)hidden: 是否为隐藏节点votes: 投票权重
在高权限账户下,可以查看已创建的用户(验证一下是否与上面创建的两个用户角色一致):
shell
db.system.users.find()
开启证书认证
创建密钥文件:
shell
# 在主节点上创建密钥文件,将文件拷贝到其它节点中
openssl rand -base64 756 > /opt/software/mongodb/key/access.key
# 设置密钥文件权限为仅所有者可读取(必须执行这一步)
chmod 600 /opt/software/mongodb/key/access.key
接着,在每个节点的配置文件中打开keyFile和auth。
使用MongoDB Compass或其它工具连接集群,连接字符串如下:
mongodb://mongo_system:321123%40123456@192.168.215.23:30000,192.168.215.24:30000,192.168.215.24:30001/?retryWrites=true&loadBalanced=false&replicaSet=cmdReplSet&readPreference=primary&serverSelectionTimeoutMS=5000&connectTimeoutMS=10000&authSource=bjcmd&authMechanism=SCRAM-SHA-1
注:密码中包含特殊字符需要额外转义

测试验证
测试读写:
shell
db.createCollection("test")
db.test.insertOne({
name: "Alice",
age: 30,
email: "alice@example.com",
registrationDate: new Date()
})
db.test.find()

此时可以尝试手动kill掉集群中的某个节点,通过rs.status()观察集群状态,测试是否可以正常读写,手动恢复后是否可以正常恢复健康状态。
需要注意一点:当PRIMARY宕机后会变成SECONDARY,oplog同步完之后priority最高的那个又会变为PRIMARY。
默认行为流程:
- Primary 宕机
- 副本集选举一个新的 primary
- 原 primary 恢复
- 恢复的节点进入 RECOVERING → SECONDARY 状态
- 当 oplog 追上后,如果它的 priority 更高(或与其他节点 priority 相同但它更"适合")
- 触发 priority takeover,再一次选举,它重新成为 PRIMARY
使用服务管理器管理服务
注:使用上面的启动方式时配置文件中可以使用相对路径,如果要使用systemd方式启动服务,mongodb的配置文件中数据库目录和日志、密钥等目录要写绝对路径,不能写相对路径。
MongoDB 官方已不再推荐使用fork 模式,注释调三个节点中配置文件的fork=true
创建 systemd 服务文件(核心步骤):
shell
sudo vim /etc/systemd/system/mongodb.service
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target
[Service]
User=root
Group=root
Type=simple
PIDFile=/run/mongodb/mongod.pid
ExecStart=/opt/software/mongodb/mongodb-linux-x86_64-rhel80-7.0.6/bin/mongod --config /opt/software/mongodb/conf/db30000.conf
Restart=always
RestartSec=5
LimitNOFILE=64000
LimitNPROC=64000
TasksMax=infinity
[Install]
WantedBy=multi-user.target
shell
sudo systemctl daemon-reload
sudo systemctl start mongodb
sudo systemctl enable mongodb
sudo systemctl status mongodb
journalctl -u mongodb
服务器B起两个名称不一样的服务即可,例如:mongodb1、mongodb2,实际使用尽量不要使用root用户。