此落地方案,用于实现高可用。
复制集
这里部署相关的复制集,用于实现MongoDB的高可用。
介绍
MongoDB 复制集用于提供相关的数据副本,当发生硬件或者服务中断的时候,将会从副本中恢复数据,并进行自动化的故障转移用于实现MongoDB的高可用。
本部分,将会介绍如何部署一个相关的复制集的环境,用3个Mongodb 实例建立一个由三节点组成的,已经安装好的Mongodb数据库。
部署复制集
本部分将会部署一个rs0的复制集
1. 建立数据目录
mkdir -p /srv/mongodb/rs0-0 /srv/mongodb/rs0-1 /srv/mongodb/rs0-2
- 启动mongodb实例启动第一个实例
mongod --port 27018 --dbpath /srv/mongodb/rs0-0 --replSet rs0
启动第二个实例
mongod --port 27019 --dbpath /srv/mongodb/rs0-1 --replSet rs0
启动第三个实例
mongod --port 27020 --dbpath /srv/mongodb/rs0-2 --replSet rs0
这里port选项指定了相关的端口号,用于设置不同的端口号,其-dbpath选项用于指定相关的数据目录,每个节点都有不同的repSet选项,用于指定复制集的名称,所有节点共同拥有相关的复制集的名称
- 设置主机名
hostname # 查看主机名hostname mongodb-server # 修改主机名hostname # 确认主机名为 mongodb-server
编辑文件/etc/hosts 添加下面一行
127.0.0.1 mongodb-server
- 通过命令,连接到mongod实例,需要指定所需要的端口
mongo --port 27018
- 执行命令,初始化复制集
> rs.initiate(){"info2" : "no configuration explicitly specified -- making one","me" : "mongodb-server:27018","ok" : 1}
- 执行命令,查看复制集的配置
rs0:PRIMARY> rs.conf(){ "_id" : "rs0", "version" : 1, "members" : [ { "_id" : 0, "host" : "mongodb-server:27018", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : 0, "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatTimeoutSecs" : 10, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 } }}
- 添加相关的复制节点
rs0:PRIMARY> rs.add("mongodb-server:27019"){ "ok" : 1 }rs0:PRIMARY> rs.add("mongodb-server:27020"){ "ok" : 1 }
- 检查相关的复制集的状态
rs0:PRIMARY> rs.status(){ "set" : "rs0", "date" : ISODate("2015-12-04T06:12:07.664Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "mongodb-server:27018", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 3611, "optime" : Timestamp(1449209487, 1), "optimeDate" : ISODate("2015-12-04T06:11:27Z"), "electionTime" : Timestamp(1449208829, 2), "electionDate" : ISODate("2015-12-04T06:00:29Z"), "configVersion" : 3, "self" : true }, { "_id" : 1, "name" : "mongodb-server:27019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 41, "optime" : Timestamp(1449209487, 1), "optimeDate" : ISODate("2015-12-04T06:11:27Z"), "lastHeartbeat" : ISODate("2015-12-04T06:12:07.338Z"), "lastHeartbeatRecv" : ISODate("2015-12-04T06:12:06.005Z"), "pingMs" : 0, "configVersion" : 3 }, { "_id" : 2, "name" : "mongodb-server:27020", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 40, "optime" : Timestamp(1449209487, 1), "optimeDate" : ISODate("2015-12-04T06:11:27Z"), "lastHeartbeat" : ISODate("2015-12-04T06:12:07.339Z"), "lastHeartbeatRecv" : ISODate("2015-12-04T06:12:07.339Z"), "pingMs" : 0, "configVersion" : 3 } ], "ok" : 1}
测试复制集
测试数据同步。
[root@mongodb ~]# mongo --port 27020MongoDB shell version: 3.0.7connecting to: 127.0.0.1:27020/test...rs0:SECONDARY>
由于默认的Secondary节点不可读,所以这里要让Secondary节点可读。
rs0:SECONDARY> rs.slaveOk()rs0:SECONDARY> show dbslocal 1.078GBrs0:SECONDARY> show collectionsrs0:SECONDARY>
然后在primary 节点插入数据,
rs0:PRIMARY> use testdbswitched to db testdbrs0:PRIMARY> db.tc.insert({ name : "mongo" })WriteResult({ "nInserted" : 1 })rs0:PRIMARY> db.tc.insert({ x : 3 })WriteResult({ "nInserted" : 1 })rs0:PRIMARY> db.tc.find(){ "_id" : ObjectId("5661345929d3c35bcbe64803"), "name" : "mongo" }{ "_id" : ObjectId("5661346b29d3c35bcbe64804"), "x" : 3 }rs0:PRIMARY>
然后在 Secon命令上的客户端执行。
rs0:SECONDARY> rs.slaveOk()rs0:SECONDARY> show dbslocal 1.078GBtestdb 0.078GBrs0:SECONDARY> use testdbswitched to db testdbrs0:SECONDARY> show collectionssystem.indexestcrs0:SECONDARY> db.tc.find(){ "_id" : ObjectId("5661345929d3c35bcbe64803"), "name" : "mongo" }{ "_id" : ObjectId("5661346b29d3c35bcbe64804"), "x" : 3 }rs0:SECONDARY>
测试故障转移
在主节点的服务器按下Ctrl + C 键模拟主节点故障,此时命令提示符变成
rs0:SECONDARY>rs0:PRIMARY>
这个时候查看状态,可以看到故障已经转移。
rs0:PRIMARY> rs.status(){ "set" : "rs0", "date" : ISODate("2015-12-04T06:52:09.191Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "mongodb-server:27018", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : Timestamp(0, 0), "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2015-12-04T06:52:08.039Z"), "lastHeartbeatRecv" : ISODate("2015-12-04T06:45:11.755Z"), "pingMs" : 0, "lastHeartbeatMessage" : "Failed attempt to connect to mongodb-server:27018; couldn't connect to server mongodb-server:27018 (127.0.0.1), connection attempt failed", "configVersion" : -1 }, { "_id" : 1, "name" : "mongodb-server:27019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 2441, "optime" : Timestamp(1449210987, 1), "optimeDate" : ISODate("2015-12-04T06:36:27Z"), "lastHeartbeat" : ISODate("2015-12-04T06:52:07.857Z"), "lastHeartbeatRecv" : ISODate("2015-12-04T06:52:08.567Z"), "pingMs" : 0, "configVersion" : 3 }, { "_id" : 2, "name" : "mongodb-server:27020", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 5984, "optime" : Timestamp(1449210987, 1), "optimeDate" : ISODate("2015-12-04T06:36:27Z"), "electionTime" : Timestamp(1449211514, 1), "electionDate" : ISODate("2015-12-04T06:45:14Z"), "configVersion" : 3, "self" : true } ], "ok" : 1}
这样就完成了,节点的故障转移。
主从实现高可用
这里使用主从实现高可用。
主从结构如下所示
其有两种角色构成
主
可读可写,当数据有修改的时候,会将oplog同步到所有连接的salve上去。
从
只读不可写,自动从Master同步数据。
特别的,对于Mongodb来说,并不推荐使用Master-Slave架构,因为Master-Slave其中Master宕机后不能自动恢复,推荐使用Replica Set,后面会有介绍,除非Replica的节点数超过50,才需要使用Master-Slave架构,正常情况是不可能用那么多节点的。
还有一点,Master-Slave不支持链式结构,Slave只能直接连接Master。Redis的Master-Slave支持链式结构,Slave可以连接Slave,成为Slave的Slave。
主从搭建
主服务器
在主服务器上创建个存放数据的路径
mkdir -p /data/mongodb/master
然后通过mongo命令启动服务,加上master参数
mongod –dbpath /data/mongodb/master –master
从服务器
在从服务器上创建存放数据的路径
mkdir -p /data/mongodb/slave
以从模式进行启动
mongod -dbpath /data/mongodb/slave -slave -source 10.29.240.13:27017
这样就完成了一主,多从的mongodb的搭建
最复杂的 Replica Sets+Sharding
启动配置服务器
- 启动配置服务器的副本集
mongod -f /u01/conf/config.cnf
- 查看配置服务器的状态
mongo localhost:27019/admin -uroot -prs.status()
启动相关的副本集
- 启动分片副本集
mongod -f /u01/conf/sd1.cnf
- 查看分片的副本集的状态
mongo localhost:27018/admin -uroot -prs.status()
启动服务器
- 启动所有的mongos
mongos -f /u01/conf/mongos.cnf
- 连接 mongos
mongo localhost:27017/admin -uroot -p
- 查看分片集群状态
sh.status()