连接Mongo集群,应用层面可以直接区分读写状态,无需其他应用做读写分离,架构设计如图所示:

Mongo复制集部署_数据库

1. 获取MongoDB

​https://www.mongodb.com/try/download/community​

2. 上传解压

cd /mongodb/
rz
rz waiting to receive.
Starting zmodem transfer. Press Ctrl+C to cancel.
Transferring mongodb-linux-x86_64-rhel70-4.2.8.tgz...
100% 129656 KB 32414 KB/sec 00:00:04 0 Errors
tar xf mongodb-linux-x86_64-rhel70-4.2.8.tgz

3. 关闭THP

echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.d/rc.local
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local

修改 /etc/default/grub

GRUB_CMDLINE_LINUX="crashkernel=auto ipv6.disable=1 rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet transparent_hugepage=never"

执行如下命令生效,有些系统不生效是因为没有选对相应的命令

  • EFI使用如下命令

grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg

  • BIOS使用如下命令

grub2-mkconfig -o /boot/grub2/grub.cfg

修改完成重启机器

[root@mongo01~]# grep Huge /proc/meminfo
AnonHugePages: 83968 kB
HugePages_Total: 0 #success
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
[root@mongo01~]# cat /proc/sys/vm/nr_hugepages
0 #success

4. 环境准备

  1. 创建所需用户和组

useradd mongo
passwd mongo

  1. 创建mongodb所需目录结构

mkdir -p /mongodb/conf
mkdir -p /mongodb/log
mkdir -p /mongodb/data

  1. 修改权限

chown -R mongo:mongo /mongodb

  1. 切换用户并设置环境变量

su - mongo
vi .bash_profile
export PATH=/mongodb/app/bin:$PATH
source .bash_profile

5. 创建配置文件

bindIp以所在服务器为准

$ cat >> /mongodb/mongodb.yaml <<EOF
systemLog:
destination: file
path: /mongodb/log/mongod.log
logAppend: true
processManagement:
fork: true
pidFilePath: /mongodb/mongodb.pid
storage:
dbPath: /mongodb/data
journal:
enabled: true
net:
bindIp: localhost,192.168.1.11
port: 27017
security:
keyFile: /mongodb/secret
authorization: enabled
replication:
replSetName: MongoRepl
EOF

6. 创建密码文件

三个节点需要配置相同的keyfile,否则复发互相通信,此处仅需生成一次,拷贝至其他服务器即可

$ openssl rand -base64 666 > /mongodb/secret
$ chmod 400 /mongodb/secret
$ scp /mongodb/secret mongo@192.168.62.22:/mongodb/secret
$ scp /mongodb/secret mongo@192.168.62.23:/mongodb/secret

7. 三个节点启动mongod进程

$ mongod -f /mongodb/mongodb.yaml
$ ps -ef | grep mongod

8. 初始化副本集

所有节点都执行rs.initiate

$ mongo
> rs.initiate()
{
"info2" : "no configuration specified. Using a default configuration for the set",
"me" : "192.168.1.11:27017",
"ok" : 1,
"operationTime" : Timestamp(1605262167, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1605262167, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}

如下设置方式设置了权重

rs.initiate({_id:"MongoRepl",
version:1,
members:[{ _id:0, host:"192.168.1.11:27017",priority:2},
{ _id:1, host:"192.168.1.12:27017",priority:1},
{ _id:2, host:"192.168.1.13:27017",priority:1}
]}
)

设置一主一从一仲裁

```javascript
rs.initiate({_id:"MongoRepl",
version:1,
members:[{ _id:0, host:"192.168.1.11:27017",priority:2},
{ _id:1, host:"192.168.1.12:27017",priority:1},
{ _id:2, host:"192.168.1.13:27017","arbiterOnly":true}
]}
)

9. 添加数据库管理用户

$ mongo
MongoRepl:PRIMARY> use admin
MongoRepl:PRIMARY> db.createUser({user: "admin",pwd: "admin1234",roles:[{role: "root",db:"admin"}]})
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}

10. 建立业务数据库及用户

mongo用户创建比较特殊,要想用户能直接登录对应的数据库,需要在创建用户前use数据库

$ mongo
MongoRepl:PRIMARY> use admin
MongoRepl:PRIMARY> db.auth("admin","admin1234")
MongoRepl:PRIMARY> use testdb
MongoRepl:PRIMARY> db.createUser({user: "test",pwd: "test1234",roles:[{role: "readWrite",db:"testdb"}]})
Successfully added user: {
"user" : "test",
"roles" : [
{
"role" : "readWrite",
"db" : "testdb"
}
]
}

11. 副本集验证

  1. 验证同步

登录主节点新增数据

$ mongo
MongoRepl:PRIMARY> use testdb
MongoRepl:PRIMARY> db.auth("test","test1234")
MongoRepl:PRIMARY> db.test.insert({"name":"test"})
WriteResult({ "nInserted" : 1 })
MongoRepl:PRIMARY> db.test.find()
{ "_id" : ObjectId("5ac9f5e06e02cf1ec5d82ae7"), "name" : "test" }

登录从节点192.168.1.12查询数据

$ mongo
MongoRepl:SECONDARY> use testdb
MongoRepl:SECONDARY> db.auth("test","test1234")
MongoRepl:SECONDARY> rs.slaveOk()
MongoRepl:SECONDARY> db.test.find()
{ "_id" : ObjectId("5ac9f5e06e02cf1ec5d82ae7"), "name" : "test" }

  1. 验证故障转移

关闭主节点

$ mongo
MongoRepl:PRIMARY> use admin
MongoRepl:PRIMARY> db.auth("admin","admin1234")
MongoRepl:PRIMARY> db.shutdownServer()
server should be down...
2018-04-09T09:50:30.195+0800 I NETWORK [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
2018-04-09T09:50:30.195+0800 W NETWORK [thread1] Failed to connect to 127.0.0.1:27017, in(checking socket for error after poll), reason: Connection refused

确认主节点mongod进程已关闭

$ ps -ef|grep mongod
mongo 3799 1581 0 09:54 pts/0 00:00:00 grep mongod

登录从节点查看集群状态

$ mongo
MongoRepl:PRIMARY> db.auth("admin","admin1234")
1
MongoRepl:PRIMARY> rs.status()
{
"set" : "MongoRepl",
"date" : ISODate("2020-11-13T10:47:45.141Z"),
"myState" : 1,
"term" : NumberLong(2),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1605264400, 1),
"t" : NumberLong(1)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1605264400, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1605264456, 1),
"t" : NumberLong(2)
},
"durableOpTime" : {
"ts" : Timestamp(1605264456, 1),
"t" : NumberLong(2)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.1.11:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2020-11-13T10:47:43.243Z"),
"lastHeartbeatRecv" : ISODate("2020-11-13T10:46:45.196Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Connection refused",
"configVersion" : -1
},
{
"_id" : 1,
"name" : "192.168.1.12:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 7748,
"optime" : {
"ts" : Timestamp(1605264456, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2020-11-13T10:47:36Z"),
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1605264415, 1),
"electionDate" : ISODate("2020-11-13T10:46:55Z"),
"configVersion" : 3,
"self" : true
},
{
"_id" : 2,
"name" : "192.168.1.13:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 1241,
"lastHeartbeat" : ISODate("2020-11-13T10:47:43.186Z"),
"lastHeartbeatRecv" : ISODate("2020-11-13T10:47:44.331Z"),
"pingMs" : NumberLong(0),
"configVersion" : 3
}
],
"ok" : 1,
"operationTime" : Timestamp(1605264456, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1605264456, 1),
"signature" : {
"hash" : BinData(0,"j7wJlWUpy/znoe6RSdnRL/yfVz0="),
"keyId" : NumberLong("6894548517361025025")
}
}
}