MongoDB 基礎(九)分區,mongodb基礎

來源:互聯網
上載者:User

MongoDB 基礎(九)分區,mongodb基礎


分區(sharding)是通過多台伺服器儲存資料的方法。Mongodb使用分區可支援部署非常大的資料集和高的輸送量操作。單台伺服器的能力在各方面都有限,如CPU、IO、RAM、儲存空間等。解決擴充的問題,資料庫提供了兩種方法:垂直擴充和分區。


垂直擴充:增加CPU、RAM,儲存資源等,這也受限於硬體裝置。而有些雲端式的供應商也規定使用者使用小的系統。


分區(水平擴充):劃分資料集,將資料分布到多台伺服器中,每個片段(chard)是一個獨立的資料庫,這些片段共同組成了一個邏輯的資料庫。(這類似於Windows動態磁碟條帶化一樣)


Mongodb 中的分區叢集結構如下:


分區叢集有三個組件:shards,query routers 和 configservers。

 

Shards:片段,儲存資料,提供高可用性和資料的一致性。分區叢集中,每個片段都是一個複製集。

 

query routers:查詢路由,或稱mongos執行個體,用戶端應用程式直接操作片段的介面。查詢路由處理和定位操作到片段中並返回相關資料到用戶端。一個分區叢集包含多個查詢路由來劃分用戶端的請求壓力。

 

configservers:設定管理員,儲存叢集中的中繼資料。這些資料包含叢集資料到片段的映射。查詢路由使用這些中繼資料定位操作到明確的片段中。共用叢集需要有3台設定管理員。


註:用於測試,可以值配置1個config servers


Mongodb 分布資料或片段,是在collection 層級上。分區是通過shardkey 劃分一個集合的資料。shard key 可以是一個索引鍵列,或者是存在每個文檔中的複合鍵列。Mongodb 劃分shard key 值到 chunk 中,並將chunk平均分配到片段中。Mongodb 使用劃分的方法為定界分割或者雜湊分割。(更多參考:shardkey)


分區叢集部署:

Mongodb伺服器:(Red HatEnterprise Linux 6 64-bit + Mongodb 3.0.2)

192.168.1.11    mongodb11.kk.net  21017

192.168.1.12    mongodb12.kk.net  21018

192.168.1.13    mongodb13.kk.net  21019

192.168.1.14    mongodb14.kk.net  21020


用於測試結構如下:


註:配置前確保要加入叢集中的成員都能相互串連。



【1. 配置 config servers】(在 192.168.1.14伺服器上)

設定管理員(config servers)儲存叢集中繼資料,因此首先配置該伺服器。設定管理員需使用參數—configsvr 來啟動mongod服務。若有多個設定管理員,每個設定管理員都完整儲存叢集的元素就。

1. 1 建立資料庫目錄 configdb :

[root@mongodb14 ~]# mkdir /var/lib/mongo/configdb[root@mongodb14 ~]# chown mongod:mongod /var/lib/mongo/configdb/

1.2.  配置啟動參數檔案:

[root@mongodb14 ~]# vi /etc/mongod.conf

192.168.1.14

logpath=/var/log/mongodb/mongod.log

pidfilepath=/var/run/mongodb/mongod.pid

logappend=true

fork=true

port=27020

bind_ip=192.168.1.14

dbpath=/var/lib/mongo/configdb

configsvr=true


1.3.  重啟 mongod 服務:

[root@mongodb14 ~]# service mongod restart


【2. 配置 router】(在 192.168.1.11伺服器上)

2.1.啟用 mongos (MongoDB Shard)執行個體,串連到 config servers:(更多參考:mongos 

#使用mongos串連到config servers,指定本地連接埠,否則預設27017#當前伺服器mongod 連接埠為27017,所以配置mongos 連接埠為27016#mongo --host <hostname of machine running mongos> --port <port mongos listens on>[root@redhat11 ~]# mongos --configdb mongodb14.kk.net:27020 --port 27016 --chunkSize 200 --logpath /var/log/mongodb/mongos.log --fork

實際環境中,若配置了多個config servers ,mongos 可同時指定多個。

mongos--configdb mongodb14.kk.net:27020, mongodb15.kk.net:27020,mongodb16.kk.net:27020……


【3. 添加 shard 成員到叢集中】(添加IP為 11、12、13 分區集中 ,以192.168.1.11為例)

3.1. 配置啟動參數檔案:

[root@redhat11 ~]# vi /etc/mongod.conf

192.168.1.11

192.168.1.12

192.168.1.13

logpath=/var/log/mongodb/mongod.log

pidfilepath=/var/run/mongodb/mongod.pid

logappend=true

fork=true

port=27017

bind_ip=192.168.1.11

dbpath=/var/lib/mongo

shardsvr=true

 

logpath=/var/log/mongodb/mongod.log

pidfilepath=/var/run/mongodb/mongod.pid

logappend=true

fork=true

port=27018

bind_ip=192.168.1.12

dbpath=/var/lib/mongo

shardsvr=true

 

logpath=/var/log/mongodb/mongod.log

pidfilepath=/var/run/mongodb/mongod.pid

logappend=true

fork=true

port=27019

bind_ip=192.168.1.13

dbpath=/var/lib/mongo

shardsvr=true

 


3.2.重啟 mongod 服務:

[root@mongodb11 ~]# service mongod restart

3.3各shard 成員串連到mongos 執行個體中添加(添加前把已存在的使用者資料移走或者刪除):

[root@mongodb11 ~]# mongo 192.168.1.11:27016mongos> sh.addShard("mongodb11.kk.net:27017")mongos> sh.addShard("mongodb12.kk.net:27018")mongos> sh.addShard("mongodb13.kk.net:27019")

3.4添加完成!~串連到mongos可查看系統相關資訊:

configsvr> show dbsconfigsvr> use configconfigsvr> show collectionsconfigsvr> configsvr> db.mongos.find(){ "_id" : "mongodb11.kk.net:27016", "ping" : ISODate("2015-05-23T11:16:47.624Z"), "up" : 1221, "waiting" : true, "mongoVersion" : "3.0.2" }configsvr> configsvr> db.shards.find(){ "_id" : "shard0000", "host" : "mongodb11.kk.net:27017" }{ "_id" : "shard0001", "host" : "mongodb12.kk.net:27018" }{ "_id" : "shard0002", "host" : "mongodb13.kk.net:27019" }configsvr> configsvr> db.databases.find(){ "_id" : "admin", "partitioned" : false, "primary" : "config" }{ "_id" : "mydb", "partitioned" : false, "primary" : "shard0000" }{ "_id" : "test", "partitioned" : false, "primary" : "shard0000" }


【4. 對資料庫啟用分區】

4.1 當前可串連到 mongos 查看資料庫或者集合的分區情況(沒有分區):

mongos> db.stats()mongos> db.tab.stats()

4.2 對資料庫啟用分區功能:

[root@mongodb11 ~]# mongo 192.168.1.11:27016mongos> sh.enableSharding("test")#或者[root@mongodb11 ~]# mongo 192.168.1.11:27016mongos> use adminmongos> db.runCommand( { enableSharding: "test"} )

4.3 此時查看資料庫分區情況,partitioned 變為 “true”。

configsvr> use configswitched to db configconfigsvr> db.databases.find(){ "_id" : "admin", "partitioned" : false, "primary" : "config" }{ "_id" : "mydb", "partitioned" : true, "primary" : "shard0000" }{ "_id" : "test", "partitioned" : true, "primary" : "shard0000" }


啟用資料庫分區並沒有將資料進行分開,還需要對 collection 進行分區。

【5. 對集合啟用分區】

啟用前,有幾個問題需要考慮的:

1. 選擇哪個鍵列作為 shard key  。(更多參考: Considerations for Selecting Shard Keys)

2. 如果集合中已經存在資料,在選定作為shard key 的鍵列必須建立索引;如果集合為空白,mongodb 將在啟用集合分區(sh.shardCollection)時建立索引。

3. 集合分區函數 sh.shardCollection ,


sh.shardCollection("<database>.<collection>", shard-key-pattern)


mongos> sh.shardCollection("test.tab", { "_id": "hashed" })


測試:

for (var i=1; i<100000; i++) {db.kk.insert({"id": i, "myName" : "kk"+i, "myDate" : new Date()});}mongos> show collectionsmongos> db.kk.find()mongos> db.kk.createIndex({ "id": "hashed" })mongos> db.kk.getIndexes()mongos> sh.shardCollection("test.kk", { "id": "hashed" })mongos> db.stats()mongos> db.kk.stats()


由於資料分區需要時間,過會再查看資料分布情況:

 總行數:99999

mongos> db.kk.count()99999

mongos> db.printShardingStatus();--- Sharding Status ---   sharding version: {"_id" : 1,"minCompatibleVersion" : 5,"currentVersion" : 6,"clusterId" : ObjectId("556023c02c2ebfdfbc8d39eb")}  shards:{  "_id" : "shard0000",  "host" : "mongodb11.kk.net:27017" }{  "_id" : "shard0001",  "host" : "mongodb12.kk.net:27018" }{  "_id" : "shard0002",  "host" : "mongodb13.kk.net:27019" }  balancer:Currently enabled:  yesCurrently running:  noFailed balancer rounds in last 5 attempts:  0Migration Results for the last 24 hours: 1334 : Success2 : Failed with error 'could not acquire collection lock for test.kk to migrate chunk [{ : MinKey },{ : MaxKey }) :: caused by :: Lock for migrating chunk [{ : MinKey }, { : MaxKey }) in test.kk is taken.', from shard0000 to shard0001  databases:{  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }{  "_id" : "mydb",  "partitioned" : true,  "primary" : "shard0000" }{  "_id" : "test",  "partitioned" : true,  "primary" : "shard0000" }test.kkshard key: { "id" : "hashed" }chunks:shard0000667shard0001667shard0002667too many chunks to print, use verbose if you want to force print{  "_id" : "events",  "partitioned" : false,  "primary" : "shard0002" }mongos> 


看這裡 chunks :
shard0000 667
shard0001 667
shard0002 667

原本 shard0000 最大,shard0001 與 shard0002 為 0 。最終平均,資料將穩定不再變化。

mongos> db.kk.stats(){"sharded" : true,"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.","userFlags" : 1,"capped" : false,"ns" : "test.kk","count" : 99999,"numExtents" : 19,"size" : 11199888,"storageSize" : 44871680,"totalIndexSize" : 10416224,"indexSizes" : {"_id_" : 4750256,"id_hashed" : 5665968},"avgObjSize" : 112,"nindexes" : 2,"nchunks" : 2001,"shards" : {"shard0000" : {"ns" : "test.kk","count" : 33500,"size" : 3752000,"avgObjSize" : 112,"numExtents" : 7,"storageSize" : 22507520,"lastExtentSize" : 11325440,"paddingFactor" : 1,"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.","userFlags" : 1,"capped" : false,"nindexes" : 2,"totalIndexSize" : 3605616,"indexSizes" : {"_id_" : 1913184,"id_hashed" : 1692432},"ok" : 1},"shard0001" : {"ns" : "test.kk","count" : 32852,"size" : 3679424,"avgObjSize" : 112,"numExtents" : 6,"storageSize" : 11182080,"lastExtentSize" : 8388608,"paddingFactor" : 1,"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.","userFlags" : 1,"capped" : false,"nindexes" : 2,"totalIndexSize" : 3343984,"indexSizes" : {"_id_" : 1389920,"id_hashed" : 1954064},"ok" : 1},"shard0002" : {"ns" : "test.kk","count" : 33647,"size" : 3768464,"avgObjSize" : 112,"numExtents" : 6,"storageSize" : 11182080,"lastExtentSize" : 8388608,"paddingFactor" : 1,"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.","userFlags" : 1,"capped" : false,"nindexes" : 2,"totalIndexSize" : 3466624,"indexSizes" : {"_id_" : 1447152,"id_hashed" : 2019472},"ok" : 1}},"ok" : 1}mongos> 


上面中,個分區資料分布情況:

"shard0000"  "count" : 33500

"shard0001"  "count" : 32852

"shard0002"  "count" : 33647


總計99999 行,完全準確,資料分布也很平均了。

(測試資料盡量多些,否則看不得效果。一開始本人測試資料較少,不到1000行,沒有效果,還以為哪裡出現問題,又多折騰了2小時!~)



參考: Sharding Introduction

(官方文檔的步驟不是很清楚,倒騰了好久。網上也有些部落格介紹,也只是博主的總結,對於一個新人來講,在哪操作,操作什麼不詳細)




相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.