1. 程式人生 > >【MongoDB】配置主從模式 複製集搭建 完整教程

【MongoDB】配置主從模式 複製集搭建 完整教程

NoSQL資料庫的最大優勢在於很好的支援了叢集,今天就準備用MongoDB來配置一個主從伺服器。

關於MongoDB的安裝就不介紹了,本人使用的是Mac端的MongoDB,版本3.4.9

MongoDB的主從有兩種模式,一種是早期的master-slave模式,還有就是後續出來的replica-set模式,一般推薦使用replica-set模式,因為該模式如果master節點掛了,其餘的節點會進行選舉,選出下一個primary節點,容錯性大大提升。

下面就開始配置一個replica-set節點集。主要有三個節點:

127.0.0.1:29010,primary

127.0.0.1:29011,secondary

127.0.0.1:29012,secondary

先來構建目錄,我在Mac下的目錄結構:

根目錄為/data/replica-project,根目錄下有三個子目錄,分別為:

log,存放日誌;

data,存放資料;

config,存放啟動配置;

在config目錄下,存放三個節點的配置檔案:

r0.conf:

#資料資料夾
dbpath=/data/replica-project/data/r0

#日誌資料夾,如果以後臺方式執行,必須指定logpath
logpath=/data/replica-project/log/r0.log

#以追加而非覆蓋方式寫入日誌
logappend=true

#埠
port=29010

#以後臺方式執行
fork=true

r1.conf:

#資料資料夾
dbpath=/data/replica-project/data/r1

#日誌資料夾,如果以後臺方式執行,必須指定logpath
logpath=/data/replica-project/log/r1.log

#以追加而非覆蓋方式寫入日誌
logappend=true

#埠
port=29011

#以後臺方式執行
fork=true

r2.conf:

#資料資料夾
dbpath=/data/replica-project/data/r2

#日誌資料夾,如果以後臺方式執行,必須指定logpath
logpath=/data/replica-project/log/r2.log

#以追加而非覆蓋方式寫入日誌
logappend=true

#埠
port=29012

#以後臺方式執行
fork=true

然後分別啟動上述三個節點:

sudo mongod -f /data/replica-project/config/r0.conf --replSet "rs0"
sudo mongod -f /data/replica-project/config/r1.conf --replSet "rs0"
sudo mongod -f /data/replica-project/config/r2.conf --replSet "rs0"
結果如下:



接著我們需要登入想要作為primary節點的機器:

mongo --port 29010


然後配置replica-set:

在剛才登入的shell中定義一個配置物件:

config={_id:"rs0", members:[{_id:0,host:"localhost:29010",priority:1}]}

這裡設定priority為1,那麼這個機器就會被選舉為primary的節點。

呼叫rs的API進行初始化set:

rs.initiate(config)


可以看到,這裡和登入普通的mongod的命令提示符不同,這裡有rs0字首,表明是一個replica-set。但是我們不是設定其為primary了嗎?怎麼是secondary?別急還沒選舉出來。我們可以使用命令

rs.conf()

檢視我們剛才的配置:



這次提示符變為了primary,說明這個節點已經被推舉為了master。master或者priamry節點的特殊性在於,set中至多會有一個primary節點,只有primary節點可以配置set的節點,比如增加和刪除,也只有primary節點用於新增或者更新資料,secondary節點只能讀取資料。

接著我們需要新增其他的節點到這個set中:

rs.add("localhost:29011")
rs.add("localhost:29012")



使用命令檢視當前set叢集的狀態:
rs.status()

結果為:
rs0:PRIMARY> rs.status()
{
	"set" : "rs0",
	"date" : ISODate("2017-10-03T01:18:55.080Z"),
	"myState" : 1,
	"term" : NumberLong(1),
	"heartbeatIntervalMillis" : NumberLong(2000),
	"optimes" : {
		"lastCommittedOpTime" : {
			"ts" : Timestamp(1506993534, 1),
			"t" : NumberLong(1)
		},
		"appliedOpTime" : {
			"ts" : Timestamp(1506993534, 1),
			"t" : NumberLong(1)
		},
		"durableOpTime" : {
			"ts" : Timestamp(1506993534, 1),
			"t" : NumberLong(1)
		}
	},
	"members" : [
		{
			"_id" : 0,
			"name" : "localhost:29010",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 470,
			"optime" : {
				"ts" : Timestamp(1506993534, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2017-10-03T01:18:54Z"),
			"electionTime" : Timestamp(1506993212, 2),
			"electionDate" : ISODate("2017-10-03T01:13:32Z"),
			"configVersion" : 3,
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "localhost:29011",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 43,
			"optime" : {
				"ts" : Timestamp(1506993534, 1),
				"t" : NumberLong(1)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1506993534, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2017-10-03T01:18:54Z"),
			"optimeDurableDate" : ISODate("2017-10-03T01:18:54Z"),
			"lastHeartbeat" : ISODate("2017-10-03T01:18:54.457Z"),
			"lastHeartbeatRecv" : ISODate("2017-10-03T01:18:53.457Z"),
			"pingMs" : NumberLong(0),
			"syncingTo" : "localhost:29010",
			"configVersion" : 3
		},
		{
			"_id" : 2,
			"name" : "localhost:29012",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 38,
			"optime" : {
				"ts" : Timestamp(1506993534, 1),
				"t" : NumberLong(1)
			},
			"optimeDurable" : {
				"ts" : Timestamp(1506993534, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2017-10-03T01:18:54Z"),
			"optimeDurableDate" : ISODate("2017-10-03T01:18:54Z"),
			"lastHeartbeat" : ISODate("2017-10-03T01:18:54.457Z"),
			"lastHeartbeatRecv" : ISODate("2017-10-03T01:18:53.650Z"),
			"pingMs" : NumberLong(0),
			"syncingTo" : "localhost:29010",
			"configVersion" : 3
		}
	],
	"ok" : 1
}
從這裡可以看到配置成功了。

下面我們來驗證一下主從伺服器,在主庫裡面插入一條資料,然後在從庫裡面讀取。

在主庫插入一條資料:

use test
db.test.insert({name:"liyao", age:25})

登入一臺secondary伺服器:

mongo --port 29011

然後嘗試讀取:

use test
db.test.find()
出現瞭如下資訊:


這是因為預設只能對主庫進行操作,如果想從從庫讀取,必須使用下面的命令設定:
db.setSlaveOk()
只有就可以查詢了。

至此,一個簡單的MongoDB主從構架就配置好了。