MongoDB提供了Replica pairs模式啟動資料庫,以這種方式啟動後,資料庫會自動協商誰是master誰是slave。一旦一個資料庫伺服器斷電,另外一個會自動接管,並從那一刻起為master,萬一另一個將來也出錯了,那麼master狀態會轉回第一個伺服器。
(10.7.3.95 -> 10.7.3.97 單Replication 沒有shard)
Replication-Sets
Step 1. 兩台伺服器單獨啟動mongod 並加上replSet = XXX 的選項。
Step 2. 隨便選擇一台伺服器,進行Replication的配置.
var cfg = {_id:"dzhRepl", members:[ {_id:0, host:"10.7.3.95:10000"}, {_id:1, host:"10.7.3.97:10000"} ]}rs.initiate(cfg)
到此就初始化好了,然後資料會慢慢遷移到Secondary.
1. rs.slaveOk() 使SECONDARY 也能查詢到資料。
2. rs.stepDown() 使Primary降為Secondary
Master-Slave:
官方介紹: http://www.mongodb.org/display/DOCS/Master+Slave
需要注意參數:
Master configfile:
---
bind_ip = 10.7.3.95
port = 10000
fork = true
master = true
logappend = true
journal = true
dbpath = ../data/
logpath = ../log/mongodb.log
directoryperdb = true
Slave configfile:
----
bind_ip = 10.7.3.97
port = 10000
fork = true
logappend = true
slave = true # 啟動slave
only = testDB # 只同步testDB資料庫
source = 10.7.3.95:10000 # Master host和port
autoresync = true # 當發生意外時,會自動執行同步操作
slavedelay = 10 # 設定更新頻率(s)
journal = true
dbpath = ../Slave
logpath = ../log/mongodb.log.
directoryperdb = true.
Master和Slave啟動後,Master會首先首先建立local資料庫,然后里面有oplog.$main 和slaves 和 system.indexes 和 system.users 等collection。
AutoSharding + Replication-Sets
MongoDB包括一個自動分區模組”mongos“ 從而可以構建一個大的水平可擴充的資料庫叢集,可以動態添加伺服器,自動建立一個水平擴充的資料庫叢集系統,將資料庫分表格儲存體在sharding的各個節點上
這裡我使用3台伺服器做測試。
分別為
10.X.X.21.163
10.X.X.21.164
10.X.X.228
................. (如果有服務沒起來 ,根據經驗可能是你Data下的檔案鎖問題,或者是命名不對)
準備工作:
每台機器先建立資料目錄
Server 1
^_^[root@:/usr/local/mongodb]#mkdir -p data/shard11^_^[root@:/usr/local/mongodb]#mkdir -p data/shard21
Server 2
^_^[root@:/usr/local/mongodb]#mkdir -p data/shard12^_^[root@:/usr/local/mongodb]#mkdir -p data/shard22
Server 3
^_^[root@:/usr/local/mongodb]#mkdir -p data/shard13^_^[root@:/usr/local/mongodb]#mkdir -p data/shard23
然後針對每個伺服器進行Shard1 Replica Sets:
Server1:
./mongod --shardsvr --replSet shard1 --port 27017 --dbpath ../data/shard11 --oplogSize 100 --logpath ../data/shard11.log --logappend --fork.
Server2:
./mongod --shardsvr --replSet shard1 --port 27017 --dbpath ../data/shard12 --oplogSize 100 --logpath ../data/shard12.log --logappend --fork.
Server3:
./mongod --shardsvr --replSet shard1 --port 27017 --dbpath ../data/shard13 --oplogSize 100 --logpath ../data/shard13.log --logappend --fork.
初始化Replica set:
> config={_id:'shard1',members:[... {_id:0,host:'10.X.X.228:27017'},... {_id:1,host:'10.X.X.163:27017'},... {_id:2,host:'10.X.X.164:27017'}]... }
rs.initiate(config);
再給Shard2配置Replica Sets
Server1:
./mongod --shardsvr --replSet shard2 --port 27018 --dbpath ../data/shard21 --oplogSize 100 --logpath ../data/shard21.log --logappend --fork.
Server2:
./mongod --shardsvr --replSet shard2 --port 27018 --dbpath ../data/shard22 --oplogSize 100 --logpath ../data/shard22.log --logappend --fork.
Server3:
./mongod --shardsvr --replSet shard2 --port 27018 --dbpath ../data/shard23 --oplogSize 100 --logpath ../data/shard23.log --logappend --fork.
經過第一次初始化後運行用戶端會出現:
如果要用27018的 需要指定
./mongo 10.X.X.228:27018
再次初始化Replica set:
> config={_id:'shard2',members:[... {_id:0,host:'10.X.X.228:27018'},... {_id:1,host:'10.X.X.163:27018'},... {_id:2,host:'10.X.X.164:27018'}]... }
rs.initiate(config);
現在有2 個 Replica sets 和2個shards
.......................
再配置三台Config Server
mkdir -p data/config./mongod --configsvr --dbpath ../data/config --port 20000 --logpath ../data/config.log -- logappend --fork.
每台Server都這樣運行一遍(哎。好多配置啊。。。。。)
再配置Mongos(同樣每台機器都要運行一遍)
./mongos --configdb 10.X.X.228:20000,10.X.X.163:20000,10.X.X.164:20000 --port 30000 - -chunkSize 5 --logpath ../data/mongos.log --logappend --fork
再Config Shard Cluster
串連到mongos,並且切換到admin
./mongo 10.X.X.228:30000/admin
>db
admin
再加入Shards
db.runCommand({addshard:"shard1/10.7.3.228:27017,10.10.21.163:27017,10.10.21.164:27017",name:"s1",maxsize:20480}); db.runCommand({addshard:"shard2/10.7.3.228:27018,10.10.21.163:27018,10.10.21.164:27018",name:"s2",maxsize:20480});
enable一個資料庫
db.runCommand({ enablesharding:"test" })
資料集分區
db.runCommand({ shardcollection: "test.users", key: { _id:1 }})
列出已經加入的Shards
> db.runCommand({listshards:1})
查看Sharding資訊
printShardingStatus ()
查看Shard儲存資訊(需要先use test)
db.users.stats()
> use test switched to db test> db.users.stats(){ "sharded" : true, "ns" : "test.users", "count" : 0, "size" : 0, "avgObjSize" : NaN, "storageSize" : 8192, "nindexes" : 1, "nchunks" : 1, "shards" : { "s1" : { "ns" : "test.users", "count" : 0, "size" : 0, "storageSize" : 8192, "numExtents" : 1, "nindexes" : 1, "lastExtentSize" : 8192, "paddingFactor" : 1, "flags" : 1, "totalIndexSize" : 8192, "indexSizes" : { "_id_" : 8192 }, "ok" : 1 } }, "ok" : 1}
下面對分區進行測試:
#include <iostream>#include <mongo/client/dbclient.h>using namespace std;using namespace mongo;#define INIT_TIME \ struct timeval time1,time2; \#define START_TIME \ gettimeofday(&time1,NULL); \#define STOP_TIME \ gettimeofday(&time2,NULL); \#define PRINT_TIME \ cout<<"Time:"<<time2.tv_sec-time1.tv_sec<<":"<<time2.tv_usec-time1.tv_usec<<endl;int main() { srand(time(NULL)); char ar[26+1]; DBClientConnection conn; conn.connect("10.7.3.228:30000"); cout<<"MongoDB Connected OK!"<<endl; int count=10000000; INIT_TIME; START_TIME;//insert#if 1 while (count--) { //loop insert 1000W for (int i=0; i<26; i++) { ar[i] = rand()%26+97; } ar[26]='\0'; BSONObj p = BSON("NewsId"<<ar); conn.insert("test.users",p); }#endif//Query#if 0 cout<<"Count:"<<conn.count("News.News_key")<<endl; BSONObj emptyObj; auto_ptr<DBClientCursor> cursor = conn.query("News.News_key",emptyObj); while (cursor->more()) { BSONObj p = cursor->next(); cout<<p.getStringField("NewsId")<<endl; if (p.getStringField("NewsId")=="bfatckiyxlougsxrffsnylsfuo"){ cout<<"find"<<endl; break; } }#endif STOP_TIME; PRINT_TIME; return 0;}