天天看點

MongoDB主從/叢集/分片

本文内容筆者均在本地操作成功。

1.主從複制 master :./mongod --dbpath=xxx --port=xxx --master slave:./mongod --dbpath=xxx --port=xxx --slave --source=MASTER_IP:MASTER_PORT 好處:資料備份/資料恢複/讀寫分離

2.副本集 該叢集沒有特定的主資料庫。 如果哪個主資料庫當機了,叢集中就會推選出一個從屬資料庫作為主資料庫頂上,這就具備了自動故障恢複功能。 ./mongod --dbpath=xxx --port=xxx --replSet REPLSET_NAME ./mongod --dbpath=xxx --port=xxx --replSet REPLSET_NAME

... 進入任意資料庫,執行: >var config={_id:"test_repl",members:[{_id:0,host:"127.0.0.1:2222"},{_id:1,host:"127.0.0.1:3333"}]}; >rs.initiate(config);

{

"info" : "Config now saved locally. Should come online in about a minute.",

"ok" : 1

}

test_repl:PRIMARY>

此時還需要指定仲裁伺服器,執行:

rs.addArb("127.0.0.1:4444");

rs.status();

檢視現在系統中仲裁/主/從等的配置設定。

關閉任意資料庫,然後通過rs.status()驗證自動故障恢複功能。

3.分片

在mongodb裡面存在另一種叢集,就是分片技術,跟sql server的表分區類似,我們知道當資料量達到T級别的時候,我們的磁盤,記憶體就吃不消了,針對這樣的場景我們該如何應對。

mongodb采用将集合進行拆分,然後将拆分的資料均攤到幾個片上的一種解決方案。

MongoDB主從/叢集/分片

人臉:       代表用戶端,用戶端肯定說,你資料庫分片不分片跟我沒關系,我叫你幹啥就幹啥,沒什麼好商量的。

mongos: 首先我們要了解”片鍵“的概念,也就是說拆分集合的依據是什麼?按照什麼鍵值進行拆分集合....

                     好了,mongos就是一個路由伺服器,它會根據管理者設定的“片鍵”将資料分攤到自己管理的mongod叢集,資料

                    和片的對應關系以及相應的配置資訊儲存在"config伺服器"上。

mongod:   一個普通的資料庫執行個體,如果不分片的話,我們會直接連上mongod。

實作過程:

1.開啟config伺服器

先前也說了,mongos要把mongod之間的配置放到config伺服器裡面,理所當然首先開啟它。

nohup ./mongod --dbpath=/home/zd/mongodb2.4.4/mongodb-config/db/ --port=2222 &

2.開啟mongos伺服器

 這裡要注意的是我們開啟的是mongos,不是mongod,同時指定下config伺服器。

nohup ./mongos --port=3333 --configdb=127.0.0.1:2222 &

這裡不需要指定dbpath,否則起不來

3.啟動mongod伺服器

對分片來說,也就是要添加片了。

nohup ./mongod --dbpath=/home/zd/mongodb2.4.4/mongodb-ins1/db/ --port=4444 &

nohup ./mongod --dbpath=/home/zd/mongodb2.4.4/mongodb-ins2/db/ --port=5555 &

4.服務配置

-先前圖中也可以看到,我們client直接跟mongos打交道,也就說明我們要連接配接mongos伺服器,然後将4444,5555的mongod交給mongos,添加分片也就是addshard()。

mongos> db.runCommand({"addshard":"127.0.0.1:4444",allowLocal:true})

{ "shardAdded" : "shard0000", "ok" : 1 }

mongos> db.runCommand({"addshard":"127.0.0.1:5555",allowLocal:true})

{ "shardAdded" : "shard0001", "ok" : 1 }

這裡要注意的是,在addshard中,我們也可以添加副本集,這樣能達到更高的穩定性。

-片已經叢集了,但是mongos不知道該如何切分資料,也就是我們先前所說的片鍵,在mongodb中設定片鍵要做兩步:

①:開啟資料庫分片功能,指令很簡單 enablesharding(),這裡我就開啟test資料庫。

mongos> db.runCommand({"enablesharding":"test"})

{ "ok" : 1 }

②:指定集合中分片的片鍵,這裡我就指定為person.name字段。

mongos> db.runCommand({"shardcollection":"test.person","key":{"name":1}})

{ "collectionsharded" : "test.person", "ok" : 1 }

5.檢視效果

好了,至此我們的分片操作全部結束,接下來我們通過mongos向mongodb插入10w記錄,然後通過printShardingStatus指令檢視mongodb的資料分片情況。

mongos> use test

switched to db test

mongos> for(var i=0;i<100000;i++){

... db.person.insert({"name":"jack"+i,"age":i})

... }

mongos> db.printShardingStatus()

--- Sharding Status --- 

sharding version: {

"_id" : 1,

"version" : 3,

"minCompatibleVersion" : 3,

"currentVersion" : 4,

"clusterId" : ObjectId("51d27eb0aa0fa9779621879e")

}

shards:

{ "_id" : "shard0000", "host" : "127.0.0.1:4444" }

{ "_id" : "shard0001", "host" : "127.0.0.1:5555" }

databases:

{ "_id" : "admin", "partitioned" : false, "primary" : "config" }

{ "_id" : "test", "partitioned" : true, "primary" : "shard0000" }

test.person

shard key: { "name" : 1 }

chunks:

shard0000 2

shard0001 1

{ "name" : { "$minKey" : 1 } } -->> { "name" : "jack0" } on : shard0000 { "t" : 2, "i" : 1 } 

{ "name" : "jack0" } -->> { "name" : "jack9999" } on : shard0000 { "t" : 1, "i" : 3 } 

{ "name" : "jack9999" } -->> { "name" : { "$maxKey" : 1 } } on : shard0001 { "t" : 2, "i" : 0 }

mongos>

這裡主要看三點資訊:

  ① shards:     我們清楚的看到已經别分為兩個片了,shard0000和shard0001。

  ② databases:  這裡有個partitioned字段表示是否分區,這裡清楚的看到test已經分區。

  ③ chunks:     這個很有意思,我們發現集合被砍成三段:

                           無窮小 —— jack0,jack0 ——jack9999,jack9999——無窮大。

                           分區情況為:2:1,從後面的 on shardXXXX也能看得出。