1、 分區的結構及原理
分區叢集結構分布:
分區叢集主要由三種組件組成:mongos,config server,shard
1) MONGOS
資料庫叢集請求的入口,所有的請求都通過mongos進行協調,不需要在應用程式添加一個路由選取器,mongos自己就是一個請求分發中心,它負責把對應的資料請求請求轉寄到對應的shard伺服器上。在生產環境通常有多個mongos作為請求的入口,防止其中一個掛掉所有的mongodb請求都沒有辦法操作。
2) CONFIG SERVER
顧名思義為設定管理員,儲存所有資料庫元資訊(路由、分區)的配置。mongos本身沒有實體儲存體分區伺服器和資料路由資訊,只是緩衝在記憶體裡,設定管理員則實際儲存這些資料。
mongos第一次啟動或者關掉重啟就會從 config server 載入配置資訊,以後如果設定管理員資訊變化會通知到所有的 mongos 更新自己的狀態,這樣 mongos 就能繼續準確路由。在生產環境通常有多個 config server 設定管理員,因為它儲存了分區路由的中繼資料,這個可不能丟失。就算掛掉其中一台,只要還有存貨, mongodb叢集就不會掛掉。
3) SHARD
這就是傳說中的分區了。
如圖所示,一台機器的一個資料表 Collection1 儲存了 1T 資料,壓力太大了。在分給4個機器後,每個機器都是256G,則分攤了集中在一台機器的壓力。
事實上,上圖4個分區如果沒有複本集(replica set)是個不完整架構,假設其中的一個分區掛掉那四分之一的資料就丟失了,所以在高可用性的分區架構還需要對於每一個分區構建 replica set 複本集保證分區的可靠性。生產環境通常是 2個副本 + 1個仲裁。
2、 搭建分區
假設我們要配置如下圖所示的一個分區叢集
因為沒有足夠的機器,現在都部署於同一台機器上,通過不同連接埠來進行劃分:
|
“機器”一 |
“機器”二 |
“機器”三 |
mongos |
20000 |
20001 |
20002 |
config |
30000 |
30001 |
30002 |
shard |
40000,40001(副本),40002(仲裁) |
41000,41001(副本),42002(仲裁) |
42000,42001(副本),42002(仲裁) |
1) 啟動設定管理員
樣本,啟動3台“機器”的設定管理員:
mongod --configsvr --dbpath config\1\data --port 30000 --logpath config\1\log\config.log
mongod --configsvr --dbpath config\2\data --port 30001 --logpath config\2\log\config.log
mongod --configsvr --dbpath config\3\data --port 30002 --logpath config\3\log\config.log
2) 啟動MONGOS伺服器
樣本,啟動3台“機器”的mongos,jsj-1306-201是在下電腦的機器名:
mongos --configdb jsj-1306-201:30000,jsj-1306-201:30001,jsj-1306-201:30002 --port 20000 --logpath mongos\1\log \mongos.log
mongos --configdb jsj-1306-201:30000,jsj-1306-201:30001,jsj-1306-201:30002 --port 20001 --logpath mongos\2\log \mongos.log
mongos --configdb jsj-1306-201:30000,jsj-1306-201:30001,jsj-1306-201:30002 --port 20002 --logpath mongos\3\log \mongos.log
3) 啟動分區及其複本集執行個體
shard1:
mongod --shardsvr --replSet shard1 --port 40000 --dbpath shard\1\data --logpath shard\1\log\shard.log --nojournal --oplogSize 10
mongod --shardsvr --replSet shard1 --port 40001 --dbpath shard\1_1\data --logpath shard\1_1\log\shard.log -- nojournal --oplogSize 10
mongod --shardsvr --replSet shard1 --port 40002 --dbpath shard\1_2\data --logpath shard\1_2\log\shard.log -- nojournal --oplogSize 10
shard2:
mongod --shardsvr --replSet shard2 --port 41000 --dbpath shard\2\data --logpath shard\2\log\shard.log --nojournal --oplogSize 10
mongod --shardsvr --replSet shard2 --port 41001 --dbpath shard\2_1\data --logpath shard\2_1\log\shard.log -- nojournal --oplogSize 10
mongod --shardsvr --replSet shard2 --port 41002 --dbpath shard\2_2\data --logpath shard\2_2\log\shard.log -- nojournal --oplogSize 10
shard3:
mongod --shardsvr --replSet shard3 --port 42000 --dbpath shard\3\data --logpath shard\3\log\shard.log --nojournal --oplogSize 10
mongod --shardsvr --replSet shard3 --port 42001 --dbpath shard\3_1\data --logpath shard\3_1\log\shard.log -- nojournal --oplogSize 10
mongod --shardsvr --replSet shard3 --port 42002 --dbpath shard\3_2\data --logpath shard\3_2\log\shard.log -- nojournal --oplogSize 10
4) 啟動分區複本集
登入各個複本集中的任意執行個體,進行複本集初始化
config={_id:"shard1",members:[
{_id:0,host:"jsj-1306-201:40000","priority":2},
{_id:1,host:"jsj-1306-201:40001"},
{_id:2,host:"jsj-1306-201:40002",arbiterOnly:true}
]
}
config={_id:"shard2",members:[
{_id:0,host:"jsj-1306-201:41000",arbiterOnly:true},
{_id:1,host:"jsj-1306-201:41001","priority":2},
{_id:2,host:"jsj-1306-201:41002"}
]
}
config={_id:"shard3",members:[
{_id:0,host:"jsj-1306-201:42000"},
{_id:1,host:"jsj-1306-201:42001",arbiterOnly:true},
{_id:2,host:"jsj-1306-201:42002","priority":2}
]
}
詳細操作方法參考複本集
5) 設定分區,讓分區生效
串連mongos,比如
mongo jsj-1306-201:20000
use admin
db.runCommand({addshard:"shard1/jsj-1306-201:40000,jsj-1306-201:40001,jsj-1306-201:40002"});
db.runCommand({addshard:"shard2/jsj-1306-201:41000,jsj-1306-201:41001,jsj-1306-201:41002"});
db.runCommand({addshard:"shard3/jsj-1306-201:42000,jsj-1306-201:42001,jsj-1306-201:42002"});
6) 查看分區
在mongos下
db.runCommand( { listshards : 1 } );
3、 測試分區
在mongos下:
mongos> use test
switched to db test
mongos> use admin
switched to db admin
mongos> db.runCommand({enablesharding:"testdb"});
{ "ok" : 1 }
mongos> db.runCommand({shardcollection:"testdb.table1",key:{id:1}});
{ "collectionsharded" : "testdb.table1", "ok" : 1 }
mongos> use testdb;
switched to db testdb
mongos> for(var i=1;i<=100000;i++) db.table1.save({id:i,"test1":"testval1"});
查閱資料分布情況:
mongos> db.table1.stats();
4、 查閱分區資訊
分區叢集的資訊儲存在congfig伺服器,名為config的資料庫裡。通過mongos可以進行訪問。
mongos> use config
1) 查詢當前的版本
mongos> db.getCollection("version").findOne()
2) 查詢當前的配置CHUNKSIZE的大小
mongos> db.settings.find()
3) 查詢整個SHARD叢集的成員
mongos> db.shards.find()
4) 查詢被水平分割的集合:
mongos> db.collections.find()
5) 查詢被水平分割的集合分成的CHUNK分布
mongos> db.chunks.find()
6) 查詢當前MONGODB裡面的資料庫的SHARD資訊:
mongos> db.databases.find()
7) 查詢MONGOS集合
mongos> db.mongos.find()
8) 查看整個MONGODB 資料庫SHARD的詳細資料
mongos> printShardingStatus();
參考文章:
http://www.lanceyan.com/tech/arch/mongodb_shard1.html
http://blog.itpub.net/22664653/viewspace-710281/