分片
在Mongodb裏面存在另外一種集羣,就是分片技術,能夠知足MongoDB數據量大量增加的需求。
當MongoDB存儲海量的數據時,一臺機器可能不足以存儲數據,也可能不足以提供可接受的讀寫吞吐量。這時,咱們就能夠經過在多臺機器上分割數據,使得數據庫系統能存儲和處理更多的數據。
爲何使用分片?
1. 複製全部的寫入操做到主節點
2. 延遲的敏感數據會在主節點查詢
3. 單個副本集限制在12個節點
4. 當請求量巨大時會出現內存不足。
5. 本地磁盤不足
6. 垂直擴展價格昂貴
前端
Shard:
用於存儲實際的數據塊,實際生產環境中一個shard server角色可由幾臺機器組個一個relica set承擔,防止主機單點故障
Config Server:
mongod實例,存儲了整個 ClusterMetadata,其中包括 chunk信息。
Query Routers:
前端路由,客戶端由此接入,且讓整個集羣看上去像單一數據庫,前端應用能夠透明使用。node
分片實例:
node1:10.0.0.10 -- 3個Config Server、1個Routers、1個Shard
node2:10.0.0.11 -- 1個Routers、1個Shard
node3:10.0.0.12 -- 1個Shard
注意:在作分片的時候,要避免Shard在同一臺主機上,這樣就沒辦法實現分片。mongodb
node1 配置以下:
三個Shard 的配置文件:數據庫
[root@node1 conf]# ls mongosvr-20000.conf mongosvr-21000.conf mongosvr-22000.conf [root@node1 conf]# vim mongosvr-20000.conf systemLog: destination: file ###日誌存儲位置 path: /mongodb/logs/mongosvr-20000.log logAppend: true storage: ##journal配置 journal: enabled: true ##數據文件存儲位置 dbPath: /mongodb/data/mongosvr-20000 ##是否一個庫一個文件夾 directoryPerDB: true ##數據引擎 engine: wiredTiger ##WT引擎配置 wiredTiger: engineConfig: ##WT最大使用cache(根據服務器實際狀況調節) cacheSizeGB: 10 ##是否將索引也按數據庫名單獨存儲 directoryForIndexes: true ##表壓縮配置 collectionConfig: blockCompressor: zlib ##索引配置 indexConfig: prefixCompression: true processManagement: fork: true # fork and run in background pidFilePath: /mongodb/socket/mongodsvr-20000.pid ##端口配置 net: port: 20000 bindIp: 10.0.0.10 sharding: clusterRole: configsvr # 啓動config服務 [root@node1 ~]# mongod -f /mongodb/conf/mongosvr-20000.conf about to fork child process, waiting until server is ready for connections. forked process: 1934 child process started successfully, parent exiting [root@node1 conf]# netstat -ntplu | grep mongod tcp 0 0 10.0.0.10:20000 0.0.0.0:* LISTEN 1934/mongod tcp 0 0 10.0.0.10:21000 0.0.0.0:* LISTEN 1960/mongod tcp 0 0 10.0.0.10:22000 0.0.0.0:* LISTEN 1990/mongod
建立mongos服務vim
[root@node1 conf]# vim mongos-30000.conf systemLog: destination: file ###日誌存儲位置 path: /mongodb/logs/mongos-30000.log logAppend: true processManagement: fork: true # fork and run in background pidFilePath: /mongodb/socket/mongos-30000.pid ##端口配置 net: port: 30000 bindIp: 10.0.0.10 ## 將confige server 添加到路由 sharding: configDB: 10.0.0.10:20000,10.0.0.10:21000,10.0.0.10:22000
啓動路由服務服務器
[root@node1 conf]# mongos -f /mongodb/conf/mongos-30000.conf about to fork child process, waiting until server is ready for connections. forked process: 2022 child process started successfully, parent exiting [root@node1 conf]# netstat -ntplu | grep mongos tcp 0 0 10.0.0.10:30000 0.0.0.0:* LISTEN 2022/mongos
在開啓一個Shard服務socket
配置: [root@node1 conf]# ls mongod-40000.conf mongos-30000.conf mongosvr-20000.conf mongosvr-21000.conf mongosvr-22000.conf [root@node1 conf]# vim mongod-40000.conf systemLog: destination: file ###日誌存儲位置 path: /mongodb/logs/mongod-40000.log logAppend: true storage: ##journal配置 journal: enabled: true ##數據文件存儲位置 dbPath: /mongodb/data/mongod-40000 ##是否一個庫一個文件夾 directoryPerDB: true ##數據引擎 engine: wiredTiger ##WT引擎配置 wiredTiger: engineConfig: ##WT最大使用cache(根據服務器實際狀況調節) cacheSizeGB: 10 ##是否將索引也按數據庫名單獨存儲 directoryForIndexes: true ##表壓縮配置 collectionConfig: blockCompressor: zlib ##索引配置 indexConfig: prefixCompression: true processManagement: fork: true # fork and run in background pidFilePath: /mongodb/socket/mongod-40000.pid ##端口配置 net: port: 40000 bindIp: 10.0.0.10 # 啓動Shard服務 [root@node1 conf]# mongod -f /mongodb/conf/mongod-40000.conf about to fork child process, waiting until server is ready for connections. forked process: 2184 child process started successfully, parent exiting
node1 節點服務配置完畢。tcp
node2 配置1個router、1個Shard
node3 配置1個Shard
配置如同node1同樣,這裏不在貼代碼。ui
node1: [root@node1 ~]# netstat -ntplu | grep mongo. tcp 0 0 10.0.0.10:40000 0.0.0.0:* LISTEN 2184/mongod tcp 0 0 10.0.0.10:20000 0.0.0.0:* LISTEN 1934/mongod tcp 0 0 10.0.0.10:21000 0.0.0.0:* LISTEN 1960/mongod tcp 0 0 10.0.0.10:30000 0.0.0.0:* LISTEN 2022/mongos tcp 0 0 10.0.0.10:22000 0.0.0.0:* LISTEN 1990/mongod node2: [root@node2 ~]# netstat -ntplu | grep mongo. tcp 0 0 10.0.0.11:40000 0.0.0.0:* LISTEN 1851/mongod tcp 0 0 10.0.0.11:30000 0.0.0.0:* LISTEN 1923/mongos node3: [root@node3 ~]# netstat -ntplu | grep mongo. tcp 0 0 10.0.0.12:40000 0.0.0.0:* LISTEN 1927/mongod
接下來須要在node1上進行分片的配置:spa
[root@node1 ~]# mongo 10.0.0.10:30000 mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("57b1addb0a3c54686427f812") } shards: # 目前尚未節點加入到分片中 active mongoses: "3.2.8" : 2 balancer: Currently enabled: yes Currently running: no Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: No recent migrations databases: # 添加新的分片 mongos> sh.addShard('10.0.0.10:40000') { "shardAdded" : "shard0000", "ok" : 1 } mongos> sh.addShard('10.0.0.11:40000') { "shardAdded" : "shard0001", "ok" : 1 } mongos> sh.addShard('10.0.0.12:40000') { "shardAdded" : "shard0002", "ok" : 1 } mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("57b1addb0a3c54686427f812") } shards: # 這裏就能夠看到剛纔添加的三個Shard節點 { "_id" : "shard0000", "host" : "10.0.0.10:40000" } { "_id" : "shard0001", "host" : "10.0.0.11:40000" } { "_id" : "shard0002", "host" : "10.0.0.12:40000" } active mongoses: "3.2.8" : 2 balancer: Currently enabled: yes Currently running: no Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: No recent migrations databases:
注意:分片的功能是須要手動開啓才能實現的:sh.enableSharding("庫名")、sh.shardCollection("庫名.集合名",{"key":1})
mongos> sh.enableSharding('testdb') { "ok" : 1 } mongos> sh.shardCollection('testdb.users',{uid:1}) { "collectionsharded" : "testdb.users", "ok" : 1 }
mongos> show dbs config 0.001GB testdb 0.000GB mongos> use testdb switched to db testdb mongos> for(i=1;i<=200000;i++) db.users.insert({uid:i,name:'hukey',age:23}) # 生成20W條數據,而且經過uid來進行分片 WriteResult({ "nInserted" : 1 })
# 分片的規則是自動分裂和平衡。
數據生成完畢,咱們能夠經過node2的router服務登陸上去查看。
mongos> db.users.count() 200000 mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("57b1addb0a3c54686427f812") } shards: { "_id" : "shard0000", "host" : "10.0.0.10:40000" } { "_id" : "shard0001", "host" : "10.0.0.11:40000" } { "_id" : "shard0002", "host" : "10.0.0.12:40000" } active mongoses: "3.2.8" : 2 balancer: Currently enabled: yes Currently running: no Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: 2 : Success databases: { "_id" : "testdb", "primary" : "shard0000", "partitioned" : true } testdb.users shard key: { "uid" : 1 } unique: false balancing: true chunks: # 這裏能夠查看到平均分片到每一個Shard上。 shard0000 1 shard0001 1 shard0002 1 { "uid" : { "$minKey" : 1 } } -->> { "uid" : 2 } on : shard0001 Timestamp(2, 0) { "uid" : 2 } -->> { "uid" : 18 } on : shard0002 Timestamp(3, 0) { "uid" : 18 } -->> { "uid" : { "$maxKey" : 1 } } on : shard0000 Timestamp(3, 1)
mongodb是用來存儲海量數據的,因此20W分片可能不是特別明顯,能夠每次增長10W條來查看。
chunks: shard0000 3 shard0001 2 shard0002 2 { "uid" : { "$minKey" : 1 } } -->> { "uid" : 2 } on : shard0001 Timestamp(2, 0) { "uid" : 2 } -->> { "uid" : 18 } on : shard0002 Timestamp(3, 0) { "uid" : 18 } -->> { "uid" : 26232 } on : shard0002 Timestamp(5, 0) { "uid" : 26232 } -->> { "uid" : 59000 } on : shard0000 Timestamp(5, 1) { "uid" : 59000 } -->> { "uid" : 65554 } on : shard0000 Timestamp(4, 4) { "uid" : 65554 } -->> { "uid" : 200000 } on : shard0000 Timestamp(3, 3) { "uid" : 200000 } -->> { "uid" : { "$maxKey" : 1 } } on : shard0001 Timestamp(4, 0)
這樣,就很明顯了。分片集羣搭建完畢,可是目前全部節點都是單點,一旦故障就形成很嚴重的後果,所以須要將分片和副本集聯合起來用,才能實現高可用。