mongoDB的复制集2----同步机制(工作原理,oplog详解,初始化同步的过程

来源:互联网 发布:广联达造价软件价格 编辑:程序博客网 时间:2024/05/01 18:33

                      

一、复制集是怎么工作的

1-1.复制集工作原理

    Mongodb复制集由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点,Mongodb Driver(客户端)的所有数据都写入Primary,Secondary从Primary同步写入的数据,以保持复制集内所有成员存储相同的数据集,提供数据的高可用。
    下图(图片源于Mongodb官方文档)是一个典型的Mongdb复制集,包含一个Primary节点和2个Secondary节点。

    mongodb集群:复制,复制集和分片。 强烈建议在生产环境中使用mongodb的复制功能。复制具有故障切换,读扩展,热备份和离线批处理操作。
默认情况下,主节点负责客户端所有的读写请求,从节点不可读不可写。

工作原理
    1). mongodb的复制至少需要两个实例。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
    2). 主节点的操作记录称为oplog(operation log),存储在local数据库中(local数据库不会被复制,用来存放复制状态信息的)。oplog中的每个文档代表着主节点上执行的操作。oplog只作为从节点与主节点保持数据同步的机制。
    3). oplog.rs是一个固定长度的capped collection。默认情况下,64位的实例将使用oplog 5%的可用空间,这个空间将在local数据库中分配,并在服务器启动时预先分配。
    4). 如果从节点落后主节点很远了,oplog日志从节点还没执行完,oplog可能已经轮滚一圈了,那么从节点将会追赶不上主节点了,复制将会停止。从节点需要重新做完整的同步,可以用{resync:1}命令来手动执行重新同步或在启动从节点时指定--autoresync选项让其自动重新同步。重新同步的代价昂贵,应尽量避免,避免的方法就是配置足够大的oplog。
查看oplog信息:db.oplog.rs.stats()

查看oplog.rs内容:db.oplog.rs.find().limit(1).to

1-2.oplog是复制集的复制源

字段说明:
ts:操作的时间戳(8字节),用于跟踪操作执行的时间。
h : 此操作的独一无二的ID
v : oplog的版本
op:操作类型,i代表插入,u代表更新,d代表delete,cmd, null
ns:执行操作的集合名(命名空间),以db_name,coll_name
o : 操作对应的文档
o2: 仅update操作时有更新操作的变更条件

changwen:PRIMARY> use changwenswitched to db changwenchangwen:PRIMARY> db.changwen2.insert({"name":"insert_oplog_test"})WriteResult({ "nInserted" : 1 })changwen:PRIMARY> use localswitched to db localchangwen:PRIMARY> db.oplog.rs.find().sort({$natural:-1}).limit(1).pretty(){"ts" : Timestamp(1472480366, 1),"t" : NumberLong(2),"h" : NumberLong("-560593709840393662"),"v" : 2,"op" : "i","ns" : "changwen.changwen2","o" : {"_id" : ObjectId("57c4446e0c13aa68781c47d5"),"name" : "insert_oplog_test"}}------------------------------------------------changwen:PRIMARY> use changwenswitched to db changwenchangwen:PRIMARY> db.changwen2.update({"name":"insert_oplog_test"},{$set:{"name":"update_oplog_test"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })changwen:PRIMARY> use localswitched to db localchangwen:PRIMARY> db.oplog.rs.find().sort({$natural:-1}).limit(1).pretty(){"ts" : Timestamp(1472481441, 1),"t" : NumberLong(2),"h" : NumberLong("6796117594516952707"),"v" : 2,"op" : "u","ns" : "changwen.changwen2","o2" : {"_id" : ObjectId("57c4446e0c13aa68781c47d5")},"o" : {"$set" : {"name" : "update_oplog_test"}}}-----------------------------------------------changwen:PRIMARY> use changwenswitched to db changwenchangwen:PRIMARY> db.changwen2.remove({"name":"update_oplog_test"})WriteResult({ "nRemoved" : 1 })changwen:PRIMARY> use localswitched to db localchangwen:PRIMARY> db.oplog.rs.find().sort({$natural:-1}).limit(1).pretty(){"ts" : Timestamp(1472481535, 1),"t" : NumberLong(2),"h" : NumberLong("-2737498259321252386"),"v" : 2,"op" : "d","ns" : "changwen.changwen2","o" : {"_id" : ObjectId("57c4446e0c13aa68781c47d5")}}--不要对数据进行物理删除,要进行逻辑删除,类似备份

2-3.oplog的数据结构

oplog:
  特点:封顶表Capped collection滚动覆盖写入,固定大小
  什么是封顶表?
  创建封顶表命令
   db.createCollection("coll_name",
      {capped:true,size:1024*1024*1024*4,[max:5000]})
  --上面的大小为4G,[]为可选

  默认大小:64位Linux,windows操作系统为当前分区可用空间5%,体积不会超过50G
            --oplogSize 单位是mb

  复制时间窗口:
    按记录条数封顶
    按文件体积封顶)(设置大小可以为40G)

二、复制集初始化同步的过程

  初始前需要在配置文件设置replSet。
  如下流程图是已存在的复制集,往这个复制集添加新的节点的流程。(添加节点命令rs.add()或者rs.addArb())


三、复制集的管理维护

  1.眼光长远
    即使(暂时)只有一台服务器,也要以单节点模式启动复制集
    1).单机多实例启动复制集
    2).单节点启动复制集

3-1.单节点启动复制集如下

# 创建两个启动和连接shell脚本changwen@ubuntu:~/shell$ cat start_mongoDB.sh #!/bin/bashport=$1sudo /usr/local/mongoDB/bin/mongod -f /usr/local/mongoDB/conf/$port.confchangwen@ubuntu:~/shell$ cat link_mongoDB.sh #!/bin/bashport=$1sudo /usr/local/mongoDB/bin/mongo  192.168.23.129:$port# 启动数据库changwen@ubuntu:~/shell$ sh link_mongoDB.sh 28001......> config = { _id:"changwen", members:[ {_id:0, host:"192.168.23.129:28001"}]}{"_id" : "changwen","members" : [{"_id" : 0,"host" : "192.168.23.129:28001"}]}> rs.initiate(config){ "ok" : 1 }changwen:OTHER> # 过大概一分钟再按enterchangwen:PRIMARY> rs.status(){"set" : "changwen","date" : ISODate("2016-08-30T14:26:59.829Z"),"myState" : 1,"term" : NumberLong(1),"heartbeatIntervalMillis" : NumberLong(2000),"members" : [{"_id" : 0,"name" : "192.168.23.129:28001","health" : 1,"state" : 1,"stateStr" : "PRIMARY","uptime" : 1159,"optime" : {"ts" : Timestamp(1472567178, 1),"t" : NumberLong(1)},"optimeDate" : ISODate("2016-08-30T14:26:18Z"),"infoMessage" : "could not find member to sync from","electionTime" : Timestamp(1472567177, 2),"electionDate" : ISODate("2016-08-30T14:26:17Z"),"configVersion" : 1,"self" : true}],"ok" : 1}changwen:PRIMARY> show dbslocal  0.000GBchangwen:PRIMARY> use changwenDBswitched to db changwenDBchangwen:PRIMARY> dbchangwenDBchangwen:PRIMARY> db.test.save({"name":"relpSet_initiate"})WriteResult({ "nInserted" : 1 })changwen:PRIMARY> db.test.find(){ "_id" : ObjectId("57c597e85d6786a802bee7c5"), "name" : "relpSet_initiate" }# 如果再增加实例,不要先配置文件(这样会有一小段时间的断开),用add方法changwen:PRIMARY> rs.addrs.add(     rs.addArb(changwen:PRIMARY> rs.add
以上就是部署好单节点 的复制集

3-2.暂停服务

# 在上面的基础上操作changwen:PRIMARY> rs.add({_id:1,host:"192.168.23.129:28002"}){ "ok" : 1 }changwen:PRIMARY> rs.add({_id:2,host:"192.168.23.129:28003"}){ "ok" : 1 }# 将发出这个命令的节点冻结changwen:PRIMARY> rs.freeze(100){ "ok" : 1 }# stepDown在多少秒的时间内让出主节点changwen:PRIMARY> rs.stepDown(100)......changwen:SECONDARY> # 然后就可以对28001进行其它操作了

3-3.修改复制集成员属性

  大多数操作都要主节点操作,所以需要直接在主节点操作

#如果其中一台服务器性能好,我们需要每次启动时都使用它,如下:changwen:PRIMARY> config=rs.conf()changwen:PRIMARY> config.members[0]{"_id" : 0,"host" : "192.168.23.129:28001","arbiterOnly" : false,"buildIndexes" : true,"hidden" : false,"priority" : 1,"tags" : {},"slaveDelay" : NumberLong(0),"votes" : 1}# 其中priority默认是1changwen:PRIMARY> config.members[0].priority=55# 让配置文件生效changwen:PRIMARY> rs.reconfig(config){ "ok" : 1 }changwen:PRIMARY> 2016-08-30T08:07:19.265-0700 I NETWORK  [thread1] trying reconnect to 192.168.23.129:28002 (192.168.23.129) failed2016-08-30T08:07:19.266-0700 I NETWORK  [thread1] reconnect 192.168.23.129:28002 (192.168.23.129) ok# 过段时间就成了从节点 changwen:SECONDARY> # 在连接28001服务就会成从节点变成主节点
人工干预选举和创建索引
  1).将priority进行修改
  2).将主节点rs.freeze(),rs.stepDown()

3-4.调整oplog大小

  尽量变大,没事别变小





0 0
原创粉丝点击