綠岸網絡MongoDB
---何旭東
目錄
綠岸網絡MongoDB. 1
場景介紹... 1
機器功能:... 2
主機名... 2
邏輯圖... 3
primary secondary. 4
模型選擇... 4
啟動... 5
第一台... 5
第二台... 5
第三台... 5
配置... 5
第二台... 6
第三台... 7
啟動路由... 8
分片... 8
添加分片... 9
配置結果... 9
檢視目前主庫... 11
調整從庫可讀... 12
模拟故障... 13
主機點當機... 13
從節點自動提升主節點... 13
主機點恢複... 14
問題... 15
臨時調整,不生效... 15
程式實作可讀... 17
場景介紹
MongoDB 3.0其實是2.8,上個版本是2.6.2.8有極大的增加,用2.8有點委屈,在MongoDB市場部主導命名3.0. 增加了高性能,可伸縮的存儲引擎wiredtiger.性能有了極大的提升,尤其在寫操作對硬體資源的使用率。
mongodb最初版本一直到2.6都隻支援一種基于記憶體映射技術的存儲引擎即mmap。mongodb 3.0實作對支援集合級鎖的存儲引擎mmap和支援壓縮和文檔級鎖的存儲引擎wiredtiger的支援。
MongoDB官方同步釋出了一份YCSB測試報告。
且官方下載下傳資源,确實了沒有2.8。以下為官方下載下傳位址
https://www.mongodb.org/downloads?_ga=1.220177757.596614690.1431100647#development
機器功能:
機器 | 角色名稱 | 端口 | 功能 |
mongod01 | 28017 | 'shard1' PRIMARY | |
mongoc01 | 20000 | 配置節點 | |
mongos01 | 28885 | 路由節點 | |
41000 | 啟動路由 生成此端口 | ||
mongod02 | 'shard1' SECONDARY | ||
mongoc02 | |||
mongos02 | |||
mongod03 | 'shard1' arbiter | ||
mongoc03 |
Shardingoptions:
--configdb arg 1 or 3 comma separated config servers
路由節點隻能配置1 或者 3 個!
主機名
192.168.200.87 mongohost1
192.168.200.90 mongohost2
192.168.200.88 mongohost3
192.168.200.87 mongo01
192.168.200.87 mongodb01
192.168.200.87 mongos01
192.168.200.90 mongo02
192.168.200.90 mongodb02
192.168.200.90 mongos02
192.168.200.88 mongo03
192.168.200.88 mongodb03
邏輯圖
primary secondary
模型選擇
CAP定理(Consistency ,Availability和Partition Tolerance)
–Consistency(一緻性):資料一緻更新,所有資料變動都是同步的
–Availability(可用性):好的響應性能
–PartitionTolerance(分區容錯性):資料可靠性
–分布式系統三選二
官方CP模型
CP
–ReplicaSet,設定寫入節點數w=ReplicaSet資料節點數,查詢開啟SlaveOk
AP
–ReplicaSet,預設設定w=1,查詢開啟slaveOk
CA
–ReplicaSet,預設設定w=1,查詢不開啟slaveOk
啟動
第一台
mongod -f /etc/shard11.conf
mongod -f /etc/config1.conf
mongos -f /etc/mongos1.conf
第二台
mongod -f /etc/shard12.conf
mongod -f /etc/config2.conf
mongos -f /etc/mongos2.conf
第三台
mongod -f /etc/shard13.conf
mongod -f /etc/config3.conf
配置
mkdir /usr/local/mongodb/shard11/ -p
mkdir /usr/local/mongodb/config/
mkdir /usr/local/mongodb/logs/
cat > /etc/shard11.conf <<EOF
shardsvr=true
port=28017
dbpath = /usr/local/mongodb/shard11/
logpath = /usr/local/mongodb/logs/shard11.log
logappend=true
fork=true
nojournal=true
rest=true
replSet=shard1
oplogSize=2048
EOF
cat > /etc/config1.conf <<EOF
configsvr=true
port=20000
dbpath = /usr/local/mongodb/config/
logpath =/usr/local/mongodb/logs/config1.log
cat > /etc/mongos1.conf <<EOF
configdb=mongodb01:20000,mongodb02:20000,mongodb03:20000
chunkSize=100
port=28885
logpath =/usr/local/mongodb/logs/mongos1.log
mkdir /usr/local/mongodb/shard12/ -p
cat > /etc/shard12.conf <<EOF
dbpath = /usr/local/mongodb/shard12/
logpath =/usr/local/mongodb/logs/shard12.log
logpath =/usr/local/mongodb/logs/config2.log
cat > /etc/mongos2.conf <<EOF
configdb = mongodb01:20000,mongodb02:20000,mongodb03:20000
logpath =/usr/local/mongodb/logs/mongos2.log
mkdir /usr/local/mongodb/shard13/ -p
mkdir /usr/local/mongodb/logs/
cat > /etc/shard13.conf <<EOF
dbpath = /usr/local/mongodb/shard13/
logpath = /usr/local/mongodb/logs/shard13.log
cat > /etc/config3.conf <<EOF
logpath = /usr/local/mongodb/logs/config3.log
啟動路由
參考
mongos --configdbmongohost3:20000,mongohost2:20000,mongohost1:20000 --port 41000 --chunkSize 100--logpath /usr/local/mongodb/logs/mongos.log --logappend --fork
綠岸配置
mongos --configdb mongodb01:20000,mongodb02:20000,mongodb03:20000--port 41000 --chunkSize 100 --logpath /usr/local/mongodb/logs/mongos.log--logappend --fork
分片
以下為參考配置
mongo mongohost1:28017/admin
config = {_id:'shard1', members: [{_id: 0,host: 'mongohost1:28017'},{ "_id" : 1,"host":"mongohost2:28017",},{_id:2, host: 'mongohost3:28017', arbiterOnly : true}]};
rs.initiate(config);
以下為綠岸配置
mongo mongo01:28017/admin
config = {_id:'shard1', members: [{_id: 0,host: 'mongo01:28017'},{ "_id" : 1,"host":" mongo02:28017",},{_id:2, host: ' mongo03:28017', arbiterOnly : true}]};
添加分片
mongo mongohost1:28885/admin
db.runCommand({"addshard" :"shard1/mongohost1:28017,mongohost2:28017"})
mongo mongos01:28885/admin
db.runCommand({"addshard" :"shard1/mongo01:28017,mongo02:28017"})
配置結果
[root@mongohost1 mongodb]# mongomongohost1:28885/admin
MongoDB shell version: 2.6.10
connecting to: mongohost1:28885/admin
mongos> db.printShardingStatus();
--- Sharding Status ---
sharding version: {
"_id" : 1,
"version" : 4,
"minCompatibleVersion" : 4,
"currentVersion" : 5,
"clusterId" : ObjectId("55adedc8c5488912b58e20aa")
}
shards:
{ "_id" :"shard1", "host" :"shard1/mongohost1:28017,mongohost2:28017" }
databases:
{ "_id" :"admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "shard1", "host" : "shard1/mongohost1:28017,mongohost2:28017"}
mongos> rs.status()
{
"info" : "mongos",
"ok" : 0,
"errmsg" : "replSetGetStatus is not supported throughmongos"
mongos> exit
bye
[root@mongohost1 mongodb]# mongomongohost1:28017/admin
connecting to: mongohost1:28017/admin
Server has startup warnings:
2015-07-21T14:57:14.934+0800 ** WARNING:--rest is specified without --httpinterface,
2015-07-21T14:57:14.934+0800 ** enabling http interface
2015-07-21T14:57:14.939+0800[initandlisten]
2015-07-21T14:57:14.939+0800[initandlisten] ** WARNING: Readahead for /usr/local/mongodb/shard11/ is set to4096KB
2015-07-21T14:57:14.939+0800[initandlisten] ** We suggestsetting it to 256KB (512 sectors) or less
2015-07-21T14:57:14.939+0800[initandlisten] ** http://dochub.mongodb.org/core/readahead
shard1:PRIMARY> rs.status();
"set" : "shard1",
"date" : ISODate("2015-07-21T07:13:20Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" :"mongohost1:28017",
"health" : 1,
"state" : 1,
"stateStr" :"PRIMARY",
"uptime" :966,
"optime" :Timestamp(1437462480, 1),
"optimeDate": ISODate("2015-07-21T07:08:00Z"),
"electionTime" : Timestamp(1437462489, 1),
"electionDate" : ISODate("2015-07-21T07:08:09Z"),
"self" : true
},
"_id" : 1,
"name" :"mongohost2:28017",
"health" : 1,
"state" : 2,
"stateStr" :"SECONDARY",
"uptime" :319,
"optime" :Timestamp(1437462480, 1),
"lastHeartbeat" : ISODate("2015-07-21T07:13:19Z"),
"lastHeartbeatRecv" : ISODate("2015-07-21T07:13:18Z"),
"pingMs" : 0,
"syncingTo" :"mongohost1:28017"
"_id" : 2,
"name" :"mongohost3:28017",
"health": 1,
"state" : 7,
"stateStr" :"ARBITER",
"lastHeartbeatRecv": ISODate("2015-07-21T07:13:18Z"),
"pingMs" : 0
}
],
"ok" : 1
shard1:PRIMARY>
檢視目前主庫
shard1:PRIMARY> rs.isMaster();
"setName" : "shard1",
"setVersion" : 1,
"ismaster" : true,
"secondary" : false,
"hosts" : [
"mongohost1:28017",
"mongohost2:28017"
"arbiters" : [
"mongohost3:28017"
"primary" : "mongohost1:28017",
"me" : "mongohost1:28017",
"electionId" : ObjectId("55adefda41c78564aaa0ffd8"),
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2015-07-21T07:21:14.600Z"),
"maxWireVersion" : 2,
"minWireVersion" : 0,
調整從庫可讀
passive ----節點執行以下内容
testSet:PRIMARY> show dbs;
admin (empty)
local 2.077GB
testSet:PRIMARY> use testdb;
switched to db testdb
testSet:PRIMARY>db.document01.insert({"name":"hxd","sex":"N","age":"22"});
WriteResult({ "nInserted" : 1 })
testSet:PRIMARY> show tables;
document01
system.indexes
testSet:PRIMARY> db.document01.find();
{ "_id" :ObjectId("55a71118442e12ca0d28b50a"), "name" :"hxd", "sex" : "N", "age" :"22" }
testSet:PRIMARY>
standard ----節點執行以下内容
testSet:SECONDARY> show dbs;
admin (empty)
local 2.077GB
testdb 0.078GB
testSet:SECONDARY> use testdb
testSet:SECONDARY> show tables;
2015-07-16T10:05:22.978+0800 error: {"$err" : "not master and slaveOk=false", "code" :13435 } at src/mongo/shell/query.js:131
testSet:SECONDARY> rs.slaveOk();
testSet:SECONDARY> db.document01.find();
testSet:SECONDARY>
模拟故障
主機點當機
[root@mongohost1 mongodb]# ps aux | grepshard11.conf
root 2142 0.4 5.6 2888808 56768 ? Sl 14:57 0:07 mongod -f/etc/shard11.conf
root 5191 0.0 0.0 112640 972 pts/0 S+ 15:25 0:00 grep --color=auto shard11.conf
[root@mongohost1 mongodb]# kill -2 2142
從節點自動提升主節點
shard1:SECONDARY> db.document01.find();
{ "_id" :ObjectId("55adf36ae512c815a6569440"), "name" :"hxd", "sex" : "N", "age" :"22" }
shard1:SECONDARY> rs.status()
"date" : ISODate("2015-07-21T07:25:47Z"),
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" :Timestamp(1437463402, 1),
"optimeDate": ISODate("2015-07-21T07:23:22Z"),
"lastHeartbeat" : ISODate("2015-07-21T07:25:47Z"),
"lastHeartbeatRecv" : ISODate("2015-07-21T07:25:39Z"),
"stateStr" : "PRIMARY",
"uptime" :1683,
"electionTime" :Timestamp(1437463543, 1),
"electionDate" : ISODate("2015-07-21T07:25:43Z"),
"uptime" :1063,
"lastHeartbeatRecv" :ISODate("2015-07-21T07:25:46Z"),
主機點恢複
主節點當機狀态:
"stateStr" : "(notreachable/healthy)",
恢複主節點後:
"stateStr" :"SECONDARY",
問題
問題:
降級的SECONDARY 為不可讀模式。需手動調整。
在已更新成為:mongohost2 PRIMARY 節點插入資料。
shard1:PRIMARY> show dbs;
shard1:PRIMARY> use testdb;
shard1:PRIMARY>db.document01.insert({"name":"lazy","sex":"N","age":"52"});
shard1:PRIMARY> show tables;
shard1:PRIMARY> db.document01.find();
{ "_id" : ObjectId("55adf36ae512c815a6569440"),"name" : "hxd", "sex" : "N","age" : "22" }
{ "_id" :ObjectId("55adf6ddc036dfbdc18191cc"), "name" :"lazy", "sex" : "N", "age" :"52" }
shard1:PRIMARY> exit
[root@mongohost2 mongodb]#
在已降級成為:mongohost1 SECONDARY 節點檢視資料
shard1:SECONDARY> rs.slaveOk();
shard1:SECONDARY> exit
[root@mongohost1 mongodb]#
臨時調整,不生效
手動配置slaveOk ,為臨時。exit退出後,将失去讀取權限,問題 求解決。
以下為測試案例:
shard1:SECONDARY> show dbs;
admin (empty)
local 2.077GB
testdb 0.078GB
shard1:SECONDARY> use testdb
switched to db testdb
shard1:SECONDARY> show tables;
2015-07-21T15:52:12.008+0800 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:131
shard1:SECONDARY> db.document01.find();
error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
shard1:SECONDARY> rs.slaveOk();
{ "_id" : ObjectId("55adf36ae512c815a6569440"), "name" : "hxd", "sex" : "N", "age" : "22" }
{ "_id" : ObjectId("55adf6ddc036dfbdc18191cc"), "name" : "lazy", "sex" : "N", "age" : "52" }
shard1:SECONDARY> exit
[root@mongohost1 mongodb]# mongo mongohost1:28017/admin 再次登入
MongoDB shell version: 2.6.10
connecting to: mongohost1:28017/admin
Server has startup warnings:
2015-07-21T15:28:05.172+0800 ** WARNING: --rest is specified without --httpinterface,
2015-07-21T15:28:05.172+0800 ** enabling http interface
2015-07-21T15:28:05.176+0800 [initandlisten]
2015-07-21T15:28:05.176+0800 [initandlisten] ** WARNING: Readahead for /usr/local/mongodb/shard11/ is set to 4096KB
2015-07-21T15:28:05.176+0800 [initandlisten] ** We suggest setting it to 256KB (512 sectors) or less
2015-07-21T15:28:05.176+0800 [initandlisten] ** http://dochub.mongodb.org/core/readahead
shard1:SECONDARY> db.document01.find();
[root@mongohost1 mongodb]#
北京-何旭東 2015/7/21 15:57:15
以上為mongohost1 ,在首次配置中為:PRIMARY狀态。當mongohost1 資料節點當機後。mongohost2 成為PRIMARY 狀态。
現狀: 想對mongohost1 進行讀取操作,沒有配置生效。
我找一下這個問題的答案,大家也可以想一下。
程式實作可讀
就以上截圖,重點說明了。1 當首次查詢 沒有權限,手從操作後,再次查詢,沒有問題。exit退出後
2 退出後,再次登入查詢,發現又沒有了 權限。 請求。
此次說明了。rs.slave0k(); 為臨時生效,退出後 依然沒有查詢權限。
16:08:13
2015/7/21 16:08:13
的确如此:slaveOk隻對當次的連接配接生效。每次連接配接之後都要判斷一次目前是否master,不是就重新設定,的确有些不太合理了。
看看老師有什麼解決方法
16:08:54
老師-孫玄2015/7/21 16:08:54
如果使用driver,在程式裡可以設定永久開啟slaveok
老師-孫玄2015/7/21 16:09:11
如果使用shell用戶端,的确每次都有設定slaveok
老師-孫玄2015/7/21 16:09:19
不然從庫讀不了
37537-廈門-陳 2015/7/21 16:09:54
MongoDB為什麼要這麼設計呀?
2015/7/21 16:09:57
也就是使用driver的話,不管是否連master,都設定一次slaveok?
北京-何旭東 2015/7/21 16:10:04
哦。一會咨詢下,我們的這邊的大神。謝謝老師回答
2015/7/21 16:10:28
這是一種保護機制:防止誤讀取了從庫,以至于讀取到非最新的資料。
實作
PRIMARY 節點 寫入
SECONDARY 節點 讀取
老師-孫 2015/7/21 16:15:51
基于paxos算法
老師-孫 2015/7/21 16:16:25
@北京-何旭東 這點replic set集合支援的
老師-孫 2015/7/21 16:16:30
開啟slaveok就可以
2015/7/21 16:16:49
但之前程式是直接連接配接的單個節點,原本連接配接的這個節點是主庫,重新選舉後其他節點變成了主庫,此節點變成從庫。那程式在沒有調整設定之前,如何從從庫讀取資料呢?
2015/7/21 16:17:06
是以,還是經過mongos是最佳的方案。
老師-孫 2015/7/21 16:17:21
對,直接連接配接資料節點,不行的
16:17:30
2015/7/21 16:17:30
也就是說副本集最好與分片一起,否則,讀寫分離上有些麻煩?
老師-孫 2015/7/21 16:17:31
經過mongos就沒有這個問題了
老師-孫 2015/7/21 16:17:45
不是
老師-孫 2015/7/21 16:18:03
一個replic set 内部是支援讀寫分離的
老師-孫 2015/7/21 16:18:11
和sharding沒有必然關系