您好,登錄后才能下訂單哦!
Mongodb支持在多個機器中通過異步復制達到故障轉移和實現冗余,多機器之間同一時刻只有一臺是用于寫操作,正是由于這個特性,為mongodb提供了數據一致性的保證,擔當primary角色的機器能把讀操作分發給slave
Mongodb高可用分兩種:
Master-slave 主從復制
只需要在某一個服務啟動時加上--master參數,而另外一個服務加上-slave與-source參數,即可實現同步,mongodb的最新版本已經不在支持此方案了
Replica sets 復制集:
Mongodb是從1.6版本開發了新功能replica sets,這個比master-slave功能更加強大一些,增加了故障自動切換和自動修復成員節點,各個DB之間的數據完全一致,大大降低了維護成本。Auto shared已經明確說明不在支持replication paris,建議使用replica set,replica set故障切換完全自動化
假設一個三節點的mongodb集群
三個節點server-1、-2、-3無論哪一個節點出現故障,其他節點馬上會將業務接轉過來而無需停機操作
主要學習replica set 復制集
replica set可以實現自動的failover和自動的recovery。
replica set由兩個或者更多的節點組成,實現彼此的復制。
replica set自動選擇primary節點,沒有一個節點是固定的primary。
mongos會自動發現一個replica set的primary節點發生變化,并將寫操作發送給這個新的primary節點。
通常用于下面幾個場景
數據冗余。
自動failover,提供高可用性的服務。
分散讀的負載。
簡化維護(相對于master-slave來說)。
災難恢復。
首先還是啟動mongod,用于replica set的參數有兩個:
--replSet <setname>,復制集的名稱。
--oplogSize <MB>,操作日志的大小,單位為MB。(一般是磁盤空間的5%);
Mongodb的版本:
[root@anenjoy mongodb]# /usr/local/mongodb/bin/mongo -version
MongoDB shell version: 2.4.8
實驗中三臺虛擬機的IP:
192.168.1.247
192.168.1.248
192.168.1.250
先在各個server主機上搭建mongodb的安裝,配置存儲路徑
安裝就是解壓包,不再細述
第三步:啟動mongodb
命令參數:
SERVER -1
/usr/local/mongodb/bin/mongod --port 27017 --replSet res1 --keyFile /data/mon_db/key/res1 --oplogSize 100 --dbpath=/data/mon_db/res1/ --logpath=/usr/local/mongodb/log/mongodb.log --logappend --fork
參數詳解:--port 是端口號
--replSet 是replica set的標識參數,后跟set名稱
--keyFile 就是標識進群的私鑰文件
--oplogSize replica操作的日志,是可以crapped collection,可循環使用的,大小100MB
--dbpath 數據文件的存儲路徑
--logpath 日志文件路徑 --logappend是日志追加
--fork 后臺運行程序
SERVER -2
/usr/local/mongodb/bin/mongod --port 27018 --replSet res1 --keyFile /data/mon_db/key/res2 --oplogSize 100 --dbpath=/data/mon_db/res2/ --logpath=/usr/local/mongodb/log/mongodb.log --logappend --fork
SERVER -3
/usr/local/mongodb/bin/mongod --port 27019 --replSet res1 --keyFile /data/mon_db/key/res3 --oplogSize 100 --dbpath=/data/mon_db/res3/ --logpath=/usr/local/mongodb/log/mongodb.log --logappend --fork
各自啟動,注意實時觀察log文件的變化,看是否有問題產生(tail mongodb.log -f)
如果遇到error信息:
[rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)
表示你還沒有執行初始化,這個暫時不用考慮
第四步:初始化
登錄任意一臺server的mongodb數據庫
[root@test02 bin]# /usr/local/mongodb/bin/mongo --port 27017
MongoDB shell version: 2.4.8
connecting to: 127.0.0.1:27017/test
>
配置初始化文件
config_res1={_id:'res1',members:[
{_id:0,host:'192.168.1.248:27017',priority:2},
{_id:1,host:'192.168.1.247:27018',priority:0}
{_id:2,host:'192.168.1.250:27019',priority:1}]
}
"_id" : "res1",
"members" : [
{
"_id" : 0,
"host" : "192.168.1.248:27017",
"priority" : 2
},
{
"_id" : 1,
"host" : "192.168.1.247:27018",
"priority" : 0
},
{
"_id" : 2,
"host" : "192.168.1.250:27019",
"priority" : 1
}
]
}
Priority 優先級,值越大,表示是primary,當primary宕機時,就會使用priority 值次之的當primary 角色
> rs.initiate(config_res1);
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
_id:’res1’這個_id:的值必須是你set集合的名稱,就是--replSet的集合名稱,否則就是提示你
Error message 信息
"errmsg" : "couldn't initiate : set name does not match the set name host 192.168.1.247:27018 expects"
之后查看狀態
rs.status();
{
"set" : "res1", ###set 集名稱
"date" : ISODate("2013-12-04T00:37:08Z"), 創建日期
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.1.248:27017",
"health" : 1, 1表示正常訪問,0異常
"state" : 1, 1表示是primary ,2表示secondary
"stateStr" : "PRIMARY", primary 主庫
"uptime" : 1632,
"optime" : Timestamp(1386116964, 1),
"optimeDate" : ISODate("2013-12-04T00:29:24Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.1.247:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 461,
"optime" : Timestamp(1386116964, 1),
"optimeDate" : ISODate("2013-12-04T00:29:24Z"),
"lastHeartbeat" : ISODate("2013-12-04T00:37:07Z"),
"lastHeartbeatRecv" : ISODate("2013-12-04T00:37:07Z"),
"pingMs" : 0,
"syncingTo" : "192.168.1.248:27017"
},
{
"_id" : 2,
"name" : "192.168.1.250:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 461,
"optime" : Timestamp(1386116964, 1),
"optimeDate" : ISODate("2013-12-04T00:29:24Z"),
"lastHeartbeat" : ISODate("2013-12-04T00:37:08Z"),
"lastHeartbeatRecv" : ISODate("2013-12-04T00:37:08Z"),
"pingMs" : 1,
"syncingTo" : "192.168.1.248:27017"
}
],
"ok" : 1
}
同步好信息之后,查看另外兩個mongodb的日志,就會發現
Fri Dec 6 15:48:48.380 [conn33] end connection 192.168.1.247:25633 (1 connection now open)
Fri Dec 6 15:48:48.381 [initandlisten] connection accepted from 192.168.1.247:25635 #35 (2 connections now open)
Fri Dec 6 15:48:48.383 [conn35] authenticate db: local { authenticate: 1, nonce: "6d6fb8a5d540c164", user: "__system", key: "51b0f27144ec17860f1ca2bd245807ce" }
表示正常的
也可以使用
res1:PRIMARY> rs.isMaster();查看replica set的信息
{
"setName" : "res1",
"ismaster" : true,
"secondary" : false,
"hosts" : [
"192.168.1.248:27017",
"192.168.1.250:27019"
],
"passives" : [
"192.168.1.247:27018"
],
"primary" : "192.168.1.248:27017",
"me" : "192.168.1.248:27017",
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"localTime" : ISODate("2013-12-04T00:42:57.347Z"),
"ok" : 1
Replica set的配置文件,也可以用來更改、增加節點信息
res1:PRIMARY> rs.conf();
{
"_id" : "res1",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "192.168.1.248:27017",
"priority" : 2
},
{
"_id" : 1,
"host" : "192.168.1.247:27018",
"priority" : 0
},
{
"_id" : 2,
"host" : "192.168.1.250:27019"
}
]
}
以上步驟,就是replica set的一個搭建的過程,接下來就是操作和驗證
五:主從操作的oplog日志
Mongodb的replica set架構是通過一個日志來存儲寫操作的,這個日志就是‘oplog’。Oplog是一個固定長度的capped collection,它存放于local數據庫下,用于記錄replica sets的操作記錄。Oplog的日志大小是可以調整的,就在我們啟動的時候使用--oplogSize 參數指定的,單位是MB
res1:PRIMARY> show dbs;
admin (empty)
local 0.203125GB (有oplog的collection,是有數據的)
先在primary上創建庫,secondary是無法讀寫操作的(等下可以解決讀的問題)
Use test1
db.appstore.save({'e_name':'frank','e_id':1101,'class_id':1});
db.appstore.find();
{ "_id" : ObjectId("529e7c88d4d317e4bd3eece9"), "e_name" : "frank", "e_id" : 1101, "class_id" : 1 }
之后,你會看到另外兩臺mongodb的log日志的變化,有追加:
Fri Dec 6 15:56:22.338 [FileAllocator] allocating new datafile /data/mon_db/res2/test1.ns, filling with zeroes...
Fri Dec 6 15:56:22.474 [FileAllocator] done allocating datafile /data/mon_db/res2/test1.ns, size: 16MB, took 0.136 secs
Fri Dec 6 15:56:22.474 [FileAllocator] allocating new datafile /data/mon_db/res2/test1.0, filling with zeroes...
Fri Dec 6 15:56:23.850 [FileAllocator] done allocating datafile /data/mon_db/res2/test1.0, size: 64MB, took 1.376 secs
Fri Dec 6 15:56:23.852 [repl writer worker 1] build index test1.appstore { _id: 1 }
Fri Dec 6 15:56:23.852 [FileAllocator] allocating new datafile /data/mon_db/res2/test1.1, filling with zeroes...
Fri Dec 6 15:56:23.853 [repl writer worker 1] build index done. scanned 0 total records. 0 secs
Fri Dec 6 15:56:27.006 [FileAllocator] done allocating datafile /data/mon_db/res2/test1.1, size: 128MB, took 3.153 secs
Fri Dec 6 15:56:27.007 [rsSyncNotifier] repl: old cursor isDead, will initiate a new one
如果想在secondary上查看數據,默認情況下:
[root@test04 ~]# /usr/local/mongodb/bin/mongo --port 27018
MongoDB shell version: 2.4.8
connecting to: 127.0.0.1:27018/test
res1:SECONDARY> show dbs;show dbs;
admin (empty)
local 0.203125GB
test1 0.203125GB
Ok,可以看到我們剛創建的test1庫,
res1:SECONDARY> use test1;
switched to db test1
res1:SECONDARY> show collections;
Fri Dec 6 15:59:10.758 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:128
OK,提示error
解決辦法:
res1:SECONDARY> db.getMongo().setSlaveOk(); (自帶的函數)
res1:SECONDARY> show collections;show collections;
appstore
System.indexes
res1:SECONDARY> db.appstore.find();db.appstore.find();
{ "_id" : ObjectId("529e7c88d4d317e4bd3eece9"), "e_name" : "frank", "e_id" : 1101, "class_id" : 1 }
如果說你想寫數據,就會提示 not master
db.appstore.insert({'e_name':1102,'e_id':1102});
not master
OK.這樣就可以實現讀寫的分離
怎樣查看oplog的日志
use local;
show collections;
oplog.rs
slaves
startup_log
system.indexes
System.replset
就是查看oplog.rs collection
res1:PRIMARY> db.oplog.rs.find();
{ "ts" : Timestamp(1386116964, 1), "h" : NumberLong(0), "v" : 2, "op" : "n", "ns" : "", "o" : { "msg" : "initiating set" } }
{ "ts" : Timestamp(1386118280, 1), "h" : NumberLong("8972935208244346897"), "v" : 2, "op" : "i", "ns" : "test1.appstore", "o" : { "_id" : ObjectId("529e7c88d4d317e4bd3eece9"), "e_name" : "frank", "e_id" : 1101, "class_id" : 1 } }
相關解釋:
Ts 表示某個操作的時間戳
Op:表示操作類型,一般包括
I insert 插入
D delete 刪除
Uupdate 更新
Ns 命名空間,也就是你操作的collection name名
O document(文檔),就是你插入的數據信息
查看Mster上的oplog元數據信息:
res1:PRIMARY> db.printReplicationInfo();
configured oplog size: 100MB
log length start to end: 1316secs (0.37hrs)
oplog first event time: Wed Dec 04 2013 08:29:24 GMT+0800 (CST)
oplog last event time: Wed Dec 04 2013 08:51:20 GMT+0800 (CST)
now: Wed Dec 04 2013 09:14:20 GMT+0800 (CST)
Oplog size 是你oplog 的總大小,是可循環的
log length start to end oplog日志的啟用時間段,單位 秒
oplog first event time 第一個事務產生的時間
oplog last event time 最后一個事務產生的時間
Now現在的時間
查看slave的數據同步狀態
res1:PRIMARY> db.printSlaveReplicationInfo();
source: 192.168.1.247:27018
syncedTo: Wed Dec 04 2013 08:51:20 GMT+0800 (CST)
= 1620 secs ago (0.45hrs)
source: 192.168.1.250:27019
syncedTo: Wed Dec 04 2013 08:51:20 GMT+0800 (CST)
= 1620 secs ago (0.45hrs)
Source:slave的IP和端口信息
SyncedTo:目前的同步情況,延遲了多久等信息
在local數據庫內,不僅有oplog的集合,還有一個集合是記錄set 配置信息
db.system.replset.find();
或者是 rs.conf() 都可以查看到
以上步驟是replica set的搭建過程和相關的查看語句,如有不足之處,還請指點
replica set 節點的增、刪、改和故障切換參考:http://1413570.blog.51cto.com/1403570/1337622
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。