分片(sharding)是MongoDB用來將大型集合水平分割到不一樣服務器(或者複製集)上所採用的方法。不須要功能強大的大型計算機就能夠存儲更多的數據,處理更大的負載。html
1.存儲容量需求超出單機磁盤容量。
2.活躍的數據集超出單機內存容量,致使不少請求都要從磁盤讀取數據,影響性能。
3.IOPS超出單個MongoDB節點的服務能力,隨着數據的增加,單機實例的瓶頸會愈來愈明顯。
4.副本集具備節點數量限制。linux
垂直擴展:增長更多的CPU和存儲資源來擴展容量。
水平擴展:將數據集分佈在多個服務器上。水平擴展即分片。mongodb
分片集羣由如下3個服務組成:
Shards Server: 每一個shard由一個或多個mongod進程組成,用於存儲數據。
Router Server: 數據庫集羣的請求入口,全部請求都經過Router(mongos)進行協調,不須要在應用程,序添加一個路由選擇器,Router(mongos)就是一個請求分發中心它負責把應用程序的請求轉發到對應的Shard服務器上。
Config Server: 配置服務器。存儲全部數據庫元信息(路由、分片)的配置。shell
爲了在數據集合中分配文檔,MongoDB使用分片主鍵分割集合數據庫
在一個shard server內部,MongoDB仍是會把數據分爲chunks,每一個chunk表明這個shard server內部一部分數據。MongoDB分割分片數據到區塊,每個區塊包含基於分片主鍵的左閉右開的區間範圍後端
範圍分片適合知足在必定範圍內的查找,例如查找X的值在[20,30)之間的數據,mongo 路由根據Config server中存儲的元數據,能夠直接定位到指定的shard的Chunk中。
缺點: 若是shard key有明顯遞增(或者遞減)趨勢,則新插入的文檔多會分佈到同一個chunk,沒法擴展寫的能力。
centos
Hash分片是計算一個分片主鍵的hash值,每個區塊將分配一個範圍的hash值。Hash分片與範圍分片互補,能將文檔隨機的分散到各個chunk,充分的擴展寫能力,彌補了範圍分片的不足,缺點是不能高效的服務範圍查詢,全部的範圍查詢要分發到後端全部的Shard才能找出知足條件的文檔
服務器
數據庫中沒有比較合適的片鍵供選擇,或者是打算使用的片鍵基數過小(即變化少如星期只有7天可變化),能夠選另外一個字段使用組合片鍵,甚至能夠添加冗餘字段來組合。通常是粗粒度+細粒度進行組合。app
# 數據庫文件位置 dbpath=config/config1 #日誌文件位置 logpath=config/logs/config1.log # 以追加方式寫入日誌 logappend=true # 是否以守護進程方式運行 fork = true bind_ip=0.0.0.0 port = 17017 # 表示是一個配置服務器 configsvr=true #配置服務器副本集名稱 replSet=configsvr # 數據庫文件位置
# 數據庫文件位置 節點3 config-17019.conf 啓動配置節點 進入任意節點的mongo shell 並添加 配置節點集羣 注意use admin dbpath=config/config2 #日誌文件位置 logpath=config/logs/config.log # 以追加方式寫入日誌 logappend=true # 是否以守護進程方式運行 fork = true bind_ip=0.0.0.0 port = 17018 # 表示是一個配置服務器 configsvr=true #配置服務器副本集名稱 replSet=configsvr
# 數據庫文件位置 dbpath=config/config3 #日誌文件位置 logpath=config/logs/config3.log # 以追加方式寫入日誌 logappend=true # 是否以守護進程方式運行 fork = true bind_ip=0.0.0.0 port = 17019 # 表示是一個配置服務器 configsvr=true #配置服務器副本集名稱 replSet=configsvr
./bin/mongod -f config/config-17017.conf ./bin/mongod -f config/config-17018.conf ./bin/mongod -f config/config-17019.conf
./bin/mongo --port 17017 use admin var cfg ={"_id":"configsvr", "members":[ {"_id":1,"host":"192.168.211.133:17017"}, {"_id":2,"host":"192.168.211.133:17018"}, {"_id":3,"host":"192.168.211.133:17019"}] }; rs.initiate(cfg)
mkdir shard_cluster mv mongodb-linux-x86_64-amazon-3.6.21.tgz shard_cluster/ cd shard_cluster/ tar -xvf mongodb-linux-x86_64-amazon-3.6.21.tgz rm -rf mongodb-linux-x86_64-amazon-3.6.21.tgz mv mongodb-linux-x86_64-amazon-3.6.21 shard_cluster cd shard_cluster/
[root@VM_0_4_centos shard_cluster]# mkdir config/config1 -p [root@VM_0_4_centos shard_cluster]# mkdir config/config2 -p [root@VM_0_4_centos shard_cluster]# mkdir config/config3 -p [root@VM_0_4_centos shard_cluster]# mkdir config/logs/ -p
新建節點配置文件,並依次修改1071七、1701八、17019數據位置,和端口dom
[root@VM_0_4_centos shard_cluster]# vi mongo_17017.conf
[root@VM_0_4_centos shard_cluster]# cp mongo_17017.conf mongo_17018.conf
[root@VM_0_4_centos shard_cluster]# cp mongo_17017.conf mongo_17019.conf
依次啓動各節點
configsvr:SECONDARY> rs.status() { "set" : "configsvr", "date" : ISODate("2020-12-24T07:37:22.074Z"), "myState" : 1, "term" : NumberLong(1), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "configsvr" : true, "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1608795438, 1), "t" : NumberLong(1) }, "readConcernMajorityOpTime" : { "ts" : Timestamp(1608795438, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1608795438, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1608795438, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 1, "name" : "152.136.193.58:17017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 455, "optime" : { "ts" : Timestamp(1608795438, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-12-24T07:37:18Z"), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1608795352, 1), "electionDate" : ISODate("2020-12-24T07:35:52Z"), "configVersion" : 1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 2, "name" : "152.136.193.58:17018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 99, "optime" : { "ts" : Timestamp(1608795438, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1608795438, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-12-24T07:37:18Z"), "optimeDurableDate" : ISODate("2020-12-24T07:37:18Z"), "lastHeartbeat" : ISODate("2020-12-24T07:37:20.977Z"), "lastHeartbeatRecv" : ISODate("2020-12-24T07:37:21.680Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "152.136.193.58:17017", "syncSourceHost" : "152.136.193.58:17017", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 1 }, { "_id" : 3, "name" : "152.136.193.58:17019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 99, "optime" : { "ts" : Timestamp(1608795438, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1608795438, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2020-12-24T07:37:18Z"), "optimeDurableDate" : ISODate("2020-12-24T07:37:18Z"), "lastHeartbeat" : ISODate("2020-12-24T07:37:20.978Z"), "lastHeartbeatRecv" : ISODate("2020-12-24T07:37:21.674Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "152.136.193.58:17017", "syncSourceHost" : "152.136.193.58:17017", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 1 } ], "ok" : 1, "operationTime" : Timestamp(1608795438, 1), "$gleStats" : { "lastOpTime" : Timestamp(1608795342, 1), "electionId" : ObjectId("7fffffff0000000000000001") }, "$clusterTime" : { "clusterTime" : Timestamp(1608795438, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } } } configsvr:PRIMARY>
以上配置節點完成
[root@VM_0_4_centos shard1]# mkdir shard1-37017 shard1-37018 shard1-37019
[root@VM_0_4_centos shard1]# mkdir logs
[root@VM_0_4_centos shard1]# vi shard1_37017.conf
[root@VM_0_4_centos shard1]# cp shard1_37017.conf shard1_37018.conf
[root@VM_0_4_centos shard1]# cp shard1_37018.conf shard1_37019.conf
shard1集羣搭建37017到37019
dbpath=shard/shard1/shard1-37017 bind_ip=0.0.0.0 port=37017 fork=true logpath=shard/shard1/shard1-37017.log replSet=shard1 shardsvr=true
dbpath=shard/shard1/shard1-37018 bind_ip=0.0.0.0 port=37018 fork=true logpath=shard/shard1/logs/shard1-37018.log replSet=shard1 shardsvr=true
dbpath=shard/shard1/shard1-37019 bind_ip=0.0.0.0 port=37019 fork=true logpath=shard/shard1/logs/shard1-37019.log replSet=shard1 shardsvr=true
啓動每一個mongod 而後進入其中一個進行集羣配置(以前若是搭建過複製集replica_sets 請先停掉)
var cfg ={"_id":"shard1", "protocolVersion" : 1, "members":[ {"_id":1,"host":"152.136.193.58:37017"}, {"_id":2,"host":"152.136.193.58:37018"}, {"_id":3,"host":"152.136.193.58:37019"} ] }; rs.initiate(cfg) rs.status()
shard1搭建完成
dbpath=shard/shard2/shard2-47017 bind_ip=0.0.0.0 port=47017 fork=true logpath=shard/shard2/logs/shard2-47017.log replSet=shard2 shardsvr=true dbpath=shard/shard2/shard2-47018 bind_ip=0.0.0.0 port=47018 fork=true logpath=shard/shard2/logs/shard2-47018.log replSet=shard2 shardsvr=true dbpath=shard/shard2/shard2-47019 bind_ip=0.0.0.0 port=47019 fork=true logpath=shard/shard2/logs/shard2-47019.log replSet=shard2 shardsvr=true
var cfg ={"_id":"shard2", "protocolVersion" : 1, "members":[ {"_id":1,"host":"152.136.193.58:47017"}, {"_id":2,"host":"152.136.193.58:47018"}, {"_id":3,"host":"152.136.193.58:47019"} ] }; rs.initiate(cfg) rs.status()
實操過程 ,參照shard1 過程
route-27017.conf
port=27017 bind_ip=0.0.0.0 fork=true logpath=route/logs/route.log configdb=configsvr/192.168.211.133:17017,192.168.211.133:17018,192.168.211.133:1 7019
啓動路由節點使用 mongos (注意不是mongod)
./bin/mongos -f route/route-27017.conf
進入路由mongos
mongo --port 27017
sh.status()
sh.addShard("shard1/152.136.193.58:37017,152.136.193.58:37018,152.136.193.58:37019");
sh.addShard("shard2/152.136.193.58:47017,152.136.193.58:47018,152.136.193.58:47019");
sh.status()
繼續使用mongos完成分片開啓和分片大小設置(路由節點)
爲數據庫開啓分片功能 sh.enableSharding("wg_test") 爲指定集合開啓分片功能.使用 hash 分片 sh.shardCollection("wg_test.t_datas",{"name":"hashed"})
經過路由循環向集合中添加數
use wg_test; for(var i=1;i<= 1000;i++){ db.t_datas.insert({"name":"test"+i, salary:(Math.random()*20000).toFixed(2)}); }
分別進入 shard1 和 shard2 中的數據庫 進行驗證
down...............................................................ao li gei