在mongodb中,數據同步有兩種類型:
master/slave:主從。已經廢棄,被副本集取代。
replica set:副本集。
一個副本集只能有一個主節點,可以有多個從節點。主節點可以讀寫,從節點只能讀。
https://docs.mongodb.com/v2.6/core/replica-set-members/

主節點將數據修改操作保存至oplog中。
需要奇數個節點,至少三個節點。
心跳信息每兩秒傳遞一次。
通過選舉,實現自動故障轉移。主節點宕機后會進行自動選舉。

副本集中的從節點的特殊類型:
https://docs.mongodb.com/v2.6/core/replica-set-secondary/
1、0優先級節點:冷備節點,參與選舉,但不會被選舉成為主節點。
2、隱藏的從節點:首先是一個0優先級節點,並且對客戶端不可見。
3、延遲復制從節點:首先是一個0優先級節點,並且復制時間落后於主節點一個固定時長。持有的數據始終為過期數據。
4、arbiter:仲裁節點,不持有數據。

oplog:每個節點都有oplog,但只有主節點會寫oplog,然后同步給從節點。是一個大小固定的文件,存儲在local庫中。
新加入的節點數據同步的過程:
1、初始同步:initial sync
2、回滾后追趕:post-rollback catch-up
3、切分塊遷移:sharding chunk migrations
local數據庫:存放了所有元數據和oplog。用於存儲oplog的collection的名稱為oplog.rs。
--oplogSize arg:size to use (in MB) for replication oplog. default is 5% of disk space. 指定oplog的大小。默認為磁盤大小的5%.
會進行初始同步的場景:
1、節點沒有任何數據時。
2、節點丟失副本復制歷史。
初始同步的步驟:
1、克隆所有數據庫。
2、應用數據集的所有改變,即復制oplog並應用於本地。
3、為所有collection構建索引。
ReplicaSet安裝
准備三台機器,系統版本為CentOS7.3
1、修改Hosts
192.168.135.170 node1
192.168.135.171 node2
192.168.135.169 node3
2、分別安裝mongodb
#yum install -y mongodb mongodb-server
3、修改各節點配置文件
#vim /etc/mongod.conf
#bind_ip = 127.0.0.1 新創建的節點記得修改監聽地址,默認只監聽127.0.0.1。
replSet = testSet
replIndexPrefetch = all
4、啟動各節點mongod服務
#systemctl start mongod
> rs.help() 查看常用命令
rs.status():{ replSetGetStatus : 1 } checks repl set status. 顯示復制集的狀態。
rs.initiate():{ replSetInitiate : null } initiates set with default settings. 以默認配置初始化復制集。
rs.conf():get the current configuration object from local.system.replset. 查看當前配置信息。
rs.add(hostportstr):add a new member to the set with default attributes (disconnects). 以默認屬性添加一個新成員到集群。
rs.slaveOk():shorthand for db.getMongo().setSlaveOk(). 在從節點上標記從節點為Ok狀態。
db.isMaster():check who is primary. 檢查誰是主節點。
rs.stepDown([secs]):step down as primary (momentarily) (disconnects). 將主節點降級為從節點,這時會重新選舉。
rs.reconfig(cfg):updates the configuration of a running replica set with cfg (disconnects). 更新配置。
rs.addArb(hostportstr):add a new member which is arbiterOnly:true (disconnects). 添加一個新節點為arbiter節點。
rs.remove(hostportstr):remove a host from the replica set (disconnects). 將一個節點從集群中刪除。
rs.printReplicationInfo():check oplog size and time range. 查看oplog的大小和起始時間范圍。
rs.printSlaveReplicationInfo():check replica set members and replication lag. 查看集群成員的復制延時信息。
5、初始化副本集
> rs.status()
{
"startupStatus" : 3,
"info" : "run rs.initiate(...) if not yet done for the set",
"ok" : 0,
"errmsg" : "can't get local.system.replset config from self or any seed (EMPTYCONFIG)"
}
> rs.initiate()
{
"info2" : "no configuration explicitly specified -- making one",
"me" : "node1:27017",
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
> rs.status()
{
"set" : "testSet",
"date" : ISODate("2017-03-11T05:49:18Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "node1:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 137,
"optime" : Timestamp(1489211281, 1),
"optimeDate" : ISODate("2017-03-11T05:48:01Z"),
"electionTime" : Timestamp(1489211281, 2),
"electionDate" : ISODate("2017-03-11T05:48:01Z"),
"self" : true
}
],
"ok" : 1
}
6、添加新成員至副本集
> rs.add("node2:27017") 添加node2
{ "ok" : 1 }
> rs.add("node3:27017") 添加node3
{ "ok" : 1 }
7、再次查看副本集狀態,這時就能看到三個節點了
> rs.status()
{
"set" : "testSet",
"date" : ISODate("2017-03-11T06:00:29Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "node1:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 808,
"optime" : Timestamp(1489211964, 1),
"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
"electionTime" : Timestamp(1489211281, 2),
"electionDate" : ISODate("2017-03-11T05:48:01Z"),
"self" : true
},
{
"_id" : 1,
"name" : "node2:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 322,
"optime" : Timestamp(1489211964, 1),
"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
"lastHeartbeat" : ISODate("2017-03-11T06:00:28Z"),
"lastHeartbeatRecv" : ISODate("2017-03-11T06:00:29Z"),
"pingMs" : 3,
"syncingTo" : "node1:27017"
},
{
"_id" : 2,
"name" : "node3:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 65,
"optime" : Timestamp(1489211964, 1),
"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
"lastHeartbeat" : ISODate("2017-03-11T06:00:28Z"),
"lastHeartbeatRecv" : ISODate("2017-03-11T06:00:28Z"),
"pingMs" : 5,
"syncingTo" : "node1:27017"
}
],
"ok" : 1
}
8、分別在各從節點設置節點為Ok狀態
> rs.slaveOk()
9、查看副本集配置信息
https://docs.mongodb.com/v2.6/reference/replica-configuration/
> rs.conf()
{
"_id" : "testSet",
"version" : 3,
"members" : [
{
"_id" : 0,
"host" : "node1:27017"
},
{
"_id" : 1,
"host" : "node2:27017"
},
{
"_id" : 2,
"host" : "node3:27017"
}
]
}
10、將主節點降級為從節點
> rs.stepDown()
> rs.status() 這里重新選舉后,node3成為主節點。
{
"set" : "testSet",
"date" : ISODate("2017-03-11T06:40:03Z"),
"myState" : 2,
"syncingTo" : "node3:27017",
"members" : [
{
"_id" : 0,
"name" : "node1:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 3182,
"optime" : Timestamp(1489211964, 1),
"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
"infoMessage" : "syncing to: node3:27017",
"self" : true
},
{
"_id" : 1,
"name" : "node2:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2696,
"optime" : Timestamp(1489211964, 1),
"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
"lastHeartbeat" : ISODate("2017-03-11T06:40:01Z"),
"lastHeartbeatRecv" : ISODate("2017-03-11T06:40:02Z"),
"pingMs" : 6,
"lastHeartbeatMessage" : "syncing to: node1:27017",
"syncingTo" : "node1:27017"
},
{
"_id" : 2,
"name" : "node3:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2439,
"optime" : Timestamp(1489211964, 1),
"optimeDate" : ISODate("2017-03-11T05:59:24Z"),
"lastHeartbeat" : ISODate("2017-03-11T06:40:02Z"),
"lastHeartbeatRecv" : ISODate("2017-03-11T06:40:03Z"),
"pingMs" : 2,
"electionTime" : Timestamp(1489214375, 1),
"electionDate" : ISODate("2017-03-11T06:39:35Z")
}
],
"ok" : 1
}
11、查看副本集信息,這里會顯示oplog大小和起始時間范圍。
> db.printReplicationInfo()
configured oplog size: 2464.306884765625MB
log length start to end: 0secs (0hrs)
oplog first event time: Sat Mar 11 2017 00:59:24 GMT-0500 (EST)
oplog last event time: Sat Mar 11 2017 00:59:24 GMT-0500 (EST)
now: Sat Mar 11 2017 01:46:07 GMT-0500 (EST)
> rs.printReplicationInfo()
configured oplog size: 2464.36328125MB
log length start to end: 6205secs (1.72hrs)
oplog first event time: Sat Mar 11 2017 13:55:07 GMT+0800 (CST)
oplog last event time: Sat Mar 11 2017 15:38:32 GMT+0800 (CST)
now: Sat Mar 11 2017 15:42:26 GMT+0800 (CST)
> rs.printSlaveReplicationInfo()
source: node1:27017
syncedTo: Sat Mar 11 2017 15:38:32 GMT+0800 (CST)
0 secs (0 hrs) behind the primary
source: node3:27017
syncedTo: Sat Mar 11 2017 15:38:32 GMT+0800 (CST)
0 secs (0 hrs) behind the primary
副本集重新選舉的條件:
1、心跳信息
2、節點優先級
3、optime
4、網絡分區
觸發重新選舉的場景:
1、新副本集初始化時
2、從節點聯系不到主節點時
3、主節點降級時
12、修改節點優先級,只能在主節點上修改
https://docs.mongodb.com/v2.6/tutorial/adjust-replica-set-member-priority/
默認優先級為1,優先級的設定范圍為0-1000。
> cfg=rs.conf()
> cfg.members[1].priority = 2
2
> rs.reconfig(cfg) 這時會重新選舉節點2為主節點
2017-03-11T02:38:32.726-0500 DBClientCursor::init call() failed
2017-03-11T02:38:32.796-0500 trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
2017-03-11T02:38:32.825-0500 reconnect 127.0.0.1:27017 (127.0.0.1) ok
reconnected to server after rs command (which is normal)
13、將一個從節點轉換為arbiter
https://docs.mongodb.com/v2.6/tutorial/convert-secondary-into-arbiter/
a、在主節點remove該從節點
b、將從節點stop
c、清空數據目錄
d、啟動服務
e、將節點以arbiter的角色添加到副本集
