mongodb不推薦主從複制,推薦建立副本集(Replica Set)來保證1個服務挂了,可以有其他服務頂上,程式正常運作,幾個服務的資料都是一樣的,背景自動同步
【要搭建一個穩定的mongodb工程,副本集是必須的,因為他可以當你的主伺服器挂掉後,根據選舉機制自動選舉出1個最适合的從伺服器來做主伺服器繼續運作】
參考http://snoopyxdy.blog.163.com/blog/static/60117440201241694254441/
Replica Set使用的是n個mongod節點,建構具備自動的容錯功能(auto-failover),自動恢複的(auto-recovery)的高可用方案。
使用Replica Set來實作讀寫分離。通過在連接配接時指定或者在主庫指定slaveOk,由Secondary來分擔讀的壓力,Primary隻承擔寫操作。
對于Replica Set中的secondary 節點預設是不可讀的。
--------------------------------------------------------
建立4個,3個MONGODB伺服器,1個仲裁伺服器
步驟1【建立資料存放目錄】
分别建立4個節點配置設定資料存放的位置空間
$ mkdir -p /scmgt/data/r0
$ mkdir -p /scmgt/data/r1
$ mkdir -p /scmgt/data/r2
$ mkdir -p /scmgt/data/r3
步驟2【開啟3個mondodb服務】
背景開啟3個服務,檢視端口是否暫用指令netstat -apn|grep 1000
/scmgt/mongodb/mongodb/bin/mongod --replSet gtSet --dbpath=/scmgt/data/r0 --logpath=/scmgt/mongodb/ro_log --logappend --port=9933 --fork
/scmgt/mongodb/mongodb/bin/mongod --replSet gtSet --rest --dbpath=/scmgt/data/r1 --logpath=/scmgt/mongodb/r1_log --logappend --port=9934 --fork
/scmgt/mongodb/mongodb/bin/mongod --replSet gtSet --dbpath=/scmgt/data/r2 --logpath=/scmgt/mongodb/r2_log --logappend --port=9935 --fork
/scmgt/mongodb/mongodb/bin/mongod --replSet gtSet --dbpath=/scmgt/data/r3 --logpath=/scmgt/mongodb/r3_log --logappend --port=9936 --fork
【-replSet gtSet:表示副本集的名字為“wzh”,這裡的名字可以任意取;】
【--rest:是打開web監控頁面,比如我們這裡監聽10001端口,則打開http://10.1.49.225:9934/就可以看到這個mongodb資料庫程序的資訊】
【啟動不起來,如果出現 child process failed, exited with error number 100報錯,請删除data下面的mongod.lock】
【檢視logpath日志,提示replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG),這是因為我們還沒有初始化這個set.沒有執行第三步】
步驟3【初始化SET】
登陸mongodb背景:
cd /scmgt/mongodb/mongodb/bin
./mongo --port 9933
把下面config寫入控制台
config = {_id: 'gtSet', members: [
{_id: 0, host: 'localhost:9933'},
{_id: 1, host: 'localhost:9934'},
{_id: 2, host: 'localhost:9935'},
{_id: 3, host: 'localhost:9936',arbiterOnly:true}]
}
然後執行rs.initiate(config);
【arbiterOnly(false):如果是true,則表示這個成員為仲裁節點,不接收資料;】
【priority(1.0):權重,更高的權重會被選舉為主節點】
檢視日志,如果出現
rs.initiate(config); rs.initiate(config);
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}表示将在1分鐘後初始化完畢
之後執行 rs.status(),檢視詳細
【這裡有個值"myState",如果這個值為1,說明是主要節點(master);如果是 2 ,說明是從屬節點(slave).】
----------------------搭建完畢,添加資料,來需要驗證的--------------------
1:主從伺服器資料是否同步,從伺服器沒有讀寫權限
a:向主伺服器寫入資料 ok 背景自動同步到從伺服器,從伺服器有資料
b:向從伺服器寫入資料 false 從伺服器不能寫
c:主伺服器讀取資料 ok
d:從伺服器讀取資料 false 從伺服器不能讀
2:關閉主伺服器,從伺服器是否能頂替
kill -2 9933的pid
mongo的指令行執行rs.status() 發現PRIMARY替換了主機了
3:關閉的伺服器,再恢複,以及主從切換
a:直接啟動關閉的服務,rs.status()中會發現,原來挂掉的主伺服器重新開機後變成從伺服器了
b:額外删除新的伺服器 rs.remove("localhost:9933"); rs.status()
c:額外增加新的伺服器 rs.add({_id:0,host:"localhost:9933",priority:1});
d:讓新增的成為主伺服器 rs.stepDown(),注意之前的 priority投票
4:從伺服器讀寫
db.getMongo().setSlaveOk();
db.getMongo().slaveOk();//從庫隻讀,沒有寫權限,這個方法java裡面不推薦了
db.setReadPreference(ReadPreference.secondaryPreferred());//在複制集中優先讀secondary,如果secondary通路不了的時候就從master中讀
db.setReadPreference(ReadPreference.secondary());//隻從secondary中讀,如果secondary通路不了的時候就不能進行查詢
-------------------------------------------------------------------
日志檢視
MongoDB的Replica Set 架構是通過一個日志來存儲寫操作的,這個日志就叫做”oplog”,它存在于”local”資料庫中,oplog的大小是可以通過mongod的參數”—oplogSize”來改變oplog的日志大小。
use local
switched to db local
db.oplog.rs.find()
{ "ts" : { "t" : 1342511269000, "i" : 1 }, "h" : NumberLong(0), "op" : "n", "ns" : "", "o" : { "msg" : "initiating set" } }
字段說明:
ts: 某個操作的時間戳
op: 操作類型,如下:
i: insert
d: delete
u: update
ns: 命名空間,也就是操作的collection name
o: document的内容