Mongodb分片概括
分片在多臺服務器上分布數據的方法, Mongodb使用分片來支持具有非常大的數據集和高吞吐量的操作的部署
具有大數據集和高吞吐量應用程序的數據庫系統,可以挑戰單臺服務器的容量。
例如,高查詢率可以耗盡服務器的cpu容量,工作集大小大于系統的RAM強制磁盤驅動器的I/O容量,-
有兩種方法來解決系統增長:垂直和水平縮放。
垂直縮放 涉及增加的單個服務器的容量,例如使用更強大的CPU,加入更多的RAM,或增加的存儲空間量。可用技術中的限制可能限制單個機器對于給定工作負載足夠強大。此外,基于云的提供商具有基于可用硬件配置的硬上限。因此,對于垂直縮放存在實際的最大值。
包括將系統數據和負載在多個服務器,添加額外的服務器,需要增加容量。雖然單個機器的總速度或容量可能不高,但是每個機器處理整個工作負載的子集,潛在地提供比單個高速大容量服務器更好的效率。擴展部署的容量僅需要根據需要添加額外的服務器,這可以是比單個機器的高端硬件低的總體成本。權衡是基礎設施的復雜性和部署的維護。
Mongodb的支持水平擴展,分片。
1、分片目的
對于單臺數據庫服務器,龐大的數據量及高吞吐量的應用程序對它而言無疑是個巨大的挑戰。頻繁的CRUD操作能夠耗盡服務器的CPU資源,快速的數據增長也會讓硬盤存儲無能為力,最終內存無法滿足數據需要導致大量的I/O,主機負載嚴重。為了解決這種問題,對于數據庫系統一般有兩種方法:垂直擴展和分片(水平擴展)。
【垂直擴展】:添加更多的CPU和存儲資源來增加系統性能。這種方式缺點是:擁有大量CPU和RAM資源的高端機器比普通PC機器昂貴得太多,而且單點故障會影響整個系統的服務。
【分片】:相反地,分片將大的數據集分配到多臺主機上,每個分片是一個獨立的數據庫,這些分片整體上構成一個完整的邏輯數據庫。分片減少了每臺服務器上的數據操作量,隨著集群的增長,每臺分片處理越來越少的數據,結果,增加了系統整體服務能力。另外,分片還減少了每臺服務器需要存儲的數據量。
2、MongoDB中的分片
MongoDB通過配置分片集群來支持分片,一個分片集群包括以下幾個組件:分片,查詢路由,配置服務器
- 分片:用來存儲數據,為了提供系統可用性和數據一致性,一個生產環境的分片集群,通常每個分片是一個副本集。
- 查詢路由:指客戶端應用訪問每個分片的路徑。
- 配置服務器:存儲集群的元數據,這些數據包含了集群數據集到各分片的映射關系。查詢路由就是通過這些元數據到特定的分片上執行指定的數據操作。(從v3.2開始,配置服務器也可以作為副本集,但是必須使用WiredTiger存儲引擎,反對使用3個鏡像實例作為配置服務器)
數據劃分
MongoDB的數據劃分,是以集合級別為標準。分片通過shard key來劃分集合數據。
- shard key:
為了對集合分片,你需要指定一個shard key。shard key既可以是集合的每個文檔的索引字段也可以是集合中每個文檔都有的組合索引字段。MongoDB將shard keys值按照塊(chunks)劃分,并且均勻的將這些chunks分配到各個分片上。MongoDB使用基于范圍劃分或基于散列劃分來劃分chunks的。
- 基于范圍劃分:
MongoDB通過shard key值將數據集劃分到不同的范圍就稱為基于范圍劃分。對于數值型的shard key:你可以虛構一條從負無窮到正無窮的直線(理解為x軸),每個shard key 值都落在這條直線的某個點上,然后MongoDB把這條線劃分為許多更小的沒有重復的范圍成為塊(chunks),一個chunk就是就某些最小值到最大值的范圍。
- 基于散列劃分:
MongoDB計算每個字段的hash值,然后用這些hash值建立chunks。
- 基于范圍和基于散列劃分的性能比較:
基于范圍劃分對于范圍查詢比較高效。假設在shard key上進行范圍查詢,查詢路由很容易能夠知道哪些塊與這個范圍重疊,然后把相關查詢按照這個路線發送到僅僅包含這些chunks的分片。但是基于范圍劃分很容易導致數據不均勻分布,這樣會削弱分片集群的功能。例如當shard key是個成直線上升的字段,如時間。那么,所有在給定時間范圍內的請求都會映射到相同的chunk,也就是相同的分片上。這種情況下,小部分的分片將會承受大多數的請求,那么系統整體擴展并不理想。
相反的,基于散列劃分是以犧牲高效范圍查詢為代價,它能夠均勻的分布數據,散列值能夠保證數據隨機分布到各個分片上。
- 使用標簽來自定義數據分布
MongoDB允許DBA們通過標簽標記分片的方式直接平衡數據分布策略,DBA可以創建標簽并且將它們與shard key值的范圍進行關聯,然后分配這些標簽到各個分片上,最終平衡器轉移帶有標簽標記的數據到對應的分片上,確保集群總是按標簽描述的那樣進行數據分布。標簽是控制平衡器行為及集群中塊分布的主要方法
4、維持數據分布平衡
新加入的數據及服務器都會導致集群數據分布不平衡,MongoDB采用兩種方式確保數據分布的平衡:
- 拆分
拆分是一個后臺進程,防止塊變得太大。當一個塊增長到指定塊大小的時候,拆分進程就會塊一分為二,整個拆分過程是高效的。不會涉及到數據的遷移等操作。
- 平衡
平衡器是一個后臺進程,管理塊的遷移。平衡器能夠運行在集群任何的mongd實例上。當集群中數據分布不均勻時,平衡器就會將某個分片中比較多的塊遷移到擁有塊較少的分片中,直到數據分片平衡為止。舉個例子:如果集合users有100個塊在分片1里,50個塊在分片2中,那么平衡器就會將分片1中的塊遷移到分片2中,直到維持平衡。
分片采用后臺操作的方式管理著源分片和目標分片之間塊的遷移。在遷移的過程中,源分片中的塊會將所有文檔發送到目標分片中,然后目標分片會獲取并應用這些變化。最后,更新配置服務器上關于塊位置元數據。
- 從集群中增加和刪除分片
添加新分片到集群中會產生數據不平衡,因為新分片中沒有塊,當MongoDB開始遷移數據到新分片中時,等到數據分片平衡恐怕需要點時間。
當刪除一個分片時,平衡器將會把分片中所有塊遷移到另一個分片中,在完成這些遷移并更新元數據后,你就可以安全的刪除分片了。
分片集群
-
一個mongodb分片集群由以下幾部分組成
12.jpg
-
shard
每個shard包含分片數據的子集,每個shard可以部署一個副本集
一臺機器的一個數據表 Collection1 存儲了 1T 數據,壓力太大了!在分給4個機器后,每個機器都是256G,則分攤了集中在一臺機器的壓力。也許有人問一臺機器硬盤加大一點不就可以了,為什么要分給四臺機器呢?不要光想到存儲空間,實際運行的數據庫還有硬盤的讀寫、網絡的IO、CPU和內存的瓶頸。在mongodb集群只要設置好了分片規則,通過mongos操作數據庫就能自動把對應的數據操作請求轉發到對應的分片機器上。在生產環境中分片的片鍵可要好好設置,這個影響到了怎么把數據均勻分到多個分片機器上,不要出現其中一臺機器分了1T,其他機器沒有分到的情況,這樣還不如不分片!
-
mongos
MongoS充當一個查詢的路由器,提供客戶端應用程序和所述分片簇之間的接口,mongos作為數據庫集群請求的入口,所有的請求都是通過mongos來進行協調的,不需要在應用程序添加一個路由選擇器,mongos自己就是一個請求分發中心,它負責把對應的數據請求轉發到對應的shard服務器上,在生產環境中通常有多個monogs作為請求的入口,防止其中一個掛掉所有mongos請求都沒有辦法操作 -
config servers
為集群配置的服務器存儲元數據和配置設置,從Mongodb3.4開始,配置服務器必須部署為復制集,mongos本身沒有物理存儲分片服務器和數據路由信息,只是緩存在內存當中,配置服務器則實際存儲這些數據,mongos第一次啟動或者關掉重啟會從configserver中加載配置信息,以后如果配置信息有變化會通過所有的mongos更新自己的狀態,這樣mongs就能繼續準確路由,在生產環境中通常有多個config server配置服務器,因為它存儲了分片路由的元數據,如果就一個如果掛掉一個,整個mongodb基礎就會掛掉。
片鍵
-
片鍵
1、在分發集合中文件時,mongodb的分區使用的收集片鍵關鍵,在片鍵由存在目標集合中的每個文檔中的一個不可變或多個字段
2、在分割集合的時候選擇片鍵,<font color=red size=4>分片鍵完成之后是不能更改的</font>,分片集合只能有1個片鍵,到片鍵的非空集合,集合必須有一個索引,與片鍵啟動,對于空空集合,如果集合尚未具有指定分片鍵的相關索引,則Mongodb會創建索引
3、分片鍵的選擇會影響分片集群的性能和效率以及可伸縮性,具有最佳可能的硬件可以通過分片達到瓶頸,片鍵和其支持指數的選擇也可以影響數據的拆分,但集群可以使用
4、片鍵決定了集群中一個集合的文件咋不同的片鍵中的分布,片鍵字段必須被索引,且在集合中的每條記錄都不能為空,可以是單個字段或者是復合字段
5、Mongodb使用片鍵的范圍是吧數據分布在分片中,每個范圍,又稱為數據塊,定義了一個不重疊的片鍵范圍Mongodb把數據塊與他們存儲的文檔分布到集群中的不同分布中,當一個數據塊的大小超過數據塊最大大小的時候,Mongodb會宜聚片鍵的范圍將數據塊分裂為更小的數據塊
14.png
- 片鍵的使用語法
1、在分片集合,必須制定目標集合和片鍵的sh.shardCollection()
sh.shardCollection(namespace, key)
2、哈希片鍵使用單字段的哈希索引進行數據在分片之間的平均分發,除數取余
和一致性哈希
3、被選為片鍵的字段必須有足夠大的基數,或者有足夠多的不同的值,對于單調的遞增的字段如果ObjectID
或是時間戳,哈希索引效果更好
4、如果在一個空集合創建哈希片鍵,Mongodb會自動創建并遷移數據塊,以保證每個分片上都有兩個數據塊,也可以執行shardCollection
指定numInitialChunks
參數以控制初始化時Mongodb創建數據塊數目,或者手動調用split
命令在分片上分裂數據塊
5、對使用了哈希片鍵分片的集合進行請求時,Mongodb會自動計算哈希值,應用不需要解析哈希值
shard集群部署
- 部署ip規劃
172.17.237.33:30001 config1
172.17.237.34:30002 config2
172.17.237.36:30003 config3
172.17.237.37:40000 mongos
172.17.237.38:50000 shard1
172.17.237.39:50001 shard2
172.17.237.40:50002 shard3
172.17.237.41:60000 sha1
172.17.237.42:60001 sha2
172.17.237.43:60002 sha3
配置config server 副本集
- 配置confi1配置文件
[root@My-Dev db2]# vim config1.conf
[root@My-Dev db1]# vim configsvr.conf
logpath=/home/mongodb/test/db1/log/db1.log
pidfilepath=/home/mongodb/test/db1/db1.pid
logappend=true
port=30000
fork=true
dbpath=/home/mongodb/test/db1/data
configsvr=true # 在配置文件添加此項就行
oplogSize=512
replSet=config
- 配置confi2配置文件
[root@My-Dev db2]# vim config2.conf
logpath=/home/mongodb/test/db2/log/db2.log
pidfilepath=/home/mongodb/test/db2/db2.pid
logappend=true
port=30001
fork=true
dbpath=/home/mongodb/test/db2/data
oplogSize=512
replSet=config
configsvr=true
- 配置confi3配置文件
[root@My-Dev db2]# vim config3.conf
logpath=/home/mongodb/test/db3/log/db3.log
pidfilepath=/home/mongodb/test/db3/db3.pid
logappend=true
port=30002
fork=true
dbpath=/home/mongodb/test/db3/data
oplogSize=512
replSet=config
configsvr=true
- 啟動config server
[root@My-Dev bin]# ./mongod -f /home/mongodb/test/db1/config1.conf
about to fork child process, waiting until server is ready for connections.
forked process: 5260
child process started successfully, parent exiting
[root@My-Dev bin]# ./mongod -f /home/mongodb/test/db2/config2.conf
about to fork child process, waiting until server is ready for connections.
forked process: 5202
child process started successfully, parent exiting
[root@My-Dev bin]# ./mongod -f /home/mongodb/test/db3/config3.conf
about to fork child process, waiting until server is ready for connections.
forked process: 4260
child process started successfully, parent exiting
- 配置config副本集
> use admin
switched to db admin
> config = { _id:"config",members:[ {_id:0,host:"conf1:30000"}, {_id:1,host:"conf2:30001"}, {_id:2,host:"conf3:30002"}] } #定義副本集
{
"_id" : "config",
"members" : [
{
"_id" : 0,
"host" : "conf1:30000"
},
{
"_id" : 1,
"host" : "conf2:30001"
},
{
"_id" : 2,
"host" : "conf3:30002"
}
]
}
> rs.initiate(config) #初始化副本集
{ "ok" : 1 }
配置mongos
- 添加配置mongos配置文件
遇到坑了,在啟動mongos的時候啟動失敗,結果是mongodb3.0以后的版本config server
必須是復制集才行,結果我的版本是3.4最新的版本,所以說還需要添加兩臺confi server
[root@My-Dev db4]# vim mongos.conf
logpath=/home/mongodb/test/db4/log/db4.log
pidfilepath=/home/mongodb/test/db4/db4.pid
logappend=true
port=40004
fork=true
configdb=mongos/172.17.237.33:30000,172.17.237.34:30001,172.17.237.36:30002 #如果有多個mongo confi的話就用逗號分隔開
- 啟動mongos
[root@My-Dev bin]# ./mongos -f /home/mongodb/test/db4/mongos.conf
about to fork child process, waiting until server is ready for connections.
forked process: 6268
child process started successfully, parent exiting
shard2副本集集群部署
- 配置sha配置文件
[root@My-Dev db8]# more shard21.conf
logpath=/home/mongodb/test/db8/log/db8.log
pidfilepath=/home/mongodb/test/db8/db8.pid
directoryperdb=true
logappend=true
port=60000
fork=true
dbpath=/home/mongodb/test/db8/data
oplogSize=512
replSet=sha
shardsvr=true
[root@My-Dev db9]# more shard22.conf
logpath=/home/mongodb/test/db9/log/db9.log
pidfilepath=/home/mongodb/test/db9/db9.pid
directoryperdb=true
logappend=true
port=60001
fork=true
dbpath=/home/mongodb/test/db9/data
oplogSize=512
replSet=sha
shardsvr=true
[root@My-Dev db10]# more shard23.conf
logpath=/home/mongodb/test/db10/log/db10.log
pidfilepath=/home/mongodb/test/db10/db10.pid
directoryperdb=true
logappend=true
port=60002
fork=true
dbpath=/home/mongodb/test/db10/data
oplogSize=512
replSet=sha
shardsvr=true
- 啟動shard
[root@My-Dev bin]# ./mongod -f /home/mongodb/test/db8/shard21.conf
[root@My-Dev bin]# ./mongod -f /home/mongodb/test/db9/shard22.conf
[root@My-Dev bin]# ./mongod -f /home/mongodb/test/db10/shard23.conf
- 配置shard2副本集集群
> use admin
switched to db admin
> sha = { _id:"sha",members:[ {_id:0,host:"sha1:60000"}, {_id:1,host:"sha2:60001"}, {_id:2,host:"sha3:60002"}]}
{
"_id" : "sha",
"members" : [
{
"_id" : 0,
"host" : "sha1:60000"
},
{
"_id" : 1,
"host" : "sha2:60001"
},
{
"_id" : 2,
"host" : "sha3:60002"
}
]
}
> rs.initiate(sha)
{ "ok" : 1 }
shard1副本集集群部署
- 配置shard配置文件
[root@My-Dev db5]# vim shard1.conf
logpath=/home/mongodb/test/db5/log/db5.log
pidfilepath=/home/mongodb/test/db5/db5.pid
directoryperdb=true
logappend=true
port=50000
fork=true
dbpath=/home/mongodb/test/db5/data
oplogSize=512
replSet=shard
shardsvr=true
[root@My-Dev db6]# vim shard2.conf
logpath=/home/mongodb/test/db6/log/db6.log
pidfilepath=/home/mongodb/test/db6/db6.pid
directoryperdb=true
logappend=true
port=50001
fork=true
dbpath=/home/mongodb/test/db6/data
oplogSize=512
replSet=shard
shardsvr=true
[root@My-Dev db7]# vim shard3.conf
logpath=/home/mongodb/test/db7/log/db7.log
pidfilepath=/home/mongodb/test/db7/db7.pid
directoryperdb=true
logappend=true
port=50002
fork=true
dbpath=/home/mongodb/test/db7/data
oplogSize=512
replSet=shard
shardsvr=true
- 啟動shard
[root@My-Dev bin]# ./mongod -f /home/mongodb/test/db7/shard1.conf
[root@My-Dev bin]# ./mongod -f /home/mongodb/test/db7/shard2.conf
[root@My-Dev bin]# ./mongod -f /home/mongodb/test/db7/shard3.conf
- 配置shard2副本集集群
> use admin
switched to db admin
> shard = { _id:"shard",members:[ {_id:0,host:"shard1:50000"}, {_id:1,host:"shard2:50001"}, {_id:2,host:"shard3:50002"}] }
{
"_id" : "shard",
"members" : [
{
"_id" : 0,
"host" : "shard1:50000"
},
{
"_id" : 1,
"host" : "shard2:50001"
},
{
"_id" : 2,
"host" : "shard3:50002"
}
]
}
> rs.initiate(shard)
{ "ok" : 1 }
分片配置
分片集合中是否有數據
默認第一個添加的shard就是主shard,存放沒有被分割的shard就是主shard
在創建分片的時,必須在索引中創建的,如果這個集合中有數據,則首先自己先創建索引,然后進行分片,如果是分片集合中沒有數據的話,則就不需要創建索引,就可以分片登陸mongos配置分片,向分區集群中添加shard服務器和副本集
[root@My-Dev bin]# ./mongo mongos:40004 #登陸到mongos中
mongos> sh.status() #查看分片狀態
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("589b0cff36b0915841e2a0a2")
}
shards:
active mongoses:
"3.4.1" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Balancer lock taken at Wed Feb 08 2017 20:20:16 GMT+0800 (CST) by ConfigServer:Balancer
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
- 添加shard副本集
#首先要登陸到shard副本集中查看那個是主節點,本次實驗室使用了兩個shard副本集 sh.addShard("<replSetName>/主節點IP/port")
mongos> sh.addShard("shard/shard1:50000")
{ "shardAdded" : "shard", "ok" : 1 }
mongos> sh.addShard("sha/sha:60000")
{ "shardAdded" : "shard", "ok" : 1 }
mongos> sh.status() #查看分片集群已經成功把shard加入分片中
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("589b0cff36b0915841e2a0a2")
}
shards:
{ "_id" : "sha", "host" : "sha/sha1:60000,sha2:60001,sha3:60002", "state" : 1 }
{ "_id" : "shard", "host" : "shard/shard1:50000,shard2:50001,shard3:50002", "state" : 1 }
active mongoses:
"3.4.1" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Balancer lock taken at Wed Feb 08 2017 20:20:16 GMT+0800 (CST) by ConfigServer:Balancer
Failed balancer rounds in last 5 attempts: 5
Last reported error: Cannot accept sharding commands if not started with --shardsvr
Time of Reported error: Thu Feb 09 2017 17:42:21 GMT+0800 (CST)
Migration Results for the last 24 hours:
No recent migrations
databa
- 指定那個數據庫使用分片,創建片鍵
mongos> sh.enableSharding("zhao") #指定zhao數據庫中使用分片
{ "ok" : 1 }
mongos> sh.shardCollection("zhao.call",{name:1,age:1}) #在zhao數據庫和call集合中創建了name和age為升序的片鍵
{ "collectionsharded" : "zhao.call", "ok" : 1 }
- 查看
sh.status()
信息
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("589b0cff36b0915841e2a0a2")
}
shards:
{ "_id" : "sha", "host" : "sha/sha1:60000,sha2:60001,sha3:60002", "state" : 1 }
{ "_id" : "shard", "host" : "shard/shard1:50000,shard2:50001,shard3:50002", "state" : 1 }
active mongoses:
"3.4.1" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Balancer lock taken at Wed Feb 08 2017 20:20:16 GMT+0800 (CST) by ConfigServer:Balancer
Failed balancer rounds in last 5 attempts: 5
Last reported error: Cannot accept sharding commands if not started with --shardsvr
Time of Reported error: Thu Feb 09 2017 17:56:02 GMT+0800 (CST)
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "zhao", "primary" : "shard", "partitioned" : true }
zhao.call
shard key: { "name" : 1, "age" : 1 }
unique: false
balancing: true
chunks:
shard 1
{ "name" : { "$minKey" : 1 }, "age" : { "$minKey" : 1 } } -->> { "name" : { "$maxKey" : 1 }, "age" : { "$maxKey" : 1 } } on : shard Timestamp(1, 0)
- 測試批量插入數據驗證
mongos> for ( var i=1;i<10000000;i++){db.call.insert({"name":"user"+i,age:i})};
- 查看當前是否已經分片到兩個shard中去了
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("589b0cff36b0915841e2a0a2")
}
shards:
{ "_id" : "sha", "host" : "sha/sha1:60000,sha2:60001,sha3:60002", "state" : 1 }
{ "_id" : "shard", "host" : "shard/shard1:50000,shard2:50001,shard3:50002", "state" : 1 }
active mongoses:
"3.4.1" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: no
Balancer lock taken at Wed Feb 08 2017 20:20:16 GMT+0800 (CST) by ConfigServer:Balancer
Failed balancer rounds in last 5 attempts: 5
Last reported error: Cannot accept sharding commands if not started with --shardsvr
Time of Reported error: Thu Feb 09 2017 17:56:02 GMT+0800 (CST)
Migration Results for the last 24 hours:
4 : Success
databases:
{ "_id" : "zhao", "primary" : "shard", "partitioned" : true }
zhao.call
shard key: { "name" : 1, "age" : 1 }
unique: false
balancing: true
chunks: #數據已經分片到兩個chunks里面了
sha 4
shard 5
{ "name" : { "$minKey" : 1 }, "age" : { "$minKey" : 1 } } -->> { "name" : "user1", "age" : 1 } on : sha Timestamp(4, 1)
{ "name" : "user1", "age" : 1 } -->> { "name" : "user1", "age" : 21 } on : shard Timestamp(5, 1)
{ "name" : "user1", "age" : 21 } -->> { "name" : "user1", "age" : 164503 } on : shard Timestamp(2, 2)
{ "name" : "user1", "age" : 164503 } -->> { "name" : "user1", "age" : 355309 } on : shard Timestamp(2, 3)
{ "name" : "user1", "age" : 355309 } -->> { "name" : "user1", "age" : 523081 } on : sha Timestamp(3, 2)
{ "name" : "user1", "age" : 523081 } -->> { "name" : "user1", "age" : 710594 } on : sha Timestamp(3, 3)
{ "name" : "user1", "age" : 710594 } -->> { "name" : "user1", "age" : 875076 } on : shard Timestamp(4, 2)
{ "name" : "user1", "age" : 875076 } -->> { "name" : "user1", "age" : 1056645 } on : shard Timestamp(4, 3)
{ "name" : "user1", "age" : 1056645 } -->> { "name" : { "$maxKey" : 1 }, "age" : { "$maxKey" : 1 } } on : sha Timestamp(5, 0)
- 查看當前分片中是否均勻的分配到連個shard當中,
true
是均勻的
,false
不是均勻的
mongos> sh.getBalancerState()
true
選擇sharing kes'
注意點
- 考慮應該在哪里儲存數據?
- 應該在哪里讀取數據?
- sharding key 應該是主鍵
- sharding key 應該你能盡量保證避免分片查詢
sharing 進級
- 如果sharing 分片不均勻沒有分片均勻
- sharding : 新增
shard
和移除shard
mongos> sh.addShard("sha4/192.168.2.10:21001")
Balancer
- 開啟Balncer
開啟Balancer之后,chunks之后會自動均分
mongos> sh.startBalancer()
- 設置Balancer進程運行時間窗口
默認情況ixaBalancing進程在運行時為降低Balancing進程對系統的影響,可以設置Balancer進程的運行時間窗口,讓Balancer進程在指定時間窗口操作
#設置時間窗口
db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "23:00", stop : "6:00" } } }, true )
- 查看Balancer運行時間窗口
# 查看Balancer時間窗口
mongos> db.settings.find();
{ "_id" : "balancer", "activeWindow" : { "start" : "23:00", "stop" : "6:00" }, "stopped" : false }
mongos> sh.getBalancerWindow()
{ "start" : "23:00", "stop" : "6:00" }
- 刪除Balancer進程運行時間窗口
mongos> db.settings.update({ "_id" : "balancer" }, { $unset : { activeWindow : 1 }});
mongos> db.settings.find();
{ "_id" : "chunksize", "value" : 10 }
{ "_id" : "balancer", "stopped" : false }
在shell腳本中執行mongodb
[root@My-Dev ~]# echo -e "use zhao \n db.call.find()" |mongo --port 60001
Mongodb片鍵的添加
- 首先進入mongos的的admin數據庫中
mongos> use admin
switched to db admin
mongos> db.runCommand({"enablesharding":"zl"}) #創建zl庫中
{ "ok" : 1 }
mongos> db.runCommand(db.runCommand({"shardcollection":"$ent.t_srvappraise_back","key")
- 分片腳本
#!/bin/bash
url=10.241.96.155
port=30000
ent=test1
./mongo $url:$port/admin <<EOF
db.runCommand({"enablesharding":"$ent"});
db.runCommand({"shardcollection":"$ent.t_srvappraise_back","key":{"sa_seid":"hashed"}})
exit;
EOF
db.currentOp() 和 db.killOp()
方法說明
-db.currentOp()方法會返回數據庫實例當前操作的信息,是數據庫命令currentOp的封裝。
語法:
db.currentOp( )
operations 是可選項。 可以是boolean 或者 document 類型。 當指定true時,會包含空閑連接和系統操作。當指定查詢條件的filter文檔時,則只返回匹配條件的操作。
db.currentOp()支持的filter文檔有如下3種類型:
“$ownOps”: 布爾型,當設置為true時,只返回當前用戶的操作信息。
“$all”:布爾型,當設置為true時,返回所有操作的信息,包括空閑連接和系統操作。
:根據output fields指定過濾條件。 當”$all”: true 和 output fields 同時存在時,只有”$all”: true生效。
- 查詢正在等待lock的所有寫操作信息
db.currentOp(
{
"waitingForLock" : true,
$or: [
{ "op" : { "$in" : [ "insert", "update", "remove" ] } },
{ "command.findandmodify": { $exists: true } }
]
}
)
- 查詢所有活動但沒有工作(active but no yield)的操作
db.currentOp(
{
"active" : true,
"numYields" : 0,
"waitingForLock" : false
}
)
- 查詢db1 數據庫上所有執行超過3秒的活動會話:
db.currentOp(
{
"active" : true,
"secs_running" : { "$gt" : 3 },
"ns" : /^db1\./
}
)
- 查詢正在創建索引的操作
db.adminCommand(
{
currentOp: true,
$or: [
{ op: "command", "command.createIndexes": { $exists: true } },
{ op: "none", "msg" : /^Index Build/ }
]
}
)
-
db.killOp()
方法 - MongoDB 4.0+ 會自動將kill 操作發送到其他shard 節點和mongos 實例。
- 在mongos 實例上執行聚合管道命令:$currentOp 來查找查詢操作的shard 節點。
use admin
db.aggregate( [
{ $currentOp : { allUsers: true } },
{ $match : { op: "getmore", "command.collection": "someCollection" }}
] )
使用命令行批量進行替換修改操作
- 調整前結果
> db.fastdfs.find()
{ "_id" : ObjectId("65a9e4cb03febb56295304d4"), "fastdfs_url" : "http://1.1.1.1:8099/g10/M00/39/D9/CmQA6WEJ5NGAEtsoAABqUGfXheo386.wav" }
- 詳細命令如下
db.ent_record_fastdfs_url.find({ $or: [{ "fastdfs_url": { $regex: /1.1.1.1/ } }, { "original_url": { $regex: /1.1.1.1/ } }] }).forEach(function(doc) {
db.ent_record_fastdfs_url.update(
{ "_id": doc._id },
{
$set: {
"fastdfs_url": doc.fastdfs_url.replace(/jsdx.ccod.com/g, "2.2.2.2"),
"original_url": doc.original_url.replace(/jsdx.ccod.com/g, "2.2.2.2"),
// Add more fields here if needed
}
}
);
});
- 調整后結果
> db.fastdfs.find()
{ "_id" : ObjectId("65a9e4cb03febb56295304d4"), "fastdfs_url" : "http://2.2.2.2:8099/g10/M00/39/D9/CmQA6WEJ5NGAEtsoAABqUGfXheo386.wav" }