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. bootstrap-table表格导出

    在bootstrap-table官网->拓展模块中有导出模块的详细介绍.网址:http://bootstrap-table.wenzhixin.net.cn/zh-cn/extensions/ ...

  2. Selenium处理页面---弹窗、表格、鼠标悬停、frame、下拉框、上传文件

    一.Selenium测试-常用页面处理 1.概述 UI自动化测试(GUI界面层):UI层是用户使用产品的入口,所有功能通过这一层提供给用户,测试工作大多集中在这一层,常见的测试工具有UFT.Robot ...

  3. flask中的response

    1.Response 在flask中你想向前端返回数据,必须是Response的对象,这里和django必须是HttpResponse 对象一样, 主要将返回数据的几种方式 视图函数中return 字 ...

  4. awk分隔符

    最近需要检测日志,shell中用到了awk,因为分割条件不止一个,并且包括了中括号.在此记录一下关于多分隔符并且包含中括号的情况 awk -F'[=,]|[][]+' '{print $6}'

  5. ABAP术语-Call Transaction

    Call Transaction 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/15/1039270.html A data transfe ...

  6. MySQL的日志相关内容

    本篇文章介绍一下mysql的备份和日志,由于备份时需要用到日志,所以在讲备份前,如果日志内容篇幅过长,将会把日志和备份分开单独来讲,先简单介绍一下mysql的日志相关内容. MySQL日志 日志是my ...

  7. Linux常用文档操作命令--1

    1.查看目录下的文档 a) ls(list):查看目录下的所有文档或者文档的信息. 命令行:ls [-a][-A] [-f][-F][-h][-l][-r][-R][-S][-t] 目录名称  //注 ...

  8. jQuery获取data-*属性值

    下面就详细介绍四种方法获取data-*属性的值 <li id="getId" data-id="122" data-vice-id="11&qu ...

  9. Ajax之eval()函数

    Ajax之eval()函数 <!DOCTYPE html> <html> <head lang="en"> <meta charset=& ...

  10. Ubuntu 配置多域名站点

    思路 -- 跟Windows 一样 1添加Nginx 指向项目的入口 配置域名 2修改本地host文件域名指向 实现: 1 进入Nginx 配置文件  默认地址为 /etc/nginx/sites-e ...