MongoDB在單節點中也能夠作複製集,可是僅限於測試實驗,最大的好處就是部署方便快速,能夠隨便添加新節點,節省資源。在這裏我使用的是MongoDB 2.6版本進行復制集實驗(但MongoDB配置文件使用的是老版本格式),一共使用三個節點,一個是主節點(PRIMARY),一個是從節點(SECONDARY),一個是投票節點(ARBITER)。以下圖:node
1、實驗環境linux
1)節點信息:192.168.60.60mongodb
3)節點確保iptables和selinux已關閉shell
1
2
|
[root@node1 ~]# iptables -F
[root@node1 ~]# setenforce 0
|
2、安裝MongoDB 2.6數據庫
1
2
3
4
5
|
mongodb-org-mongos-2.6.0-1.x86_64.rpm
mongodb-org-tools-2.6.0-1.x86_64.rpm
mongodb-org-server-2.6.0-1.x86_64.rpm
mongodb-org-shell-2.6.0-1.x86_64.rpm
mongodb-org-2.6.0-1.x86_64.rpm
|
PS:須要的軟件包能夠去http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/下載,MongoDB的安裝很簡單,怎麼安裝都成。數組
3、配置單點複製集(啓動三個套接字)架構
1)建立所須要的目錄app
1
2
3
4
5
6
|
[root@node3 ~]# mkdir -p /mongodb/{conf,log,pid,data}
[root@node3 ~]# mkdir -p /mongodb/conf/{conf27017,conf27018,conf27019}
[root@node3 ~]# mkdir -p /mongodb/log/{log27017,log27018,log27019}
[root@node3 ~]# mkdir -p /mongodb/pid/{pid27017,pid27018,pid27019}
[root@node3 ~]# mkdir -p /mongodb/data/{data27017,data27018,data27019}
[root@node3 ~]# chown -R mongod.mongod /mongodb/data/{data27017,data27018,data27019}
|
2)建立三個配置文件tcp
192.168.60.60:27017ide
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[root@node3 ~]# vi /mongodb/conf/conf27017/mongod.conf
###Base configure
logpath = /mongodb/log/log27017/mongod.log
logappend = true
dbpath = /mongodb/data/data27017
port = 27017
bind_ip=192.168.60.60
fork = true
pidfilepath = /mongodb/pid/pid27017/mongod.pid
logRotate = rename
timeStampFormat = ctime
#Replica Set
oplogSize = 1024
replSet = ywnds
replIndexPrefetch = _id_only
PS:具體參數含義請看《MongoDB命令行選項介紹》
|
192.168.60.60:27018
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[root@node3 ~]# vi /mongodb/conf/conf27018/mongod.conf
###Base configure
logpath = /mongodb/log/log27018/mongod.log
logappend = true
dbpath = /mongodb/data/data27018
port = 27018
bind_ip=192.168.60.60
fork = true
pidfilepath = /mongodb/pid/pid27018/mongod.pid
logRotate = rename
timeStampFormat = ctime
#Replica Set
oplogSize = 1024
replSet = ywnds
replIndexPrefetch = _id_only
|
192.168.60.60:27019
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[root@node3 ~]# vi /mongodb/conf/conf27019/mongod.conf
###Base configure
logpath = /mongodb/log/log27019/mongod.log
logappend = true
dbpath = /mongodb/data/data27019
port = 27019
bind_ip=192.168.60.60
fork = true
pidfilepath = /mongodb/pid/pid27019/mongod.pid
logRotate = rename
timeStampFormat = ctime
#Replica Set
oplogSize = 1024
replSet = ywnds
replIndexPrefetch = _id_only
|
3)啓動集羣(全部節點)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
[root@node3 mongodb]# killall mongod
[root@node3 mongodb]# mongod -f /mongodb/conf/conf27019/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 35554
child process started successfully, parent exiting
[root@node3 mongodb]# mongod -f /mongodb/conf/conf27018/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 35601
child process started successfully, parent exiting
[root@node3 mongodb]# mongod -f /mongodb/conf/conf27017/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 35648
child process started successfully, parent exiting
|
查看進程
1
2
3
4
|
[root@node3 ~]# netstat -anplt | grep mongod
tcp 0 0 192.168.60.60:27019 0.0.0.0:* LISTEN 35554/mongod
tcp 0 0 192.168.60.60:27017 0.0.0.0:* LISTEN 35648/mongod
tcp 0 0 192.168.60.60:27018 0.0.0.0:* LISTEN 35601/mongod
|
4)選擇一個節點作主節點(能夠隨意選擇一個,這裏我使用21017)
1
2
3
4
|
[root@node3 ~]# mongo 192.168.60.60:27017/admin
MongoDB shell version: 2.6.0
connecting to: 192.168.60.60:27017/admin
>
|
5)初始化27017節點
5.1.爲複製集初始化創建配置文檔
1
2
3
4
5
6
7
|
> config = {
_id:"ywnds",
members:[
{_id:0,host:"192.168.60.60:27017"},
{_id:1,host:"192.168.60.60:27018"},
{_id:2,host:"192.168.60.60:27019"}
]}
|
5.2.更新配置文檔參數,設置27019爲arbiterOnly(投票節點)
1
|
> config.members[2] = {"_id":2,"host":"192.168.60.60:27019","arbiterOnly":true}
|
PS:上面是把複製集初始化配置文檔賦值給config變量,這裏是經過membes數組的索引來修改節點屬性,數組索引從0開始。
具體的配置文檔說明請看《MongoDB複製集配置文檔介紹》
5.3.使用rs.initiate(cfg)初始化集羣
1
2
3
4
5
|
> rs.initiate(config)
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
|
這裏使用rs.initiate(config)初始化集羣,config文件爲咱們上面定義的。這裏的ok返回值爲1表示命令執行成功,若是爲0則表示沒有執行成功。跟Linux中的狀態值恰好相反。如今可使用rs.conf()方法返回配置文件內容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
ywnds:PRIMARY> rs.conf()
{
"_id" : "ywnds",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "192.168.60.60:27017"
},
{
"_id" : 1,
"host" : "192.168.60.60:27018"
},
{
"_id" : 2,
"host" : "192.168.60.60:27019",
"arbiterOnly" : true
}
]
}
|
5.4.查看集羣狀態
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
ywnds:PRIMARY> rs.status()
{
"set" : "ywnds",
"date" : ISODate("2016-02-03T01:56:49Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.60.60:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1043,
"optime" : Timestamp(1454464583, 1),
"optimeDate" : ISODate("2016-02-03T01:56:23Z"),
"electionTime" : Timestamp(1454464592, 1),
"electionDate" : ISODate("2016-02-03T01:56:32Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.60.60:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 25,
"optime" : Timestamp(1454464583, 1),
"optimeDate" : ISODate("2016-02-03T01:56:23Z"),
"lastHeartbeat" : ISODate("2016-02-03T01:56:48Z"),
"lastHeartbeatRecv" : ISODate("2016-02-03T01:56:47Z"),
"pingMs" : 2,
"syncingTo" : "192.168.60.60:27017"
},
{
"_id" : 2,
"name" : "192.168.60.60:27019",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 25,
"lastHeartbeat" : ISODate("2016-02-03T01:56:48Z"),
"lastHeartbeatRecv" : ISODate("2016-02-03T01:56:47Z"),
"pingMs" : 0
}
],
"ok" : 1
}
|
咱們的集羣中有三個節點,由狀態返回值能夠看出27017爲PRIMARY節點,而27018爲SECONDARY節點,而27019爲咱們設置的ARBITER節點。這裏咱們發現mongodb的角標已經變了,變成了複製集名稱加上當前節點的狀態。一樣若是登錄27018和27019會發現都發生了變化。
5.5.查看主節點local庫
1
2
3
4
5
6
7
8
9
|
ywnds:PRIMARY> use local
switched to db local
ywnds:PRIMARY> show tables
me
oplog.rs
slaves
startup_log
system.indexes
system.replset
|
這裏咱們看一下本地的local庫,每個mongod實例都有本身的local數據庫,其中存儲了複製進程所用的數據和其餘實例單獨的信息,local數據庫對於複製時不可見的,local數據庫將不會被複制。
進入到local庫能夠看到一些集合和索引文件,其中startup_log 是一個固定集合,該集合主要是用來診斷的(每一個mongod 實例向 startup_log 插入一條有關mongod實例自身和host信息的診斷信息);system.replset保存了複製集的配置文檔信息(就是咱們上面定義的config),跟rs.conf()返回的信息同樣;oplog.rs是一個存儲了oplog的固定集合,大小爲咱們在配置文件中設置的大小;slaves包含了複製集每一個節點和與其通信的最後時間戳。若是該集合過期了,咱們能夠經過刪除該節點來讓複製集自動刷新生成。
6)驗證複製集
192.168.60.60:27017插入數據
1
2
3
4
5
6
7
|
[root@node3 ~]# mongo 192.168.60.60:27017
MongoDB shell version: 2.6.0
connecting to: 192.168.60.60:27017/test
ywnds:PRIMARY> use ywnds
switched to db ywnds
ywnds:PRIMARY> db.ywnds.insert({name:"ywnds",age:"20",gender:"B"})
WriteResult({ "nInserted" : 1 })
|
而後咱們來看一下主節點的數據目錄(MMAPV1存儲引擎爲例):
1
2
3
4
5
6
7
8
9
|
[root@node3 ~]# ll -h /mongodb/data/data27017/
總用量
2.2G
drwxr-xr-x. 2 mongod mongod 4.0K 2月 4 07:58 journal
-rw-------. 1 mongod mongod 64M 2月 4 07:58 local.0
-rw-------. 1 root root 2.0G 2月 3 11:31 local.1
-rw-------. 1 mongod mongod 16M 2月 4 07:58 local.ns
-rwxr-xr-x. 1 mongod mongod 6 2月 4 07:58 mongod.lock
-rw-------. 1 root root 64M 2月 3 11:31 ywnds.0
-rw-------. 1 root root 16M 2月 3 11:31 ywnds.ns
|
這裏咱們能夠看到,local數據庫的物理文件local.0和local.1。Mongodb默認第一個物理文件爲64M,名字爲local.0,而後依次爲local.1…N。而local數據庫的命名空間文件「local.ns」默認爲16M,前面咱們在說命令行選項的時候就說過命名空間文件,每個數據庫都會有一個命名空間NS文件,記錄當前數據庫每個物理文件,如local.0、local.1它們之間的聯繫,同時也記錄當前這個庫中每個集合裏的索引信息。
192.168.60.60:27018同步數據
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[root@node3 ~]# mongo 192.168.60.60:27018
MongoDB shell version: 2.6.0
connecting to: 192.168.60.60:27018/test
ywnds:SECONDARY> show dbs
admin (empty)
local 2.077GB
ywnds 0.078GB
ywnds:SECONDARY> use ywnds
switched to db ywnds
ywnds:SECONDARY> show tables
2016-02-03T11:34:24.505+0800 error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
ywnds:SECONDARY> db.ywnds.insert({name:"eric",age:20})
WriteResult({ "writeError" : { "code" : undefined, "errmsg" : "not master" } })
ywnds:SECONDARY> rs.slaveOk(true)
ywnds:SECONDARY> show tables
system.indexes
ywnds
|
咱們看到數據已經同步過來了,可是若是咱們不是經過驅動鏈接從節點的話,咱們查看數據時會報錯,說咱們不是master節點,且slaveOK=false,因此查看不了。MongoDB在數據一致性上確實下了很大的功夫啊。那麼也就是說若是從節點想查看數據就須要開啓slaveOK,而且在從節點上是沒法進行寫入操做的。
而後咱們開啓rs.slaveOk立馬就能夠查看同步的數據了。
192.168.60.60:27019投票節點
1
2
3
4
5
6
7
8
9
10
11
12
13
|
[root@node3 ~]# mongo 192.168.60.60:27019
MongoDB shell version: 2.6.0
connecting to: 192.168.60.60:27019/test
ywnds:ARBITER> show dbs
admin (empty)
local 0.078GB
ywnds:ARBITER> use local
switched to db local
ywnds:ARBITER> show tables
me
startup_log
system.indexes
system.replset
|
鏈接到投票節點,咱們能夠看到PRIMARY上的數據沒有同步到投票節點上來,沒有ywnds這個庫。可是這裏須要說明的是,咱們能夠看到arbiter雖然不一樣步數據可是local庫卻有system.indexes和system.replset這兩個文件。其次咱們看一下arbiter節點的數據目錄。
1
2
3
4
5
6
|
[root@node3 ~]# ll -h /mongodb/data/data27019/
總用量
81M
drwxr-xr-x. 2 mongod mongod 4.0K 2月 3 09:56 journal
-rw-------. 1 mongod mongod 64M 2月 3 09:56 local.0
-rw-------. 1 mongod mongod 16M 2月 3 09:56 local.ns
-rwxr-xr-x. 1 mongod mongod 6 2月 3 09:39 mongod.lock
|
能夠發現咱們所說的庫物理文件的第一個文件默認大小爲64M,而命名空間文件爲16M。
4、按照功能來區分複製集成員
從上面的分析能夠看出三個節點的不一樣之處,也能夠這麼說,上面咱們是按照數據來區分不一樣的複製集節點,那麼下面咱們按照功能上來區分各個節點。先來簡單說一下各個節點狀態的不一樣所能提供的功能有哪些?
主節點(PRIMARY):默認提供讀寫服務的節點。
從節點(SECONDARY):提供讀服務的節點,但能夠提供多樣性服務,如能夠轉爲「隱藏節點」對程序不可見、轉爲「延時節點」延時複製節點、轉爲「投票節點」具備投票權但不是arbiter。
投票節點(ARBITER):ARBITER節點,無數據,僅做選舉和充當複製集節點、也稱它爲選舉節點。
5、複製集自動容災
Mongodb複製集最大的特色就是能夠自動容災,這個特性是從主從複製的架構上改變而來,簡單來講就是當複製集(3節點)中若是PRIMARY發生故障,其餘節點沒法探測到它的心跳信息時,複製集就會產生重新投票選出一個新的PRIAMRY提供服務。下面咱們來模擬一下MongoDB的自動故障轉移功能。
咱們鏈接到27017主機上,此時的27017是PRIMARY
1
2
3
4
|
[root@node3 ~]# mongo 192.168.60.60:27017
MongoDB shell version: 2.6.0
connecting to: 192.168.60.60:27017/test
ywnds:PRIMARY>
|
咱們鏈接到27018主機上,此時的27018是SECONDARY
1
2
3
4
|
[root@node3 ~]# mongo 192.168.60.60:27018
MongoDB shell version: 2.6.0
connecting to: 192.168.60.60:27018/test
ywnds:SECONDARY>
|
咱們鏈接到27019主機上,此時的27019是ARBITER
1
2
3
4
|
[root@node3 ~]# mongo 192.168.60.60:27019
MongoDB shell version: 2.6.0
connecting to: 192.168.60.60:27019/test
ywnds:ARBITER>
|
模擬主節點宕機,kill掉27017的進程。
1
2
3
4
5
6
|
[root@node3 ~]# cat /mongodb/pid/pid27017/mongod.pid
125484
[root@node3 ~]# kill -2 125484
[root@node3 ~]# ps aux | grep mongod
root 125581 0.5 7.9 5266620 48252 ? Sl 04:07 0:00 mongod -f /mongodb/conf/conf27018/mongod.conf
root 125670 0.5 5.1 849056 31440 ? Sl 04:07 0:00 mongod -f /mongodb/conf/conf27019/mongod.conf
|
而後登陸27018主機上,看看此時的SECONDARY已經轉爲PRIMARY了,可是這個過程會有短暫的斷開。
1
2
3
4
|
[root@node3 ~]# mongo 192.168.60.60:27018
MongoDB shell version: 2.6.0
connecting to: 192.168.60.60:27018/test
ywnds:PRIMARY>
|
而27019主機上ARBITER仍是ARBITER節點。
1
2
3
4
|
[root@node3 ~]# mongo 192.168.60.60:27019
MongoDB shell version: 2.6.0
connecting to: 192.168.60.60:27019/test
ywnds:ARBITER>
|
有興趣能夠經過show log rs命令查看複製集的日誌信息,看看這個過程是怎麼進行的。這就是MongoDB三節點(一主一從一投票或一主二從)複製集的故障轉移功能,是否是很強大。固然除了複製集內部自動選舉以外,咱們也能夠進行人工干預,使用rs.stepdown()方法能夠手動切換。