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
  1.   db.products.insert(
  2.                         { writeConcern: { w: 2, wtimeout: 5000 } } #至少写入一个从结点
  3.                      )
  4. { 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:
  1. use admin
  2. db.runCommand( { resync: 1 } )  
修改slave的配置信息然后重启slave:
  1. use local
  2. db.sources.update( { host : "prod.mississippi" },
  3. { $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)初始化复制集(没有配置信息)
  1. > rs.initiate();
  2. {
  3. "info2" : "no configuration specified. Using a default configuration for the set",
  4. "me" : "node1:27017",
  5. "ok" : 0,
  6. "errmsg" : "No host described in new configuration 1 for replica set repl0 maps to this node",
  7. "code" : 93
  8. }
4)验证初始配置
  1. > rs.conf();
  2. 2015-12-27T11:04:15.763+0800 E QUERY [thread1] Error: Could not retrieve replica set config: {
  3. "info" : "run rs.initiate(...) if not yet done for the set",
  4. "ok" : 0,
  5. "errmsg" : "no replset config has been received",
  6. "code" : 94
  7. } :
  8. rs.conf@src/mongo/shell/utils.js:1090:11
  9. @(shell):1:1
  10. > cfg={"_id":"rs0","version":1,"members":[{"_id":1,"host":"192.168.75.10:27017"}]};
  11. {
  12. "_id" : "rs0",
  13. "version" : 1,
  14. "members" : [
  15. {
  16. "_id" : 1,
  17. "host" : "192.168.75.10:27017"
  18. }
  19. ]
  20. }
  21. > rs.initiate(cfg);
  22. { "ok" : 1 }

5)在复制集中加入节点
  1. rs0:PRIMARY> rs.add("192.168.75.11:27017");
  2. { "ok" : 1 }
  3. rs0:PRIMARY> rs.add("192.168.75.12:27017");
  4. { "ok" : 1 }
6)检查复制集状态
  1. rs0:PRIMARY> rs.status();
  2. {
  3. "set" : "rs0",
  4. "date" : ISODate("2015-12-27T03:13:26.970Z"),
  5. "myState" : 1,
  6. "term" : NumberLong(1),
  7. "heartbeatIntervalMillis" : NumberLong(2000),
  8. "members" : [
  9. {
  10. "_id" : 1,
  11. "name" : "192.168.75.10:27017",
  12. "health" : 1,
  13. "state" : 1,
  14. "stateStr" : "PRIMARY",
  15. "uptime" : 575,
  16. "optime" : {
  17. "ts" : Timestamp(1451185968, 1),
  18. "t" : NumberLong(1)
  19. },
  20. "optimeDate" : ISODate("2015-12-27T03:12:48Z"),
  21. "electionTime" : Timestamp(1451185613, 2),
  22. "electionDate" : ISODate("2015-12-27T03:06:53Z"),
  23. "configVersion" : 3,
  24. "self" : true
  25. },
  26. {
  27. "_id" : 2,
  28. "name" : "192.168.75.11:27017",
  29. "health" : 1,
  30. "state" : 2,
  31. "stateStr" : "SECONDARY",
  32. "uptime" : 41,
  33. "optime" : {
  34. "ts" : Timestamp(1451185968, 1),
  35. "t" : NumberLong(1)
  36. },
  37. "optimeDate" : ISODate("2015-12-27T03:12:48Z"),
  38. "lastHeartbeat" : ISODate("2015-12-27T03:13:24.973Z"),
  39. "lastHeartbeatRecv" : ISODate("2015-12-27T03:13:26.011Z"),
  40. "pingMs" : NumberLong(1),
  41. "syncingTo" : "192.168.75.10:27017",
  42. "configVersion" : 3
  43. },
  44. {
  45. "_id" : 3,
  46. "name" : "192.168.75.12:27017",
  47. "health" : 1,
  48. "state" : 2,
  49. "stateStr" : "SECONDARY",
  50. "uptime" : 37,
  51. "optime" : {
  52. "ts" : Timestamp(1451185968, 1),
  53. "t" : NumberLong(1)
  54. },
  55. "optimeDate" : ISODate("2015-12-27T03:12:48Z"),
  56. "lastHeartbeat" : ISODate("2015-12-27T03:13:25.028Z"),
  57. "lastHeartbeatRecv" : ISODate("2015-12-27T03:13:25.128Z"),
  58. "pingMs" : NumberLong(1),
  59. "configVersion" : 3
  60. }
  61. ],
  62. "ok" : 1
  63. }

7) 测试复制情况:
  1. rs0:PRIMARY> use testdb
  2. switched to db testdb
  3. rs0:PRIMARY> db.test1231.insert({"name":"test repl"});
  4. WriteResult({ "nInserted" : 1 })
  1. rs0:SECONDARY> rs.slaveOk();
  2. rs0:SECONDARY> use testdb
  3. switched to db testdb
  4. rs0:SECONDARY> show collections;
  5. test1231
  6. rs0:SECONDARY> db.test1231.find();
  7. { "_id" : ObjectId("567f58f221cb21ff2f187d33"), "name" : "test repl" }

节点重新同步resync:
如果一个节点没有数据,将该结点加入到replication set中,则会自动的完全同步数据。
把一个有数据的结点加入到replication set中:清除--dbpath目录中的内容重启该实例即可。

8)replication set的一些设置
参照:
  1. 设置优先级,是否隐藏及延时
  2. cfg = rs.conf()
  3. cfg.members[0].priority = 0
  4. cfg.members[0].hidden = true
  5. cfg.members[0].slaveDelay = 3600
  6. rs.reconfig(cfg)
  1. 设置选举权:
  2. cfg = rs.conf()
  3. cfg.members[3].votes = 0
  4. cfg.members[4].votes = 0
  5. cfg.members[5].votes = 0
  6. rs.reconfig(cfg)











MongoDB的复制一:复制的原理的更多相关文章

  1. MongoDB之Replica Set(复制集复制)

    MongoDB支持两种复制模式: 主从复制(Master/Slave) 复制集复制(Replica Set) 下面主要记录我在centos虚拟机上安装replica set,主要参考:http://d ...

  2. Studio 3T for MongoDB连接51.212复制集

    Studio 3T for MongoDB连接51.212复制集 [ #DirectConection Authentication Mode - Basic(MONGODB-CR or SCEAM- ...

  3. Java基础-输入输出-3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc。

    3.编写BinIoDemo.java的Java应用程序,程序完成的功能是:完成1.doc文件的复制,复制以后的文件的名称为自己的学号姓名.doc. try { FileInputStream in = ...

  4. iOS开发之Copy & MutableCopy及深复制 & 浅复制

    1.使用copy或mutableCopy方法可以创建一个对象的副本. copy: (1)需要实现NSCoppying协议 (2)创建的是不可变副本(如NSString.NSArray.NSDictio ...

  5. 简单理解php深复制浅复制问题

    其实接触深复制浅复制是通过学习c++了解到的,比如c++很好用的模板,php是不允许方法模板和类模板 一个简单的例子,如果不是很了解php 的取地址符&,可以去看下官方文档,php的& ...

  6. [No0000B9]C# 类型基础 值类型和引用类型 及其 对象复制 浅度复制vs深度复制 深入研究2

    接上[No0000B5]C# 类型基础 值类型和引用类型 及其 对象判等 深入研究1 对象复制 有的时候,创建一个对象可能会非常耗时,比如对象需要从远程数据库中获取数据来填充,又或者创建对象需要读取硬 ...

  7. MySQL的并行复制多线程复制MTS(Multi-Threaded Slaves)

    MySQL的并行复制多线程复制MTS(Multi-Threaded Slaves) http://www.tuicool.com/articles/m2Unmeq 姜承饶 简称MTS:基于binlog ...

  8. java 浅复制 深复制

    1.浅复制 只是复制引用,对引用的操作会影响之前复制的对象. 2.深复制 复制一个完全独立的对象,复制对象与被复制对象相互之间不影响. 只是概念性东西....

  9. HDFS源码分析数据块复制选取复制源节点

    数据块的复制当然需要一个源数据节点,从其上拷贝数据块至目标数据节点.那么数据块复制是如何选取复制源节点的呢?本文我们将针对这一问题进行研究. 在BlockManager中,chooseSourceDa ...

  10. java 及 Jquery中的深复制 浅复制

    发现问题:最近 遇到由于复制对象之后,改变复制后的新变量,原先被复制的对象居然会跟着变. EX:java中: //holidayConfig.getEnd_time()会随着sTime的改变而改变 s ...

随机推荐

  1. ccenteros 部署 redis

    step one :  yum install redis    -- 安装redis数据库 step two:安装完成之后开启redis 服务 service redis start   syste ...

  2. 看我如何使用IDEA引入GitHub上的Maven项目,从Clone到打开,图文步骤,你绝对看的懂!!

    废话不多说,就一个字:干! 1.登录GitHub,复制项目仓库的地址 2.打开IDEA,选择git(三种方式选择) 第一种方式: 第二种方式: 第三种方式: 选择git后 3.下面是我改存放的目录 正 ...

  3. poj 2186 Popular Cows :求能被有多少点是能被所有点到达的点 tarjan O(E)

    /** problem: http://poj.org/problem?id=2186 当出度为0的点(可能是缩点后的点)只有一个时就存在被所有牛崇拜的牛 因为如果存在有两个及以上出度为0的点的话,他 ...

  4. Python实现爬虫从网络上下载文档

    最近在学习Python,自然接触到了爬虫,写了一个小型爬虫软件,从初始Url解析网页,使用正则获取待爬取链接,使用beautifulsoup解析获取文本,使用自己写的输出器可以将文本输出保存,具体代码 ...

  5. haproxy+keepalived主备与双主模式配置

    Haproxy+Keepalived主备模式 主备节点设置 主备节点上各安装配置haproxy,配置内容且要相同 global log 127.0.0.1 local2 chroot /var/lib ...

  6. android Volley+Gson的使用

    听说Volley框架非常好用,今天试了一下post请求,果然如此,因为我传的是json获取的也是json所以就写了一种关于json的请求,其实其他的代码都差不多.首先要先创建一个全局的变量,请求入队列 ...

  7. Array-快餐管饱

    一.如何获得一个数组? rsp: 1. []  2.new Array() 3.str.split() ps:new Array()可以不加括号,其传一个参数代表数组长度,两个及以上就是初始化数组. ...

  8. (转载)jsp的内部方法jspInit(),_jspService(),jspDestroy()

    jspInit(){}:jsp Page被初始化的时候调用该方法,并且该方法仅在初始化时执行一次,所以可以在这里进行一些初始化的参数配置等一次性工作,由作者创建jspDestroy(){}:jsp P ...

  9. Axure RP Extension for Chrome安装

    Axure RP Extension for Chrome安装 Axure RP Extension for Chrome是一款谷歌插件,主要可以用来查看原型文件.以前安装插件的时候总是找半天资源,很 ...

  10. Apache Maven(六):存储库

    Maven 存储库主要是存放一些第三方依赖jar包等. 严格来说,只有两种存储库:本地和远程,本地存储库是指您远程下载到本地的一个缓存,还包含尚未发布的临时构建文件.远程存储库是指一些可以通过各种协议 ...