MongoDB的复制一:复制的原理
1.复制的角色
复制有三种角色:primay:主库,执行所有的写操作,并把日志写入oplog里。
secondary:复制主库的所有操作。读取主库的oplog,并执行日志里的内容。默认情况下,客户端不能读取secondary的数据。
arbiter:仲裁者,在主库失败后选举主库。该角色是可选的角色。仲裁者不包含数据,客户端不可连接。
2.主库
primay:主库,执行所有的读写操作,并把日志写入oplog里。
3.备库
secondary:复制主库的所有操作。读取主库的oplog,并执行日志里的内容。在主库宕机后,备库可以切换为主库
备库可做以下配置:
1)设置成priority 0的备库,使其不能成为主库。其它特性不变。
2)设置成应该程序不能访问
3)做主库的延迟快照。即延迟复制。延迟的备库必须是priority 0的,并且应该设置为hidden.
3.仲裁者
不包含数据,只负责极少工作,对机器的要求低,可以放在性能差一点的机器上。
每个arbiter可以投一票。其实,每个主库备库都可以投一票
注意:不能在主库或者备库上建仲裁者.(不是不能建,但是会影响投票的准确性)。只在节点数为偶然的集群中加入仲裁者。

4.关于容灾
节点数与可以宕机的节点的个数(否则会产生选举不出primary的问题):

(foolr(N/2)+1) 至少一半成员状态正常,否则不能选举出primary(待验证)
关于选举:
http://www.itpub.net/thread-1740982-1-1.html三台机器的两种复制形式:
![]()
![]()


3.其它细节
心跳:节点之间每2秒检查心跳,如果一个节点10秒内没有响应就认为该节点失效。
优先级:各节点都有优先级,优先级越高的备库越有希望成为转换为主库
无选举权节点:一个复制群最多可以有50个节点,但是只有7个有选举权,剩下的没有选举权但是可以复制数据
4.回滚
“回滚”:如果备库没有跟上主库的节奏,而主库又挂了,选举了新的主库,之前的主库又加入到复制群中做为备库,
此时之前的主库会做回滚操作。
MongoDB会把回滚数据写入到rollback/目录下,dba来决定是忽视还是使用这些数据。
避免回滚:
默认情况下write concern {w: 1} 确保主库写完后就返回给client,可以改成w: majority ,大多数据写完后返回结果给客户端。但显示可能增加响应时间。
回滚的限制:
默认下,只能回滚300M以内的数据,如果大于300M,日志中有以一警告:
[replica set sync] replSet syncThread: 13410 replSet too much data to roll back
此时必须“save the data directly”(语义不明),或者执行初始化。执行初始化同步,必须删除--dbpaht目录下的内容。。。
详情略。
5.设置默认的write concern
db.products.insert({ writeConcern: { w: 2, wtimeout: 5000 } } #至少写入一个从结点){ w: "majority", wtimeout: 5000 }
6.设置复制的可读性
默认下,应用只能读主库。
详情略。
7.oplog的大小
默认以5%的磁盘空间做oplog。详情略。
8.数据同步
有两种方式数据同步:initial sync和Replication
initical sync:初始化数据。
当集群新增加了成员,新成员没有数据,从开始复制数据。
过程如下 :
1)从数据源复制所有数据库,只复制有效的数据。这个步骤中,_id上的索引也被建立。从3.0开始如果发现无效数据,将会在日志中记录:Cloner: found corrupt document in <collection>.
2)使用oplog同步数据。
3)在各集合上建立索引
replication:复制,即正常的数据同步。
支持多线程复制数据。
9.master-slave 复制
mongodb的复制分为两种。旧的称为master-slave复制,没有自动failover功能。新的称为replication sets,有自动failover功能。
这时介绍master-slave复制。
创建master:
mongod --master --dbpath /data/masterdb/
创建salve:
mongod --slave --source <masterhostname><:<port>> --dbpath /data/slavedb/
这样就创建了一个主备。
配置mster-slave:
slave上,master的信息保存在此处:
use local
db.sources.find()#包含了source信息.
db.sources.insert( { host: <masterhostname> <,only: databasename> } ); slave 无法同步数据
slave无法同步数据的原因:备库的复制进度落后太远了。
一旦备库的复制进度落后主库太完,复制就会中断。
解决办法:
必须执行resync命令重新同步数据(应该是initical sync,即重0数据开始同步)。如果在启动slave时加上--autoresync,则slave在复制中断10秒后自动执行resync。
为了避免这种情况,在master启动的时候,可以设置--oplogSize参数,设置较大的日志文件。默认使用磁盘的5%做为oplog,32位上最小是50M,64位上最小1G.
运行时检查配置情况:
2.6以前,在master执行 db.printReplicationInfo() local库。2.6以后,执行rs.printReplicationInfo().
2.6以前,在slave执行 db.printSlaveReplicationInfo() local库。2.6以后,执行rs.printSlaveReplicationInfo().
安全性:
如果master启用了authorization,需要配置keyfile,slave通过keyfile与master通信。
在config文件里加入:
keyFile=/usr/local/mongo/ keyfile
keyFile的内容在各个节点上必须一样。可以使用OpenSSL来生成一个keyfile.
master-slave的failover:
master-slave的角色切换:
从master的磁盘快照创建slave:
从slave的磁盘快照创建slave:
resync复制进度过慢(无法继续复制)的salve:
use admindb.runCommand( { resync: 1 } )
修改slave的配置信息然后重启slave:
use localdb.sources.update( { host : "prod.mississippi" },{ $set : { host : "prod.mississippi.example.net" } } )
10. replication sets
配置replication sets
1)以--replSet启动mongod
mongod --replSet "rs0" -f /usr/local/mongodb-linux-x86_64-3.2.0/mongodb.conf
2)进入mong shell
>mongo
3)初始化复制集(没有配置信息)
> rs.initiate();{"info2" : "no configuration specified. Using a default configuration for the set","me" : "node1:27017","ok" : 0,"errmsg" : "No host described in new configuration 1 for replica set repl0 maps to this node","code" : 93}
4)验证初始配置
> rs.conf();2015-12-27T11:04:15.763+0800 E QUERY [thread1] Error: Could not retrieve replica set config: {"info" : "run rs.initiate(...) if not yet done for the set","ok" : 0,"errmsg" : "no replset config has been received","code" : 94} :rs.conf@src/mongo/shell/utils.js:1090:11@(shell):1:1> cfg={"_id":"rs0","version":1,"members":[{"_id":1,"host":"192.168.75.10:27017"}]};{"_id" : "rs0","version" : 1,"members" : [{"_id" : 1,"host" : "192.168.75.10:27017"}]}> rs.initiate(cfg);{ "ok" : 1 }
5)在复制集中加入节点
rs0:PRIMARY> rs.add("192.168.75.11:27017");{ "ok" : 1 }rs0:PRIMARY> rs.add("192.168.75.12:27017");{ "ok" : 1 }
6)检查复制集状态
rs0:PRIMARY> rs.status();{"set" : "rs0","date" : ISODate("2015-12-27T03:13:26.970Z"),"myState" : 1,"term" : NumberLong(1),"heartbeatIntervalMillis" : NumberLong(2000),"members" : [{"_id" : 1,"name" : "192.168.75.10:27017","health" : 1,"state" : 1,"stateStr" : "PRIMARY","uptime" : 575,"optime" : {"ts" : Timestamp(1451185968, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2015-12-27T03:12:48Z"),"electionTime" : Timestamp(1451185613, 2),"electionDate" : ISODate("2015-12-27T03:06:53Z"),"configVersion" : 3,"self" : true},{"_id" : 2,"name" : "192.168.75.11:27017","health" : 1,"state" : 2,"stateStr" : "SECONDARY","uptime" : 41,"optime" : {"ts" : Timestamp(1451185968, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2015-12-27T03:12:48Z"),"lastHeartbeat" : ISODate("2015-12-27T03:13:24.973Z"),"lastHeartbeatRecv" : ISODate("2015-12-27T03:13:26.011Z"),"pingMs" : NumberLong(1),"syncingTo" : "192.168.75.10:27017","configVersion" : 3},{"_id" : 3,"name" : "192.168.75.12:27017","health" : 1,"state" : 2,"stateStr" : "SECONDARY","uptime" : 37,"optime" : {"ts" : Timestamp(1451185968, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2015-12-27T03:12:48Z"),"lastHeartbeat" : ISODate("2015-12-27T03:13:25.028Z"),"lastHeartbeatRecv" : ISODate("2015-12-27T03:13:25.128Z"),"pingMs" : NumberLong(1),"configVersion" : 3}],"ok" : 1}
7) 测试复制情况:
rs0:PRIMARY> use testdbswitched to db testdbrs0:PRIMARY> db.test1231.insert({"name":"test repl"});WriteResult({ "nInserted" : 1 })
rs0:SECONDARY> rs.slaveOk();rs0:SECONDARY> use testdbswitched to db testdbrs0:SECONDARY> show collections;test1231rs0:SECONDARY> db.test1231.find();{ "_id" : ObjectId("567f58f221cb21ff2f187d33"), "name" : "test repl" }
节点重新同步resync:
如果一个节点没有数据,将该结点加入到replication set中,则会自动的完全同步数据。
把一个有数据的结点加入到replication set中:清除--dbpath目录中的内容重启该实例即可。
8)replication set的一些设置
参照:
设置优先级,是否隐藏及延时cfg = rs.conf()cfg.members[0].priority = 0cfg.members[0].hidden = truecfg.members[0].slaveDelay = 3600rs.reconfig(cfg)
设置选举权:cfg = rs.conf()cfg.members[3].votes = 0cfg.members[4].votes = 0cfg.members[5].votes = 0rs.reconfig(cfg)
浙公网安备 33010602011771号