什么是mongo副本集
https://docs.mongodb.com/manual/replication/
mongo副本集和mongo主从复制不是一回事
centos7搭建mongo副本集
没几条命令 篇幅之所以比较长 是有很多查看的信息显示 不要恐惧 哦 说给我这种胆小鬼听得 嘻嘻
PRIMARY 主 ===》 1.1.2.155
SECONDARY 副本1 ===》 1.1.2.134
SECONDARY 副本2 仲裁 ===》 1.1.2.129
1. 搭建三个mongo
根据如下连接分别在三台机器上安装三个mongo
http://www.cnblogs.com/lazyball/p/8962359.html
2. 创建key
副本和主之间的通信也是需要认证的,通过key文件认证
创建一个keyfile,并且拷贝到其他从节点
openssl rand -base64 756 > /data/mongos_m/key chmod 400 /data/mongos_m/key
三个节点都要有这个key文件,将这个key文件cp搭配每一个节点
3. 配置配置文件 mongodb.conf
port = 27111 #端口 pidfilepath = /data/mongos_m/logs/mongo3717.pid #pid目录 dbpath = /data/mongos_m/data/ #数据文件存放目录 logpath = /data/mongos_m/logs/mongodb.log #日志文件存放目录 fork = true #以守护程序的方式启用,即在后台运行 auth=true #以下两条 每个mongo的配置文件里都有
replSet=shard1 #副本集的名字 keyFile = /data/mongos_m/key/autokey #其他mongo根据自身路径添加配置
重启mongo
4. 配置复制集
在你打算做主的服务器上执行以下操作
登录mongo
配置主:
> config = {_id:"shard1", members:[{_id:0,host:"1.1.2.155:27111", priority : 3}]}
{
"_id" : "shard1",
"members" : [
{
"_id" : 0,
"host" : "1.1.2.155:27111",
"priority" : 3
}
]
}
初始化
> rs.initiate(config);
{ "ok" : 1 }
查看复制集状态
rs.status(); { "set" : "shard1", ###副本集名称 "date" : ISODate("2018-05-02T03:27:38.036Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1525231650, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1525231650, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1525231650, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 0, "name" : "1.1.2.155:27111", #主的ip和端口信息 "health" : 1, "state" : 1, "stateStr" : "PRIMARY", #主 "uptime" : 184, "optime" : { "ts" : Timestamp(1525231650, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2018-05-02T03:27:30Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1525231648, 2), "electionDate" : ISODate("2018-05-02T03:27:28Z"), "configVersion" : 1, "self" : true } ], "ok" : 1
}
添加复制集成员
#如下 添加了两个成员 观察敲命令的位置已经变成了shard1:PRIMARY>
shard1:PRIMARY> rs.add("1.1.2.134:27111") { "ok" : 1 } shard1:PRIMARY> rs.add("1.1.2.129:27111") { "ok" : 1 }
查看复制集状态
shard1:PRIMARY> rs.status(); { "set" : "shard1", "date" : ISODate("2018-05-02T05:46:24.523Z"), "myState" : 1, "term" : NumberLong(2), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1525239984, 1), "t" : NumberLong(2) }, "appliedOpTime" : { "ts" : Timestamp(1525239984, 1), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1525239984, 1), "t" : NumberLong(2) } }, "members" : [ { "_id" : 0, "name" : "1.1.2.155:27111",########## "health" : 1, "state" : 1, "stateStr" : "PRIMARY",######### "uptime" : 233, "optime" : { "ts" : Timestamp(1525239984, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2018-05-02T05:46:24Z"), "electionTime" : Timestamp(1525239752, 1), "electionDate" : ISODate("2018-05-02T05:42:32Z"), "configVersion" : 3, "self" : true }, { "_id" : 1, "name" : "1.1.2.134:27111",##### "health" : 1, "state" : 2, "stateStr" : "SECONDARY", ######### "uptime" : 57, "optime" : { "ts" : Timestamp(1525239974, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1525239974, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2018-05-02T05:46:14Z"), "optimeDurableDate" : ISODate("2018-05-02T05:46:14Z"), "lastHeartbeat" : ISODate("2018-05-02T05:46:24.363Z"), "lastHeartbeatRecv" : ISODate("2018-05-02T05:46:23.410Z"), "pingMs" : NumberLong(1), "syncingTo" : "10.10.20.155:27111", "configVersion" : 3 }, { "_id" : 2, "name" : "1.1.2.129:27111", ##### "health" : 1, "state" : 2, "stateStr" : "SECONDARY", ##### "uptime" : 52, "optime" : { "ts" : Timestamp(1525239974, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1525239974, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2018-05-02T05:46:14Z"), "optimeDurableDate" : ISODate("2018-05-02T05:46:14Z"), "lastHeartbeat" : ISODate("2018-05-02T05:46:22.557Z"), "lastHeartbeatRecv" : ISODate("2018-05-02T05:46:23.001Z"), "pingMs" : NumberLong(0), "syncingTo" : "1.1.2.134:27111", "configVersion" : 3 } ], "ok" : 1 }
查看副本集成员及其优先级(看好成员的顺序,优先级从1-100,越大的优先级越高)
shard1:PRIMARY> rs.conf(); { "_id" : "shard1", "version" : 3, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "10.10.20.155:27111", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 3, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "10.10.20.134:27111", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "10.10.20.129:27111", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : 2000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("5ae93020e22979d68675c342") } }
进行优先级设置,以便为了当主死了,可以由自己指定的服务器作为主
shard1:PRIMARY> config=rs.conf() shard1:PRIMARY> config.members[0].priority = 3; ##根据id修改优先级 主 3 shard1:PRIMARY> config.members[1].priority = 2; ## 从 2 shard1:PRIMARY> config.members[2].priority = 1 ; ##仲裁的 1
保存配置 生效
shard1:PRIMARY> rs.reconfig(config) { "ok" : 1 }
到此位置 副本集创建完毕 步骤还是很清晰明了的呢 突然好喜欢mongo 兴趣来了
5. 创建认证用户
shard1:PRIMARY> db.createUser( ... { ... user: "dba", ... pwd: "dba@2017", ... roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] ... } ... ) Successfully added user: { "user" : "dba", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] }
6. 测试主从同步
在主上
use test db.t1.insert({x:1})
然后在两个从上查看是否有新创建的库和数据
use test;
show dbs;
db.test.find()
####在从上查看的时候可能有报错 解决方法如下:
报错如下:
2018-05-02T13:56:01.550+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk" } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:769:19 shellHelper@src/mongo/shell/utils.js:659:15 @(shellhelp2):1:1
解决方法如下:
## 注意观察 输入命令的地方 shard1:SECONDARY> 变成了这样 已经是从的状态了
shard1:SECONDARY> rs.slaveOk(); ## 先执行这个再看 shard1:SECONDARY> show dbs; admin 0.000GB local 0.000GB runoob 0.000GB testtt 0.000GB user 0.000GB shard1:SECONDARY> use testtt; switched to db testtt shard1:SECONDARY> shard1:SECONDARY> db.testtt.find() { "_id" : ObjectId("5ae952dd81d821af964649f7"), "x" : 1 } shard1:SECONDARY> exit
7.测试主从故障切换
在主上 将主停了
use admin
db.shutdownServer()
去从上看
shard1:SECONDARY> shard1:PRIMARY> shard1:PRIMARY>
前缀已经改变 可以再用命令rs.status();查看一下主从状态
在新的主上,插入新的数据
shard1:PRIMARY> use test switched to db test shard1:PRIMARY> db.t1.insert({x:2}) WriteResult({ "nInserted" : 1 })
然后去另一个从上查看数据是否同步
shard1:PRIMARY> use test switched to db test shard1:PRIMARY> db.t1.find() { "_id" : ObjectId("58be61ade717794f6b66b557"), "x" : 1 } { "_id" : ObjectId("58be6408d03d16a5c98fbb57"), "x" : 2 }
将主重新启动 观察新的数据是否同步 观察新的主是否又成为了从
这几天又陆陆续续搭建了几个副本集,发现主挂了后,从是顶上去了,但是另外的从上去查数据,等了好一会也查不到 一直报错如下
018-05-03T11:27:13.147+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk" } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:769:19 shellHelper@src/mongo/shell/utils.js:659:15 @(shellhelp2):1:1
然后我手动执行
rs.slaveOk();
就可以了 这让我疑惑了 难道以后线上主挂了 从还得有上去手动恢复的可能性
知道的人告诉我一下白
这样一个需求
现在有这样一个需求
一个有数据的单点mongo做迁移,再以此mongo为主,配置两个从
1. mongo的迁移
我的mongo是用二进制包安装的,迁移的时候将mongo的程序目录,数据目录完整复制到新的机器上
修改一下 bind ip就可以了 路径啥的的最好不要变了
2. 为mongo配置主从
每个mongo的配置文件里都添加
replSet=shard1 #副本集的名字 所有的mongo一致
然后主的mongo启动的时候 或许可以不用指定 --replSet shard1
/usr/local/mongodb-3.2.16/bin/mongod -f /data/mongodb/conf/mongod.conf --replSet shard1 &
然后依次启动 其他mongo 查看副本集情况