连接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. 环境准备
-
创建所需用户和组
useradd mongo passwd mongo
-
创建mongodb所需目录结构
mkdir -p /mongodb/conf mkdir -p /mongodb/log mkdir -p /mongodb/data
-
修改权限
chown -R mongo:mongo /mongodb
-
切换用户并设置环境变量
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. 副本集验证
-
验证同步
登录主节点新增数据
$ 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" }
-
验证故障转移
关闭主节点
$ 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") } } }