此落地方案,用于实现高可用。

复制集

这里部署相关的复制集,用于实现MongoDB的高可用。

介绍

MongoDB 复制集用于提供相关的数据副本,当发生硬件或者服务中断的时候,将会从副本中恢复数据,并进行自动化的故障转移用于实现MongoDB的高可用。

本部分,将会介绍如何部署一个相关的复制集的环境,用3个Mongodb 实例建立一个由三节点组成的,已经安装好的Mongodb数据库。

部署复制集

本部分将会部署一个rs0的复制集

1. 建立数据目录

mkdir -p /srv/mongodb/rs0-0 /srv/mongodb/rs0-1 /srv/mongodb/rs0-2
  1. 启动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选项,用于指定复制集的名称,所有节点共同拥有相关的复制集的名称

  1. 设置主机名
hostname                    # 查看主机名hostname mongodb-server     # 修改主机名hostname                    # 确认主机名为 mongodb-server

编辑文件/etc/hosts 添加下面一行

127.0.0.1       mongodb-server
  1. 通过命令,连接到mongod实例,需要指定所需要的端口
mongo --port 27018
  1. 执行命令,初始化复制集
> rs.initiate(){"info2" : "no configuration explicitly specified -- making one","me" : "mongodb-server:27018","ok" : 1}
  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        }    }}
  1. 添加相关的复制节点
rs0:PRIMARY> rs.add("mongodb-server:27019"){ "ok" : 1 }rs0:PRIMARY> rs.add("mongodb-server:27020"){ "ok" : 1 }
  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}

这样就完成了,节点的故障转移。

主从实现高可用

这里使用主从实现高可用。

主从结构如下所示




mongodb 默认值 spring mongodb的默认端口是多少_mongodb


其有两种角色构成

可读可写,当数据有修改的时候,会将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


mongodb 默认值 spring mongodb的默认端口是多少_复制集_02


从服务器

在从服务器上创建存放数据的路径

mkdir -p /data/mongodb/slave

以从模式进行启动

mongod -dbpath /data/mongodb/slave -slave -source 10.29.240.13:27017

这样就完成了一主,多从的mongodb的搭建

最复杂的 Replica Sets+Sharding

启动配置服务器

  1. 启动配置服务器的副本集
mongod -f /u01/conf/config.cnf
  1. 查看配置服务器的状态
mongo localhost:27019/admin -uroot -prs.status()

启动相关的副本集

  1. 启动分片副本集
mongod -f /u01/conf/sd1.cnf
  1. 查看分片的副本集的状态
mongo localhost:27018/admin -uroot -prs.status()

启动服务器

  1. 启动所有的mongos
mongos -f /u01/conf/mongos.cnf
  1. 连接 mongos
mongo localhost:27017/admin -uroot -p
  1. 查看分片集群状态
sh.status()