mongodb 通过一主一从、一主多从可以实现数据库备份,读写分离。为了便于查找现将实现过程记录下来。这里总共有3个节点
1、在 mongodb 目录下新建3个配置文件,作为启动3个节点的参数,文件及内容如下:
mongodb1.conf
dbpath=/var/mongodb/mdata17 logpath=/var/mongodb/mlog/mongolog17.log smallfiles=true replSet=rsa logappend=true bind_ip=0.0.0.0 fork=true port=27017
mongodb2.conf
dbpath=/var/mongodb/mdata18 logpath=/var/mongodb/mlog/mongolog18.log smallfiles=true replSet=rsa logappend=true bind_ip=0.0.0.0 fork=true port=27018
mongodb3.conf
dbpath=/var/mongodb/mdata19 logpath=/var/mongodb/mlog/mongolog19.log smallfiles=true replSet=rsa logappend=true bind_ip=0.0.0.0 fork=true port=27019
2、运行 shell 脚本:mongodbStart.sh
脚本内容如下:
#!/bin/bash IP=192.168.31.151 RS=rsa read -t 30 -p 'please input is reset[y/n]:' reset if [ $reset == 'y' ] then echo "reset" pkill -9 mongo rm -rf /var/mongodb/ fi mkdir -p /var/mongodb/mdata17 /var/mongodb/mdata18 /var/mongodb/mdata19 /var/mongodb/mlog /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongodb1.conf /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongodb2.conf /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongodb3.conf /usr/local/mongodb/bin/mongo --port 27017 <<EOF use admin; var rsconf={ _id:'${RS}', members:[ {_id:0,host:'${IP}:27017'}, {_id:1,host:'${IP}:27018'}, {_id:2,host:'${IP}:27019'} ] }; rs.initiate(rsconf); EOF /usr/local/mongodb/bin/mongo
这样一个有3个节点的 mongodb 复制集就搭建好了。mongodb 会默认选中一个主节点,主节点无需人为指定,一个复制集一定会有一个主节点,假如主节点宕掉了该复制集会从其余的从节点中重新选择出一个主节点。连接主节点客户端显示的是 rsa:PRIMARY>,连接从节点客户端显示的是 rsa:SECONDARY>。
主节点能读写,从节点只能读。注意:刚搭建完环境时,客户端连接从节点不能执行读操作,执行 rs.slaveOk(); 命令后才能读取数据。所有节点读到的数据都是一样的。
3、删除节点操作,remove 方法,只能在主节点执行,主节点不能删除自己,假如删除27019端口对应的节点,执行以下语句,
rs.remove('192.168.31.151:27019');
删除后执行命令:db.isMaster();可以看到 27019 节点已经被删除,该方法还可以显示所有节点信息,主节点信息。如下:
rsa:PRIMARY> db.isMaster(); { "hosts" : [ "192.168.31.151:27017", "192.168.31.151:27018" ], "setName" : "rsa", "setVersion" : 2, "ismaster" : true, "secondary" : false, "primary" : "192.168.31.151:27017", "me" : "192.168.31.151:27017", "electionId" : ObjectId("7fffffff0000000000000001"), "lastWrite" : { "opTime" : { "ts" : Timestamp(1564813691, 1), "t" : NumberLong(1) }, "lastWriteDate" : ISODate("2019-08-03T06:28:11Z"), "majorityOpTime" : { "ts" : Timestamp(1564813691, 1), "t" : NumberLong(1) }, "majorityWriteDate" : ISODate("2019-08-03T06:28:11Z") }, "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 100000, "localTime" : ISODate("2019-08-03T06:28:12.570Z"), "logicalSessionTimeoutMinutes" : 30, "minWireVersion" : 0, "maxWireVersion" : 6, "readOnly" : false, "ok" : 1, "operationTime" : Timestamp(1564813691, 1), "$clusterTime" : { "clusterTime" : Timestamp(1564813691, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } }
5、添加节点操作,add 方法,假如添加 27019 端口对应的节点,执行以下语句,只能在主节点执行下面的语句。
rs.add('192.168.31.151:27019');
rs.slaveOk(); 必须执行这个语句 该从节点才能读操作
6、可以用 rs.status(); 查看当前复制集状态,模拟27019宕机,执行一下语句。
use admin;
db.shutdownServer();
用其他客户端查看该复制集状态:rs.status();可以看到 27019 的状态不可达 "stateStr" : "(not reachable/healthy)",结果如下
1 rsa:SECONDARY> rs.status(); 2 { 3 "set" : "rsa", 4 "date" : ISODate("2019-08-03T07:39:25.615Z"), 5 "myState" : 2, 6 "term" : NumberLong(1), 7 "syncingTo" : "192.168.31.151:27017", 8 "heartbeatIntervalMillis" : NumberLong(2000), 9 "optimes" : { 10 "lastCommittedOpTime" : { 11 "ts" : Timestamp(1564817963, 1), 12 "t" : NumberLong(1) 13 }, 14 "readConcernMajorityOpTime" : { 15 "ts" : Timestamp(1564817963, 1), 16 "t" : NumberLong(1) 17 }, 18 "appliedOpTime" : { 19 "ts" : Timestamp(1564817963, 1), 20 "t" : NumberLong(1) 21 }, 22 "durableOpTime" : { 23 "ts" : Timestamp(1564817963, 1), 24 "t" : NumberLong(1) 25 } 26 }, 27 "members" : [ 28 { 29 "_id" : 0, 30 "name" : "192.168.31.151:27017", 31 "health" : 1, 32 "state" : 1, 33 "stateStr" : "PRIMARY", 34 "uptime" : 9836, 35 "optime" : { 36 "ts" : Timestamp(1564817963, 1), 37 "t" : NumberLong(1) 38 }, 39 "optimeDurable" : { 40 "ts" : Timestamp(1564817963, 1), 41 "t" : NumberLong(1) 42 }, 43 "optimeDate" : ISODate("2019-08-03T07:39:23Z"), 44 "optimeDurableDate" : ISODate("2019-08-03T07:39:23Z"), 45 "lastHeartbeat" : ISODate("2019-08-03T07:39:23.676Z"), 46 "lastHeartbeatRecv" : ISODate("2019-08-03T07:39:24.031Z"), 47 "pingMs" : NumberLong(0), 48 "electionTime" : Timestamp(1564808137, 1), 49 "electionDate" : ISODate("2019-08-03T04:55:37Z"), 50 "configVersion" : 3 51 }, 52 { 53 "_id" : 1, 54 "name" : "192.168.31.151:27018", 55 "health" : 1, 56 "state" : 2, 57 "stateStr" : "SECONDARY", 58 "uptime" : 9845, 59 "optime" : { 60 "ts" : Timestamp(1564817963, 1), 61 "t" : NumberLong(1) 62 }, 63 "optimeDate" : ISODate("2019-08-03T07:39:23Z"), 64 "syncingTo" : "192.168.31.151:27017", 65 "configVersion" : 3, 66 "self" : true 67 }, 68 { 69 "_id" : 2, 70 "name" : "192.168.31.151:27019", 71 "health" : 0, 72 "state" : 8, 73 "stateStr" : "(not reachable/healthy)", 74 "uptime" : 0, 75 "optime" : { 76 "ts" : Timestamp(0, 0), 77 "t" : NumberLong(-1) 78 }, 79 "optimeDurable" : { 80 "ts" : Timestamp(0, 0), 81 "t" : NumberLong(-1) 82 }, 83 "optimeDate" : ISODate("1970-01-01T00:00:00Z"), 84 "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), 85 "lastHeartbeat" : ISODate("2019-08-03T07:39:25.043Z"), 86 "lastHeartbeatRecv" : ISODate("2019-08-03T07:30:15.461Z"), 87 "pingMs" : NumberLong(0), 88 "lastHeartbeatMessage" : "Connection refused", 89 "configVersion" : -1 90 } 91 ], 92 "ok" : 1, 93 "operationTime" : Timestamp(1564817963, 1), 94 "$clusterTime" : { 95 "clusterTime" : Timestamp(1564817963, 1), 96 "signature" : { 97 "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), 98 "keyId" : NumberLong(0) 99 } 100 } 101 } 102 rsa:SECONDARY>
假如主节点宕机了,另外两个中的一个节点会自动成为主节点,已测试。
db.help(); rs.help(); 可以查询有哪些方法可以使用