IP地址 | 访问端口 |
---|---|
10.0.0.201 | 27017 |
10.0.0.202 | 27018 |
10.0.0.203 | 27019 |
下载地址:https://www.mongodb.com/try/download/community
版本根据需求选择,Mongodb6.0及以上的版本没有mongo命令
tar xvf mongodb-linux-x86_64-rhel70-6.0.5.tgz -C /usr/local
mv /usr/local/mongodb-linux-x86_64-rhel70-6.0.5 /usr/local/mongodb-6.0.5
echo "export PATH=$PATH:/usr/local/mongodb-6.0.5/bin" >> /etc/profile
source /etc/profile
在三台服务器分别执行该命令
yum install -y libcurl openssl xz-libs
节点服务器1
mkdir -p /data/mongodb/node1/{data,log,config}
节点服务器2
mkdir -p /data/mongodb/node2/{data,log,config}
节点服务器3
mkdir -p /data/mongodb/node3/{data,log,config}
节点服务器1
vi /data/mongodb/node1/config/node1.conf
dbpath=/data/mongodb/node1/data #数据存放目录
logpath=/data/mongodb/node1/log/mongodb_node1.log #日志存放目录 pidfilepath=/data/mongodb/node1/data/node1.pid #指定文件保存mongod进程的进程ID
fork=true #后台运行
logappend=true #以追加的方式记录日志
bind_ip=10.0.0.201 #绑定本机
ip port=27017 #mongodb端口
replSet=rs0 #副本集名称,同一个副本集,名称必须一致
节点服务器2
vi /data/mongodb/node2/config/node2.conf
dbpath=/data/mongodb/node2/data #数据存放目录
logpath=/data/mongodb/node2/log/mongodb_node2.log #日志存放目录 pidfilepath=/data/mongodb/node2/data/node2.pid #指定文件保存mongod进程的进程ID
fork=**true** #后台运行
logappend=**true** #以追加的方式记录日志
bind_ip=10.0.0.202 #绑定本机
ip port=27018 #mongodb端口
replSet=rs0 #副本集名称,同一个副本集,名称必须一致
节点服务器3
vi /data/mongodb/node3/config/node3.conf
dbpath=/data/mongodb/node3/data #数据存放目录
logpath=/data/mongodb/node3/log/mongodb_node3.log #日志存放目录pidfilepath=/data/mongodb/node3/data/node3.pid#指定文件保存mongod进程的进程ID
fork=true #后台运行
logappend=true #以追加的方式记录日志
bind_ip=10.0.0.203 #设置绑定本机ipport=27019 #mongodb端口
replSet=rs0 #副本集名称,同一个副本集,名称必须一致
节点服务器1
mongod -f /data/mongodb/node1/config/node1.conf
节点服务器2
mongod -f /data/mongodb/node2/config/node2.conf
节点服务器3
mongod -f /data/mongodb/node3/config/node3.conf
ps aux | grep mongo
因为Mongodb6.0及以上的版本没有mongo命令,所有无法使用mongo命令连接数据库
想在命令行连接数据库,需要给三台服务器安装MongoDB shell
wget https://downloads.mongodb.com/compass/mongosh-1.6.0-linux-x64.tgz
tar -xvf /root/mongosh-1.6.0-linux-x64.tgz -C /usr/local/
mv /usr/local/mongosh-1.6.0-linux-x64 /usr/local/mongosh
echo "export PATH=$PATH:/usr/local/mongosh/bin" >> /etc/profile
source /etc/profile
mongosh 10.0.0.201:27017
rs0:PRIMARY> rs.initiate()
rs0:PRIMARY> rs.add("10.0.0.202:27018") rs0:PRIMARY> rs.add("10.0.0.203:27019")
rs0:PRIMARY> rs.status()
返回一个汇总的各 Secondary 同步延迟信息
rs0:PRIMARY> rs.printSecondaryReplicationInfo()
返回oplog 大小、保留时长、 起始时间等信息
rs0:PRIMARY> rs.printReplicationInfo()
创建超级管理员用户
rs0:PRIMARY> use admin
rs0:PRIMARY> db.createUser({user:"root",pwd:"root",roles:[{role:"root",db:"admin"}]})
rs0:PRIMARY> db.auth("root","root")
创建库管理员
rs0:PRIMARY> use admin
rs0:PRIMARY> db.createUser({user:"admin",pwd:"admin",roles:[{role:"userAdminAnyDatabase",db:"admin"}]}) rs0:PRIMARY> db.auth("admin","123456")
keyfile是mongodb副本集的实例之间的权限认证,如果keyfile文件内容不同,那么该实例添加到副本集的时候,会出现不可达的状态
将主节点中的keyfile文件拷贝到复制集其他从节点服务器中,路径地址对应mongo.conf配置文件中的kevFile字段地址,并设置kevfile权限为600
注意: 创建keyFile前,需要先停掉复制集中所有主从节点的mongod服务,然后再创建,否则有可能出现服务启动不了的情况。
节点服务器2
mongod --shutdown --config /data/mongodb/node2/config/node2.conf
节点服务器3
mongod --shutdown --config /data/mongodb/node3/config/node3.conf
节点服务器1
mongod --shutdown --config /data/mongodb/node1/config/node1.conf
openssl rand -base64 666 > /usr/local/mongodb-6.0.5/keyfile
chmod 600 /usr/local/mongodb-6.0.5/keyfile
vi /data/mongodb/node1/config/node1.conf
添加以下内容:
auth=true oplogSize=100 keyFile=/usr/local/mongodb-6.0.5/keyfile
2. 另外两个节点添加
vi /data/mongodb/node2/config/node2.conf vi /data/mongodb/node3/config/node3.conf
添加以下内容:
oplogSize=100 keyFile=/usr/local/mongodb-6.0.5/keyfile
3. 重启服务
先停两个SECONDARY节点,再停PRIMARY节点
SECONDARY节点1
mongod --shutdown --config /data/mongodb/node3/config/node3.conf
SECONDARY节点2
mongod --shutdown --config /data/mongodb/node3/config/node3.conf
PRIMARY节点
mongod --shutdown --config /data/mongodb/node3/config/node3.conf
先启动PRIMARY节点,再启动两个SECONDARY节点
PRIMARY节点
mongod -f /data/mongodb/node1/config/node1.conf
SECONDARY节点1
mongod -f /data/mongodb/node2/config/node2.conf
SECONDARY节点2
mongod -f /data/mongodb/node3/config/node3.conf
添加mongodb服务配置文件
vi /lib/systemd/system/mongodb.service
添加以下字段
[Unit]
Description=mongodb
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/usr/local/mongodb-6.0.5/bin/mongod --config /data/mongodb/node2/config/node2.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/mongodb-6.0.5/bin/mongod --shutdown --config /data/mongodb/node2/config/node2.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
重载配置文件
systemctl daemon-reload
设置mongodb.service权限
chmod 754 /lib/systemd/system/mongodb.service
系统mongodb.service操作命令
#启动服务
systemctl start mongodb.service
#关闭服务
systemctl stop mongodb.service
#开机启动
systemctl enable mongodb.service
#重启服务
systemctl restart mongodb.service
在从节点的mongodb查看是否完成复制
rs0 [direct: primary] test> db.aaa.insert({AccountID:1,UserName:"123",password:"123456"})
rs0 [direct: primary] test> show tables
rs0 [direct: primary] test> db.aaa.find()
mongosh 10.0.0.202:27018
rs0 [direct: secondary] test> use test
rs0 [direct: secondary] test> show tables
rs0 [direct: secondary] test> db.aaa.find()
mongosh 10.0.0.203:27019
rs0 [direct: secondary] test> use test
rs0 [direct: secondary] test> show tables
rs0 [direct: secondary] test> db.aaa.find()
主从替换
通过模拟主节点宕机来检验主从替换,以通过杀死指令杀死主进程来达到宕机效果
当主节点宕机后访问27018(从节点)端口,可以看到该端口对应的mongodb变成了主节点,以及当执行rs.status()命令时,显示27017端口的mongodb的状态为不可达/健康
[root@localhost ~]# systemctl stop mongodb.service
rs0 [direct: secondary] test> rs.status()
1、报错:命令列表数据库需要身份验证
MongoServerError: command listDatabases requires authentication
解决方案:认证用户
rs0 [direct: primary] test> use admin switched to db admin
rs0 [direct: primary] admin> db.auth("root","123456")
2、报错:
MongoServerError: not primary and secondaryOk=false - consider using db.getMongo().setReadPref() or readPreference in the connection string
mongodb默认是从主节点读写数据的,副本节点上不允许读
rs0 [direct: secondary] test> show dbs;
2023-04-028T22:50:43.712+0800 E QUERY [thread1] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk"
} :
解决方案:
rs0 [direct: secondary] test> rs.slaveOk()
#当执行这条命令时会有一个警告,意思是这条参数可能在以后的版本弃用了,将会用 secondaryOk()代替
rs0 [direct: secondary] test> rs.secondaryOk()