標籤:use The init 大資料量 需要 生產 利用 insert 其他
什麼是分區
高資料量和輸送量的資料庫應用會對單機的效能造成較大壓力,大的查詢量會將單機的CPU耗盡,大的資料量對單機的儲存壓力較大,最終會耗盡系統的記憶體而將壓力轉移到磁碟IO上。
MongoDB分區是使用多個伺服器儲存資料的方法,以支援巨大的資料存放區和對資料進行操作。分區技術可以滿足MongoDB資料量大量增長的需求,當一台MongoDB伺服器不足以儲存海量資料或者不足以提供可接受的讀寫輸送量時,我們就可以通過在多台伺服器上分割資料,使得資料庫系統能儲存和處理更多的資料。
MongoDB分區優勢
分區為應對高輸送量與大資料量提夠了方法
- 使用分區減少了每個分區需要處理的請求數,因此,通過水平擴充,群集可以提高自己的儲存容量。比如,當插入一條資料時,應用只需要訪問儲存這條資料的分區。
- 使用分區減少了每個分區村儲存的資料
分區的優勢在於提供類似線性增長的架構,提高資料可用性,提高大型資料庫查詢服務器的效能。當MongoDB單點資料庫伺服器儲存成為瓶頸、單點資料庫伺服器的效能成為瓶頸或需要部署大型應用以充分利用記憶體時,可以使用分區技術。MongoDB分區群集的組成
- Shard:分區伺服器,用於儲存實際的資料區塊,實際生產環境中一個shard server 角色可以由幾台伺服器組成一個Peplica Set 承擔,防止主機單點故障。
- Config Server:設定管理員,儲存了整個分區群集的配置資訊,其中包括chunk資訊。
- Routers:前端路由,用戶端由此接入,且讓整個群集看上去像單一資料庫,前端應用可以透明使用。
環境準備
IP:172.16.10.26 |
IP:172.16.10.27 |
IP:172.16.10.29 |
mongos(27017) |
mongos(27017) |
mongos(27017) |
config(30000) |
config(30000) |
config(30000) |
shard1主節點(40001) |
shard1副節點(40001) |
shard1仲裁節點(40001) |
shard2仲裁節點(40002) |
shard2主節點(40002) |
shard2副節點(40002) |
shard1副節點(40003) |
shard1仲裁節點(40003) |
shard1主節點(40003) |
部署MongoDB分區群集
群集部署的搭建思路,利用三台伺服器,分別安裝mongodb資料庫,每台伺服器建立五個執行個體(mongos、configs、shard1、shard2、shard3)。三台不同的伺服器上的相同名稱的執行個體,建立為一個複製集,分別包括主節點,副節點,仲裁節點。mongos不需建立複製集,config不需指定主副節點及仲裁節點,但是要建立複製集。三台伺服器的操作步驟略有差別,但是大多是都是重複操作,步驟完全一致。
安裝MongoDB資料庫安裝支援軟體和mongodb
yum install openssl-devel -ytar zxf mongodb-linux-x86_64-rhel70-4.0.0.tgz -C /usr/localmv /usr/local/mongodb-linux-x86_64-rhel70-4.0.0 /usr/local/mongodb //解壓即完成安裝
建立資料存放區目錄和日誌儲存目錄
路由伺服器不儲存資料,因此就不需要建立資料存放區目錄,只需建立config、shard1、shaed2、shard3即可,記錄檔建立完成之後還需要給予許可權。
mkdir -p /data/mongodb/logs/mkdir /etc/mongodb/mkdir /data/mongodb/config/mkdir /data/mongodb/shard{1,2,3}touch /data/mongodb/logs/shard{1,2,3}.logtouch /data/mongodb/logs/mongos.logtouch /data/mongodb/logs/config.logchmod 777 /data/mongodb/logs/*.log
建立系統管理使用者,修改目錄許可權
useradd -M -u 8000 -s /sbin/nologin mongochown -R mongo.mongo /usr/local/mongodbchown -R mongo.mongo /data/mongodb
設定環境變數
echo "PATH=/usr/local/mongodb/bin:$PATH" >> /etc/profilesource /etc/profile
系統記憶體最佳化
ulimit -n 25000ulimit -u 25000sysctl -w vm.zone_reclaim_mode=0echo never > /sys/kernel/mm/transparent_hugepage/enabledecho never > /sys/kernel/mm/transparent_hugepage/defrag //*注意*這些最佳化都是臨時的,重啟失效
部署設定管理員建立設定檔
#vim /etc/mongodb/config.confpidfilepath = /data/mongodb//logs/config.pid //pid檔案位置dbpath = /data/mongodb/config/ //資料檔案存放位置logpath = /data/mongodb//logs/config.log //記錄檔位置logappend = true bind_ip = 0.0.0.0 //監聽地址port = 30000 //連接埠號碼fork = true replSet=configs //複製集名稱configsvr = truemaxConns=20000 //最大串連數
將設定檔發送到其他伺服器
scp /etc/mongodb/config.conf [email protected]:/etc/mongodb/scp /etc/mongodb/config.conf [email protected]:/etc/mongodb/
啟動config執行個體
mongod -f /etc/mongodb/config.conf //三台伺服器操作一致
配置複製集(任一台操作即可)
mongo --port 30000 //建議三台伺服器都進入資料庫,方便查看角色變更config={_id:"configs",members:[{_id:0,host:"172.16.10.26:30000"},{_id:1,host:"172.16.10.27:30000"},{_id:2,host:"172.16.10.29:30000"}]} //建立複製集rs.initiate(config) //初始化複製集
部署shard1分區伺服器建立設定檔
#vim /etc/mongodb/shard1.confpidfilepath = /data/mongodb//logs/shard1.piddbpath = /data/mongodb/shard1/logpath = /data/mongodb//logs/shard1.loglogappend = truejournal = truequiet = truebind_ip = 0.0.0.0port = 40001fork = truereplSet=shard1shardsvr = truemaxConns=20000
將設定檔發送到其他伺服器
scp /etc/mongodb/shard1.conf [email protected]:/etc/mongodb/scp /etc/mongodb/shard1.conf [email protected]:/etc/mongodb/
啟動shard1執行個體
mongod -f /etc/mongodb/shard1.conf //三台伺服器操作一致
配置shard1複製集
在shard分區伺服器的建立中,需要注意的點是,不是在任一台伺服器上建立都能成功的,如果選擇在預先設定為仲裁節點的伺服器上建立複製集會報錯。以shard1分區伺服器為例,可以在172.16.10.26和172.16.10.27伺服器上建立複製集,在172.16.10.29上建立則會失敗,因為在複製集建立之前,172.16.10.29已經被設定為仲裁節點。
mongo --port 40001 //建議三台伺服器都進入資料庫,方便查看角色變更use adminconfig={_id:"shard1",members:[{_id:0,host:"172.16.10.26:40001",priority:2},{_id:1,host:"172.16.10.27:40001",priority:1},{_id:2,host:"172.16.10.29:40001",arbiterOnly:true}]}rs.initiate(config)
部署shard2分區伺服器建立設定檔
#vim /etc/mongodb/shard2.confpidfilepath = /data/mongodb//logs/shard2.piddbpath = /data/mongodb/shard2/logpath = /data/mongodb//logs/shard2.loglogappend = truejournal = truequiet = truebind_ip = 0.0.0.0port = 40002fork = truereplSet=shard2shardsvr = truemaxConns=20000
將設定檔發送到其他伺服器
scp /etc/mongodb/shard2.conf [email protected]:/etc/mongodb/scp /etc/mongodb/shard2.conf [email protected]:/etc/mongodb/
啟動shard2執行個體
mongod -f /etc/mongodb/shard2.conf //三台伺服器操作一致
配置shard複製集(非仲裁節點伺服器)
mongo --port 40002 //建議三台伺服器都進入資料庫,方便查看角色變更use adminconfig={_id:"shard2",members:[{_id:0,host:"172.16.10.26:40002",arbiterOnly:true},{_id:1,host:"172.16.10.27:40002",priority:2},{_id:2,host:"172.16.10.29:40002",priority:1}]}rs.initiate(config)
部署shard3分區伺服器建立設定檔
#vim /etc/mongodb/shard3.confpidfilepath = /data/mongodb//logs/shard3.piddbpath = /data/mongodb/shard3/logpath = /data/mongodb//logs/shard3.loglogappend = truejournal = truequiet = truebind_ip = 0.0.0.0port = 40003fork = truereplSet=shard3shardsvr = truemaxConns=20000
將設定檔發送到其他伺服器
scp /etc/mongodb/shard3.conf [email protected]:/etc/mongodb/scp /etc/mongodb/shard3.conf [email protected]:/etc/mongodb/
啟動shard3執行個體
mongod -f /etc/mongodb/shard3.conf //三台伺服器操作一致
配置shard複製集(非仲裁節點伺服器)
mongo --port 40003 //建議三台伺服器都進入資料庫,方便查看角色變更use adminconfig={_id:"shard3",members:[{_id:0,host:"172.16.10.26:40003",priority:1},{_id:1,host:"172.16.10.27:40003",arbiterOnly:true},{_id:2,host:"172.16.10.29:40003",priority:2}]}rs.initiate(config);
部署路由伺服器建立設定檔
pidfilepath = /data/mongodb/logs/mongos.pidlogpath=/data/mongodb/logs/mongos.loglogappend = truebind_ip = 0.0.0.0port = 27017fork = trueconfigdb = configs/172.16.10.26:30000,172.16.10.27:30000,172.16.10.29:30000maxConns=20000
將設定檔發送到其他伺服器
scp /etc/mongodb/mongos.conf [email protected]:/etc/mongodb/scp /etc/mongodb/mongos.conf [email protected]:/etc/mongodb/
啟動mongos執行個體
mongos -f /etc/mongodb/mongos.conf //三台伺服器操作一致*注意*這裡是“mongos”而非“mongod”
啟用分區功能
mongo //因為預設連接埠即是27017,所以此處不接連接埠號碼mongos> use adminmongos> sh.addShard("shard1/172.16.10.26:40001,172.16.10.27:40001,172.16.10.29:40001")mongos> sh.addShard("shard2/172.16.10.26:40002,172.16.10.27:40002,172.16.10.29:40002")mongos> sh.status() //查看群集狀態//此處先添加兩各分區伺服器,還有一個,待會添加
測試伺服器分區功能設定分區chunk大小
mongos> use configswitched to db configmongos> db.settings.save({"_id":"chunksize","value":1}) //設定塊大小為1M是方便實驗,不然就需要插入海量資料WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "chunksize" })
類比寫入資料
mongos> use pythonswitched to db pythonmongos> show collectionsmongos> for(i=1;i<=50000;i++){db.user.insert({"id":i,"name":"jack"+i})}//在python庫的user表中迴圈寫入五萬條資料WriteResult({ "nInserted" : 1 })
啟用資料庫分區
mongos>sh.enableSharding("python")//資料庫分區就有針對性,可以自訂需要分區的庫或者表,畢竟也不是所有資料都是需要分區操作的
為表建立的索引
建立索引的規則是不能一致性太高,要具有唯一性,例如序號,比如性別這一類重複性太高的就不適合做索引
mongos> db.user.createIndex({"id":1}) //以”id“為索引
啟用表分區
mongos> sh.shardCollection("python.user",{"id":1})
查看分區情況
mongos> sh.status()--- Sharding Status --- ···省略內容 shards: { "_id" : "shard1", "host" : "shard1/172.16.10.26:40001,172.16.10.27:40001", "state" : 1 } { "_id" : "shard2", "host" : "shard2/172.16.10.27:40002,172.16.10.29:40002", "state" : 1 } ···省略內容 chunks: shard1 3 shard2 3 { "id" : { "$minKey" : 1 } } -->> { "id" : 9893 } on : shard1 Timestamp(2, 0) { "id" : 9893 } -->> { "id" : 19786 } on : shard1 Timestamp(3, 0) { "id" : 19786 } -->> { "id" : 29679 } on : shard1 Timestamp(4, 0) { "id" : 29679 } -->> { "id" : 39572 } on : shard2 Timestamp(4, 1) { "id" : 39572 } -->> { "id" : 49465 } on : shard2 Timestamp(1, 4) { "id" : 49465 } -->> { "id" : { "$maxKey" : 1 } } on : shard2 Timestamp(1, 5)
手動添加分區伺服器,查看分區情況是否發生變化
mongos> use adminswitched to db adminmongos> sh.addShard("172.16.10.26:40003,172.16.10.27:40003,172.16.10.29:40003")mongos> sh.status()--- Sharding Status --- ···省略內容 shards: { "_id" : "shard1", "host" : "shard1/172.16.10.26:40001,172.16.10.27:40001", "state" : 1 } { "_id" : "shard2", "host" : "shard2/172.16.10.27:40002,172.16.10.29:40002", "state" : 1 } { "_id" : "shard3", "host" : "shard3/172.16.10.26:40003,172.16.10.29:40003", "state" : 1 } ···省略內容 chunks: shard1 2 shard2 2 shard3 2 { "id" : { "$minKey" : 1 } } -->> { "id" : 9893 } on : shard3 Timestamp(6, 0) { "id" : 9893 } -->> { "id" : 19786 } on : shard1 Timestamp(6, 1) { "id" : 19786 } -->> { "id" : 29679 } on : shard1 Timestamp(4, 0) { "id" : 29679 } -->> { "id" : 39572 } on : shard3 Timestamp(5, 0) { "id" : 39572 } -->> { "id" : 49465 } on : shard2 Timestamp(5, 1) { "id" : 49465 } -->> { "id" : { "$maxKey" : 1 } } on : shard2 Timestamp(1, 5)
伺服器又對資料進行重新分區,當你再次移除一個分區伺服器,此時又會對資料再次進行分區處理,MongoDB對資料的處理非常靈活
MongoDB(4.0)分區——大資料的處理之道