mongodb的分片

//場景

a.機器的磁盤不夠用了

b.某張表的數據很大,查詢效率很慢,需要分片來保存,提高查詢效率

一般來說,先要從不分片開始,然後在需要的時候將其轉換成分片.

c 單個mongod已經無法滿足寫數據的性能需要了(這裏複習一下,如果想要增加讀性能,較好的方案是採用搭建主從結構,且讓從節點可以響應查詢請求)

d  想將大量的數據放到內存中提高性能,一臺機器的內存大小永遠有極限(這就是縱向擴展和橫向擴展的區別)

//關鍵字

     客戶端:  客戶端說,你數據庫分片不分片跟我沒關係,我只需要連接mongos,然後查詢完事

     mongos: 就是一個路由服務器,它會根據管理員設置的“片鍵”將數據分攤到自己管理的mongod集羣,數據和片的對應關係以及相應的配置信息保存在"config服務器"上。它路由所有的請求,然後將結果聚合.它本身並不存儲數據或者配置信息【分片所有的後臺命令都在路由中敲定】

    ConfigServer:存儲了集羣的配置信息:數據和片的對應關係

    mongod:   我們要分片的mongodb服務器,每個mongodb都可以做

 

//實際操作

參考 http://blog.csdn.net/irelandken/article/details/8003203

 

1:創建存儲目錄

mkdir -p /scmgt/data/shard/s1

mkdir -p /scmgt/data/shard/s2

mkdir -p /scmgt/data/shard/s3

 

 

2:啓動Config配置服務器

mkdir -p /scmgt/shard/config/

/scmgt/mongodb/mongodb/bin/mongod --dbpath=/scmgt/shard/config  --logpath=/scmgt/shard/info.log --logappend --port=9334 --fork

 

3.啓動mongs路由服務器

【只需要--configdb配置服務器地址】

mongos啓動參數中,chunkSize這一項是用來指定chunk的大小的,單位是MB,默認大小爲200MB,爲了方便測試Sharding效果,我們把chunkSize指定爲 1MB。意思是當這個分片中插入的數據大於1M時開始進行數據轉移】

/scmgt/mongodb/mongodb/bin/mongos --configdb=localhost:9334  --chunkSize 1  --logpath=/scmgt/shard/route.log --logappend --port 9333 --fork

 

 

4:啓動分片服務器

/scmgt/mongodb/mongodb/bin/mongod --dbpath=/scmgt/data/shard/s1  --logpath=/scmgt/shard/s1.log --logappend --port=9335 --fork

/scmgt/mongodb/mongodb/bin/mongod --dbpath=/scmgt/data/shard/s2  --logpath=/scmgt/shard/s2.log --logappend --port=9336 --fork

/scmgt/mongodb/mongodb/bin/mongod --dbpath=/scmgt/data/shard/s3  --logpath=/scmgt/shard/s3.log --logappend --port=9337 --fork

 

 

5:連接mongos路由服務器配置Sharding

/scmgt/mongodb/mongodb/bin/mongo --port 9333  [注意,必須登陸路由服務器]

use admin

//添加分片節點,每個分片都是一個副本集【allowLocal:true僅僅開發時纔將分片配置到本地,生產時不能這樣】

db.runCommand({addshard:"localhost:9335",allowLocal:true})

db.runCommand({addshard:"localhost:9336",allowLocal:true})

db.runCommand({addshard:"localhost:9337",allowLocal:true,”maxSize”:20000})

 

注意:還可以爲不同分片設置大小”maxSize”:20000(20gb)

 

//要分片的數據庫

db.runCommand({enablesharding:"mydb"})

//設置要分片的集合:users集合,name字段爲key來分片

db.runCommand({shardcollection:"mydb.users",key:{name:1}})

//db.runCommand({shardcollection:"mydb.users",key:{_id:1,name:1,name:1}})

【如果出現"errmsg" : "please create an index that starts with the shard key before sharding.",請創建索引】

 

 

 

6:開始導入數據

略過

 

 

7:查看結果

/scmgt/mongodb/mongodb/bin/mongo --port 9333

查看分區情況

use mydb

db.users.getShardDistribution()

db.users.stats();

查看分區情況

use admin

db.printShardingStatus()

 

 

 

9.向已經分片的數據中,再次添加分片

db.runCommand({addshard:"localhost:9337",allowLocal:true})

會自動平衡數據

 

 

10。自動平衡數據

 還需要說明的是,一開始插入數據時,數據是隻插入到其中一塊分片上的,插入完畢後,mongodb內部開始在各片之間進行數據的移動,這個過程可能不是立即的,mongodb足夠智能會根據當前負載決定是立即進行移動還是稍後移動。

在插入數據後,立馬執行db.users.stats();兩次可以驗證如上所說。

路由服務器設置了chunkSize1M,分區會在10倍也就是10M範圍內分區

 

 

 

11.刪除節點  時間很久,要慢慢等待,

db.runCommand({removeshard:"localhost:9335"})   

db.runCommand({removeshard:"localhost:9336"})

db.runCommand({removeshard:"localhost:9337"})

【如果刪除的是主節點,還需要】

db.runCommand({"moveprimary" : "mydb","to" : "localhost:9336"}) 

【刪除完後還需要在執行一次db.runCommand({removeshard:"localhost:xxxx"})   才能完整刪除】

【觀察刪除情況:】

use admin

db.printShardingStatus()

或者

看錶裏面數據

【這種方式不能刪除所有分片,最後一個分片是不能刪除的】

 

12.完全刪除所有分片和集合,重新建立新的

殺掉進程

ps -ef| grep mong

kill -2 

刪除數據

cd /scmgt/data/shard/s1 rm -rf /scmgt/data/shard/s1/*

cd /scmgt/data/shard/s2 rm -rf /scmgt/data/shard/s2/*

cd /scmgt/data/shard/s3 rm -rf /scmgt/data/shard/s3/*

刪除配置服務器配置

rm -rf /scmgt/shard/config/*

 

 

 

 

 

 

//片建選擇【必須有索引,推薦組合鍵,鍵值的變化大】

參考http://www.cnblogs.com/spnt/archive/2012/07/27/2611540.html

片鍵應該有較多變化的值,如果片鍵設定爲性別,只有“男”和“女”兩種值,則這個集合就最多被分爲兩片,如果集合太大,這種分片不會最終解決效率的問題!這裏我們可以看出,片鍵的選擇和創建索引時鍵的選擇原則是相似的,實際使用中,通常片鍵就是創建索引使用的鍵

一個片鍵包含兩個字段,並確保第二個字段有非常多不同的值供MongoDB用來進行分割,比如大部分的查詢都和時間關聯,可以用時間字段做第二個字段,又可以減輕負載。

 

 

//需要驗證

1:將已有數據的集合分片,是否會分片   

原來的數據會自動分片,【最好跟oracle分區一樣,重新導入】

2:設置不同的鍵,分區是否平衡

根據鍵值的浮動區間,分片大小會不平衡,如果遞增的鍵值,大部分數據後會保存在最後一個分區裏面。

3:程序查詢是否是查詢路由ip地址即可

是的,用戶只需要跟路由打交道,不需要知道路由跟分片的事

4:新增或者刪除分片,是否會平衡移動數據

刪除分片會先移動數據再刪除分片,過程很慢

新增分片後,mogondb後臺會自動平衡移動數據

 

//優化知識擴展

1:永遠不要再分片將要滿的時候再擴容,必須未雨綢繆

2:如果選錯了片建,想取消片鍵

   可以把所有分片數據放到1個分片上,然後導出分片數據到另外一個集合裏面,刪除配置服務器配置,刪除分片,重新做分片

3:分片時使用mapreduce,每個分片都會執行自己的mapreduce

//Replica Sets + Sharding 方案 及 chunks塊 和 片鍵分析

 參考

http://blog.csdn.net/irelandken/article/details/8003195

http://www.cnblogs.com/spnt/archive/2012/07/26/2610070.html

 

 

  架構如下:

      1shard服務器:使用Replica Sets確保每個數據節點都具有備份、自動容錯轉移、自動恢復的能力。

      2,配置服務器:使用使用3個配置服務器確保元數據完整性

      3,路由進程:使用3個路由進程實現平衡,提高客戶端接入性能,架構如下

 

 

【啓動多個路由來平衡客戶端訪問】

因爲路由不保存配置只是個連接點,所有只需要指向一樣的配置即可

【啓動多個配置服務器】

/Apps/mongo/bin/mongos --port 50000 --configdb 127.0.0.1:40000,127.0.0.1:40001,127.0.0.1:40002 --chunkSize 1

【副本集分片【其中shard裏面的都是同一副本集的】】

db.runCommand({addshard:"replset1/127.0.0.1:18010,127.0.0.1:18011,127.0.0.1:18012",allowLocal:true})

分類: MongoDB2012-09-21 10:49 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章