多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > MongoDB: 7. Replication (1)

MongoDB: 7. Replication (1)

來源:程序員人生   發布時間:2013-12-29 22:20:53 閱讀次數:2751次

最新的 1.6 版總算提供了 Replica Sets,比起有點莫名其妙的 Replica Pairs,這才是高可用集群所需要的。

1. Replica Sets

Replica Sets 使用 n 個 Mongod 節點,構建具備自動容錯轉移(auto-failover)、自動恢復(auto-recovery) 的高可用方案。通常使用 3 個 mongod 實例,或者 2 mongod + 1 arbiter 方案。

(1) 首先啟動所需的 Mongod 節點。注意使用 replSet 參數指定 Sets Name。

$ sudo mkdir -p /var/mongodb/0
$ sudo mkdir -p /var/mongodb/1
$ sudo mkdir -p /var/mongodb/2

$ sudo ./mongod --fork --logpath /dev/null --dbpath /var/mongodb/0 --port 27017 --replSet myset
forked process: 1166
all output going to: /dev/null

$ sudo ./mongod --fork --logpath /dev/null --dbpath /var/mongodb/1 --port 27018 --replSet myset
forked process: 1173
all output going to: /dev/null

$ sudo ./mongod --fork --logpath /dev/null --dbpath /var/mongodb/2 --port 27019 --replSet myset
forked process: 1180
all output going to: /dev/null
(2) 使用 mongo 配置 Replica Sets。

$ ./mongo

MongoDB shell version: 1.6.1
connecting to: test

> cfg = { _id: "myset", members: [
... { _id:0, host:"localhost:27017" },
... { _id:1, host:"localhost:27018" },
... { _id:2, host:"localhost:27019" }
... ]}

> rs.initiate(cfg)
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}

> rs.conf()
{
"_id" : "myset",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "localhost:27017"
},
{
"_id" : 1,
"host" : "localhost:27018"
},
{
"_id" : 2,
"host" : "localhost:27019"
}
]
}
如此 Replica Sets 就算配置成功。

相關配置數據保存在 local 數據庫中。

> show dbs
admin
local

> use local
switched to db local

> show collections
oplog.rs
slaves
system.indexes
system.replset

> db.system.replset.find()
{ "_id" : "myset", "version" : 1, "members" : [
{
"_id" : 0,
"host" : "localhost:27017"
},
{
"_id" : 1,
"host" : "localhost:27018"
},
{
"_id" : 2,
"host" : "localhost:27019"
}
] }
oplog.rs 是一個固定長度的 capped collection,用于記錄 Replica Sets 操作日志。

(3) 可以用 isMaster 和 status 命令查看 Replica Sets 狀態。

> rs.isMaster()
{
"ismaster" : true,
"secondary" : false,
"hosts" : [
"localhost:27017",
"localhost:27019",
"localhost:27018"
],
"ok" : 1
}

> rs.status()
{
"set" : "myset",
"date" : "Sat Aug 21 2010 15:21:13 GMT+0800 (CST)",
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "yuhen-server64:27017",
"health" : 1,
"state" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "localhost:27018",
"health" : 1,
"state" : 2,
"uptime" : 280,
"lastHeartbeat" : "Sat Aug 21 2010 15:21:11 GMT+0800 (CST)"
},
{
"_id" : 2,
"name" : "localhost:27019",
"health" : 1,
"state" : 2,
"uptime" : 284,
"lastHeartbeat" : "Sat Aug 21 2010 15:21:11 GMT+0800 (CST)"
}
],
"ok" : 1
}
在同一時刻,每組 Replica Sets 只有一個 Primary,用于接受寫操作。而后會異步復制到其他成員數據庫中。一旦 primary 死掉,會自動投票選出接任的 primary 來,原服務器恢復后成為普通成員。如果數據尚未從先前的 primary 復制到成員服務器,有可能會丟失數據。

(4) 為了觀察數據復制和容錯遷移,我們可以開幾個終端,在前臺運行 mongod。

$ sudo ./mongod --port 27017 --dbpath /var/mongodb/0 --replSet myset
在 mongo 中向 primary (27017) 插入數據。

> use test
switched to db test

> db.users.insert({name:"user1"})
會在所有 mongod 輸出記錄中看到相關信息。

# 27017 #
Sat Aug 21 15:35:50 [conn2] building new index on { _id: 1 } for test.users
Sat Aug 21 15:35:50 [conn2] Buildindex test.users idxNo:0 { name: "_id_", ns: "test.users", key: { _id: 1 } }
Sat Aug 21 15:35:50 [conn2] done for 0 records 0.01secs
Sat Aug 21 15:35:50 [conn12] getmore local.oplog.rs cid:4961370576520295111 getMore: { ts: { $gte: new Date(5507762976880328705) } } bytes:118 nreturned:1 3782ms
Sat Aug 21 15:35:50 [conn2] insert test.users 1029ms

# 27018 #
Sat Aug 21 15:35:51 [rs_sync] building new index on { _id: 1 } for test.users
Sat Aug 21 15:35:51 [rs_sync] Buildindex test.users idxNo:0 { name: "_id_", ns: "test.users", key: { _id: 1 } }

# 27019 #
Sat Aug 21 15:35:51 [rs_sync] building new index on { _id: 1 } for test.users
Sat Aug 21 15:35:51 [rs_sync] Buildindex test.users idxNo:0 { name: "_id_", ns: "test.users", key: { _id: 1 } }
我們用 CTRL + C 關掉 primary mongd。

# 27018 #
Sat Aug 21 15:40:16 [ReplSetHealthPollTask] replSet info localhost:27017 is now down (or slow to respond)
Sat Aug 21 15:40:27 [rs_sync] replSet SECONDARY

# 27019 #
Sat Aug 21 15:40:16 [ReplSetHealthPollTask] replSet info localhost:27017 is now down (or slow to respond)
Sat Aug 21 15:40:16 [rs_sync] replSet syncThread: 10278 dbclient error communicating with server
Sat Aug 21 15:40:16 [rs Manager] replSet info electSelf 2
Sat Aug 21 15:40:16 [rs Manager] replSet PRIMARY
Mongod 27019 被選為 Primary。

因為 27107 的 socket 關閉,所以 mongo 需要重新連接。

$ ./mongo localhost:27019

MongoDB shell version: 1.6.1
connecting to: localhost:27018/test

> rs.status()
{
"set" : "myset",
"date" : "Sat Aug 21 2010 15:41:40 GMT+0800 (CST)",
"myState" : 2,
"members" : [
{
"_id" : 0,
"name" : "localhost:27017",
"health" : 0,
"state" : 1,
"uptime" : 0,
"lastHeartbeat" : "Sat Aug 21 2010 15:40:14 GMT+0800 (CST)",
"errmsg" : "connect/transport error"
},
{
"_id" : 1,
"name" : "yuhen-server64:27018",
"health" : 1,
"state" : 2,
"self" : true
},
{
"_id" : 2,
"name" : "localhost:27019",
"health" : 1,
"state" : 1,
"uptime" : 486,
"lastHeartbeat" : "Sat Aug 21 2010 15:41:38 GMT+0800 (CST)"
}
],
"ok" : 1
}
查詢先前插入的記錄正常。

> db.users.find()
{ "_id" : ObjectId("4c6f81d58e4719f03d5ccc65"), "name" : "user1" }
我們也可以將 mongo 連接到 27018,不過無法查詢數據。

重新啟動 27017。

# 27017 #
Sat Aug 21 15:44:54 [rs Manager] replSet can't see a majority, will not try to elect self
Sat Aug 21 15:44:56 [ReplSetHealthPollTask] replSet info localhost:27019 is now up
Sat Aug 21 15:44:56 [ReplSetHealthPollTask] replSet info localhost:27018 is now up
Sat Aug 21 15:44:56 [rs_sync] building new index on { _id: 1 } for local.me
Sat Aug 21 15:44:56 [rs_sync] Buildindex local.me idxNo:0 { name: "_id_", ns: "local.me", key: { _id: 1 } }
Sat Aug 21 15:44:56 [rs_sync] done for 0 records 0.002secs
Sat Aug 21 15:44:56 [rs_sync] replSet SECONDARY

# 27018 #
Sat Aug 21 15:44:55 [ReplSetHealthPollTask] replSet info localhost:27017 is now up

# 27019 #
Sat Aug 21 15:44:54 [ReplSetHealthPollTask] replSet info localhost:27017 is now up
rs.status 中 heartbeat 恢復正常,但不再是 Primary。

> rs.status()
{
"set" : "myset",
"date" : "Sat Aug 21 2010 15:46:44 GMT+0800 (CST)",
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "localhost:27017",
"health" : 1,
"state" : 2,
"uptime" : 110,
"lastHeartbeat" : "Sat Aug 21 2010 15:46:44 GMT+0800 (CST)"
},
{
"_id" : 1,
"name" : "localhost:27018",
"health" : 1,
"state" : 2,
"uptime" : 790,
"lastHeartbeat" : "Sat Aug 21 2010 15:46:44 GMT+0800 (CST)"
},
{
"_id" : 2,
"name" : "yuhen-server64:27019",
"health" : 1,
"state" : 1,
"self" : true
}
],
"ok" : 1
}
(5) 我們還可以在運行時添加成員。

$ sudo ./mongod --fork --port 27020 --dbpath /var/mongodb/3 --logpath /dev/null --replSet myset
forked process: 2139
all output going to: /dev/null
注意: 必須連接到 primary 才能添加成員。

$ ./mongo localhost:27019
MongoDB shell version: 1.6.1
connecting to: localhost:27020/test

> rs.add("localhost:27029")
{ "ok" : 1 }

> rs.conf()
{
"_id" : "myset",
"version" : 2,
"members" : [
{
"_id" : 0,
"host" : "localhost:27017"
},
{
"_id" : 1,
"host" : "localhost:27018"
},
{
"_id" : 2,
"host" : "localhost:27019"
},
{
"_id" : 3,
"host" : "localhost:27020"
}
]
}
查看狀態。

> rs.status()
{
"set" : "myset",
"date" : "Sat Aug 21 2010 15:52:54 GMT+0800 (CST)",
"myState" : 2,
"members" : [
{
"_id" : 0,
"name" : "localhost:27017",
"health" : 1,
"state" : 2,
"uptime" : 94,
"lastHeartbeat" : "Sat Aug 21 2010 15:52:54 GMT+0800 (CST)"
},
{
"_id" : 1,
"name" : "localhost:27018",
"health" : 1,
"state" : 1,
"uptime" : 94,
"lastHeartbeat" : "Sat Aug 21 2010 15:52:54 GMT+0800 (CST)"
},
{
"_id" : 2,
"name" : "yuhen-server64:27019",
"health" : 1,
"state" : 2,
"self" : true
},
{
"_id" : 3,
"name" : "localhost:27020",
"health" : 1,
"state" : 2,
"uptime" : 92,
"lastHeartbeat" : "Sat Aug 21 2010 15:52:54 GMT+0800 (CST)"
}
],
"ok" : 1
}
(6) 從客戶端連接 Replica Sets,需要 drivers 支持。

$ ipython

Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
IPython 0.10 -- An enhanced Interactive Python.

In [1]: import pymongo

In [2]: conn = pymongo.Connection(host = ["localhost:27017", "localhost:27018", "localhost:27019", "localhost:27020"])

In [3]: db = conn.test

In [4]: for u in db.users.find(): print u
...:
{u'_id': ObjectId('4c6f81d58e4719f03d5ccc65'), u'name': u'user1'}
{u'_id': ObjectId('4c6f82ad8e4719f03d5ccc66'), u'name': u'user2'}

In [5]: db.users.insert({"name":"user3"})
Out[5]: ObjectId('4c6f8872499b1408b7000000')
從其他終端關掉 primary,看看效果。

In [6]: db.users.count()
---------------------------------------------------------------------------
AutoReconnect Traceback (most recent call last)

AutoReconnect: connection closed
由于連接被中斷,引發異常也很正常,不過 pymongo 會自動重新連接,再次操作時一切正常。

In [7]: db.users.count()
Out[7]: 3

In [8]: for u in db.users.find(): print u
...:
{u'_id': ObjectId('4c6f81d58e4719f03d5ccc65'), u'name': u'user1'}
{u'_id': ObjectId('4c6f82ad8e4719f03d5ccc66'), u'name': u'user2'}
{u'_id': ObjectId('4c6f8872499b1408b7000000'), u'name': u'user3'}

因此編碼時切記需要做異常保護。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 90性后网| 乌克兰性欧美精品高清bd | 国产香蕉一区二区在线观看 | 国产叼嘿视频 | 国产一二三区精品 | 成人在色线视频在线观看免费大全 | 欧美性色网 | 日韩在线不卡一区在线观看 | 欧美亚洲免费久久久 | 伊人俺去久久涩五月综合 | 日本中文字幕第一页 | 国产一区二区亚洲精品天堂 | 欧美亚洲国产精品久久蜜芽 | 日本免费xxxx色视频 | 欧美日韩性生活 | 日韩a视频| 国产免费叼嘿视频 | freesexvideos性21| 午夜视频网站 | 久久影视免费观看网址 | 亚洲欧美日韩综合在线一区二区三区 | 亚洲精品久久久久网站 | 国产成人欧美 | 国产欧美精品区一区二区三区 | 亚洲一区二区三区91 | 亚洲欧美一区二区视频 | 日韩精品免费一级视频 | 自拍偷拍第 | jiizzyou欧美18 | 老司机成人在线视频 | 大片刺激免费播放视频 | 亚洲欧美一区二区久久 | 中文字幕日韩一区 | 国产视频综合 | 九九精品成人免费国产片 | 另类欧美日韩 | 亚洲系列动漫卡通 | 一本久久精品一区二区 | 国产成人系列 | 国产精品2| 欧洲一区二区 |