Mongodb分片集群部署

Mongodb分片概括

  • 分片在多臺(tái)服務(wù)器上分布數(shù)據(jù)的方法鲤孵, Mongodb使用分片來支持具有非常大的數(shù)據(jù)集和高吞吐量的操作的部署

  • 具有大數(shù)據(jù)集和高吞吐量應(yīng)用程序的數(shù)據(jù)庫系統(tǒng)钥星,可以挑戰(zhàn)單臺(tái)服務(wù)器的容量桃纯。
    例如,高查詢率可以耗盡服務(wù)器的cpu容量嘶炭,工作集大小大于系統(tǒng)的RAM強(qiáng)制磁盤驅(qū)動(dòng)器的I/O容量挤忙,

  • 有兩種方法來解決系統(tǒng)增長:垂直和水平縮放。

    • 垂直縮放 涉及增加的單個(gè)服務(wù)器的容量酪刀,例如使用更強(qiáng)大的CPU粹舵,加入更多的RAM,或增加的存儲(chǔ)空間量骂倘⊙勐耍可用技術(shù)中的限制可能限制單個(gè)機(jī)器對(duì)于給定工作負(fù)載足夠強(qiáng)大。此外历涝,基于云的提供商具有基于可用硬件配置的硬上限诅需。因此,對(duì)于垂直縮放存在實(shí)際的最大值荧库。

    • 包括將系統(tǒng)數(shù)據(jù)和負(fù)載在多個(gè)服務(wù)器堰塌,添加額外的服務(wù)器,需要增加容量分衫。雖然單個(gè)機(jī)器的總速度或容量可能不高场刑,但是每個(gè)機(jī)器處理整個(gè)工作負(fù)載的子集,潛在地提供比單個(gè)高速大容量服務(wù)器更好的效率丐箩。擴(kuò)展部署的容量僅需要根據(jù)需要添加額外的服務(wù)器摇邦,這可以是比單個(gè)機(jī)器的高端硬件低的總體成本。權(quán)衡是基礎(chǔ)設(shè)施的復(fù)雜性和部署的維護(hù)屎勘。

  • Mongodb的支持水平擴(kuò)展施籍,分片。

1概漱、分片目的

對(duì)于單臺(tái)數(shù)據(jù)庫服務(wù)器丑慎,龐大的數(shù)據(jù)量及高吞吐量的應(yīng)用程序?qū)λ詿o疑是個(gè)巨大的挑戰(zhàn)。頻繁的CRUD操作能夠耗盡服務(wù)器的CPU資源,快速的數(shù)據(jù)增長也會(huì)讓硬盤存儲(chǔ)無能為力竿裂,最終內(nèi)存無法滿足數(shù)據(jù)需要導(dǎo)致大量的I/O玉吁,主機(jī)負(fù)載嚴(yán)重。為了解決這種問題腻异,對(duì)于數(shù)據(jù)庫系統(tǒng)一般有兩種方法:垂直擴(kuò)展分片(水平擴(kuò)展)进副。

【垂直擴(kuò)展】:添加更多的CPU和存儲(chǔ)資源來增加系統(tǒng)性能。這種方式缺點(diǎn)是:擁有大量CPU和RAM資源的高端機(jī)器比普通PC機(jī)器昂貴得太多悔常,而且單點(diǎn)故障會(huì)影響整個(gè)系統(tǒng)的服務(wù)影斑。

【分片】:相反地,分片將大的數(shù)據(jù)集分配到多臺(tái)主機(jī)上机打,每個(gè)分片是一個(gè)獨(dú)立的數(shù)據(jù)庫矫户,這些分片整體上構(gòu)成一個(gè)完整的邏輯數(shù)據(jù)庫。分片減少了每臺(tái)服務(wù)器上的數(shù)據(jù)操作量残邀,隨著集群的增長皆辽,每臺(tái)分片處理越來越少的數(shù)據(jù),結(jié)果芥挣,增加了系統(tǒng)整體服務(wù)能力驱闷。另外,分片還減少了每臺(tái)服務(wù)器需要存儲(chǔ)的數(shù)據(jù)量九秀。

2遗嗽、MongoDB中的分片

MongoDB通過配置分片集群來支持分片,一個(gè)分片集群包括以下幾個(gè)組件:分片鼓蜒,查詢路由,配置服務(wù)器

  • 分片:用來存儲(chǔ)數(shù)據(jù)征字,為了提供系統(tǒng)可用性和數(shù)據(jù)一致性都弹,一個(gè)生產(chǎn)環(huán)境的分片集群,通常每個(gè)分片是一個(gè)副本集匙姜。
  • 查詢路由:指客戶端應(yīng)用訪問每個(gè)分片的路徑畅厢。
  • 配置服務(wù)器:存儲(chǔ)集群的元數(shù)據(jù),這些數(shù)據(jù)包含了集群數(shù)據(jù)集到各分片的映射關(guān)系氮昧。查詢路由就是通過這些元數(shù)據(jù)到特定的分片上執(zhí)行指定的數(shù)據(jù)操作框杜。(從v3.2開始,配置服務(wù)器也可以作為副本集袖肥,但是必須使用WiredTiger存儲(chǔ)引擎咪辱,反對(duì)使用3個(gè)鏡像實(shí)例作為配置服務(wù)器)
數(shù)據(jù)劃分

MongoDB的數(shù)據(jù)劃分,是以集合級(jí)別為標(biāo)準(zhǔn)椎组。分片通過shard key來劃分集合數(shù)據(jù)油狂。

  • shard key:

為了對(duì)集合分片,你需要指定一個(gè)shard key。shard key既可以是集合的每個(gè)文檔的索引字段也可以是集合中每個(gè)文檔都有的組合索引字段专筷。MongoDB將shard keys值按照塊(chunks)劃分弱贼,并且均勻的將這些chunks分配到各個(gè)分片上。MongoDB使用基于范圍劃分基于散列劃分來劃分chunks的磷蛹。

  • 基于范圍劃分

MongoDB通過shard key值將數(shù)據(jù)集劃分到不同的范圍就稱為基于范圍劃分吮旅。對(duì)于數(shù)值型的shard key:你可以虛構(gòu)一條從負(fù)無窮到正無窮的直線(理解為x軸),每個(gè)shard key 值都落在這條直線的某個(gè)點(diǎn)上味咳,然后MongoDB把這條線劃分為許多更小的沒有重復(fù)的范圍成為塊(chunks)鸟辅,一個(gè)chunk就是就某些最小值到最大值的范圍。

  • 基于散列劃分:

MongoDB計(jì)算每個(gè)字段的hash值莺葫,然后用這些hash值建立chunks匪凉。

  • 基于范圍和基于散列劃分的性能比較:

基于范圍劃分對(duì)于范圍查詢比較高效。假設(shè)在shard key上進(jìn)行范圍查詢捺檬,查詢路由很容易能夠知道哪些塊與這個(gè)范圍重疊再层,然后把相關(guān)查詢按照這個(gè)路線發(fā)送到僅僅包含這些chunks的分片。但是基于范圍劃分很容易導(dǎo)致數(shù)據(jù)不均勻分布堡纬,這樣會(huì)削弱分片集群的功能聂受。例如當(dāng)shard key是個(gè)成直線上升的字段,如時(shí)間烤镐。那么蛋济,所有在給定時(shí)間范圍內(nèi)的請(qǐng)求都會(huì)映射到相同的chunk,也就是相同的分片上炮叶。這種情況下碗旅,小部分的分片將會(huì)承受大多數(shù)的請(qǐng)求,那么系統(tǒng)整體擴(kuò)展并不理想镜悉。

相反的祟辟,基于散列劃分是以犧牲高效范圍查詢?yōu)榇鷥r(jià),它能夠均勻的分布數(shù)據(jù)侣肄,散列值能夠保證數(shù)據(jù)隨機(jī)分布到各個(gè)分片上旧困。

  • 使用標(biāo)簽來自定義數(shù)據(jù)分布

MongoDB允許DBA們通過標(biāo)簽標(biāo)記分片的方式直接平衡數(shù)據(jù)分布策略,DBA可以創(chuàng)建標(biāo)簽并且將它們與shard key值的范圍進(jìn)行關(guān)聯(lián)稼锅,然后分配這些標(biāo)簽到各個(gè)分片上吼具,最終平衡器轉(zhuǎn)移帶有標(biāo)簽標(biāo)記的數(shù)據(jù)到對(duì)應(yīng)的分片上,確保集群總是按標(biāo)簽描述的那樣進(jìn)行數(shù)據(jù)分布矩距。標(biāo)簽是控制平衡器行為及集群中塊分布的主要方法

4拗盒、維持?jǐn)?shù)據(jù)分布平衡

新加入的數(shù)據(jù)及服務(wù)器都會(huì)導(dǎo)致集群數(shù)據(jù)分布不平衡,MongoDB采用兩種方式確保數(shù)據(jù)分布的平衡:

  • 拆分

拆分是一個(gè)后臺(tái)進(jìn)程剩晴,防止塊變得太大锣咒。當(dāng)一個(gè)塊增長到指定塊大小的時(shí)候侵状,拆分進(jìn)程就會(huì)塊一分為二,整個(gè)拆分過程是高效的毅整。不會(huì)涉及到數(shù)據(jù)的遷移等操作趣兄。

  • 平衡

平衡器是一個(gè)后臺(tái)進(jìn)程,管理塊的遷移悼嫉。平衡器能夠運(yùn)行在集群任何的mongd實(shí)例上艇潭。當(dāng)集群中數(shù)據(jù)分布不均勻時(shí),平衡器就會(huì)將某個(gè)分片中比較多的塊遷移到擁有塊較少的分片中戏蔑,直到數(shù)據(jù)分片平衡為止蹋凝。舉個(gè)例子:如果集合users有100個(gè)塊在分片1里,50個(gè)塊在分片2中总棵,那么平衡器就會(huì)將分片1中的塊遷移到分片2中鳍寂,直到維持平衡。

分片采用后臺(tái)操作的方式管理著源分片和目標(biāo)分片之間塊的遷移情龄。在遷移的過程中迄汛,源分片中的塊會(huì)將所有文檔發(fā)送到目標(biāo)分片中,然后目標(biāo)分片會(huì)獲取并應(yīng)用這些變化骤视。最后鞍爱,更新配置服務(wù)器上關(guān)于塊位置元數(shù)據(jù)。

  • 從集群中增加和刪除分片

添加新分片到集群中會(huì)產(chǎn)生數(shù)據(jù)不平衡专酗,因?yàn)樾路制袥]有塊睹逃,當(dāng)MongoDB開始遷移數(shù)據(jù)到新分片中時(shí),等到數(shù)據(jù)分片平衡恐怕需要點(diǎn)時(shí)間祷肯。

當(dāng)刪除一個(gè)分片時(shí)沉填,平衡器將會(huì)把分片中所有塊遷移到另一個(gè)分片中,在完成這些遷移并更新元數(shù)據(jù)后躬柬,你就可以安全的刪除分片了拜轨。

分片集群

  • 一個(gè)mongodb分片集群由以下幾部分組成


    12.jpg
  • shard 每個(gè)shard包含分片數(shù)據(jù)的子集,每個(gè)shard可以部署一個(gè)副本集
    一臺(tái)機(jī)器的一個(gè)數(shù)據(jù)表 Collection1 存儲(chǔ)了 1T 數(shù)據(jù)允青,壓力太大了!在分給4個(gè)機(jī)器后卵沉,每個(gè)機(jī)器都是256G颠锉,則分?jǐn)偭思性谝慌_(tái)機(jī)器的壓力。也許有人問一臺(tái)機(jī)器硬盤加大一點(diǎn)不就可以了史汗,為什么要分給四臺(tái)機(jī)器呢琼掠?不要光想到存儲(chǔ)空間,實(shí)際運(yùn)行的數(shù)據(jù)庫還有硬盤的讀寫停撞、網(wǎng)絡(luò)的IO瓷蛙、CPU和內(nèi)存的瓶頸悼瓮。在mongodb集群只要設(shè)置好了分片規(guī)則,通過mongos操作數(shù)據(jù)庫就能自動(dòng)把對(duì)應(yīng)的數(shù)據(jù)操作請(qǐng)求轉(zhuǎn)發(fā)到對(duì)應(yīng)的分片機(jī)器上艰猬。在生產(chǎn)環(huán)境中分片的片鍵可要好好設(shè)置横堡,這個(gè)影響到了怎么把數(shù)據(jù)均勻分到多個(gè)分片機(jī)器上,不要出現(xiàn)其中一臺(tái)機(jī)器分了1T冠桃,其他機(jī)器沒有分到的情況命贴,這樣還不如不分片!
13.jpg
  • mongos MongoS充當(dāng)一個(gè)查詢的路由器食听,提供客戶端應(yīng)用程序和所述分片簇之間的接口,mongos作為數(shù)據(jù)庫集群請(qǐng)求的入口胸蛛,所有的請(qǐng)求都是通過mongos來進(jìn)行協(xié)調(diào)的,不需要在應(yīng)用程序添加一個(gè)路由選擇器樱报,mongos自己就是一個(gè)請(qǐng)求分發(fā)中心葬项,它負(fù)責(zé)把對(duì)應(yīng)的數(shù)據(jù)請(qǐng)求轉(zhuǎn)發(fā)到對(duì)應(yīng)的shard服務(wù)器上,在生產(chǎn)環(huán)境中通常有多個(gè)monogs作為請(qǐng)求的入口迹蛤,防止其中一個(gè)掛掉所有mongos請(qǐng)求都沒有辦法操作
  • config servers 為集群配置的服務(wù)器存儲(chǔ)元數(shù)據(jù)和配置設(shè)置民珍,從Mongodb3.4開始,配置服務(wù)器必須部署為復(fù)制集笤受,mongos本身沒有物理存儲(chǔ)分片服務(wù)器和數(shù)據(jù)路由信息穷缤,只是緩存在內(nèi)存當(dāng)中,配置服務(wù)器則實(shí)際存儲(chǔ)這些數(shù)據(jù)箩兽,mongos第一次啟動(dòng)或者關(guān)掉重啟會(huì)從configserver中加載配置信息津肛,以后如果配置信息有變化會(huì)通過所有的mongos更新自己的狀態(tài),這樣mongs就能繼續(xù)準(zhǔn)確路由汗贫,在生產(chǎn)環(huán)境中通常有多個(gè)config server配置服務(wù)器身坐,因?yàn)樗鎯?chǔ)了分片路由的元數(shù)據(jù),如果就一個(gè)如果掛掉一個(gè)落包,整個(gè)mongodb基礎(chǔ)就會(huì)掛掉部蛇。
片鍵
  • 片鍵
    1、在分發(fā)集合中文件時(shí)咐蝇,mongodb的分區(qū)使用的收集片鍵關(guān)鍵涯鲁,在片鍵由存在目標(biāo)集合中的每個(gè)文檔中的一個(gè)不可變或多個(gè)字段
    2、在分割集合的時(shí)候選擇片鍵有序,<font color=red size=4>分片鍵完成之后是不能更改的</font>抹腿,分片集合只能有1個(gè)片鍵,到片鍵的非空集合旭寿,集合必須有一個(gè)索引警绩,與片鍵啟動(dòng),對(duì)于空空集合盅称,如果集合尚未具有指定分片鍵的相關(guān)索引肩祥,則Mongodb會(huì)創(chuàng)建索引
    3后室、分片鍵的選擇會(huì)影響分片集群的性能和效率以及可伸縮性,具有最佳可能的硬件可以通過分片達(dá)到瓶頸混狠,片鍵和其支持指數(shù)的選擇也可以影響數(shù)據(jù)的拆分岸霹,但集群可以使用
    4、片鍵決定了集群中一個(gè)集合的文件咋不同的片鍵中的分布檀蹋,片鍵字段必須被索引松申,且在集合中的每條記錄都不能為空,可以是單個(gè)字段或者是復(fù)合字段
    5俯逾、Mongodb使用片鍵的范圍是吧數(shù)據(jù)分布在分片中贸桶,每個(gè)范圍,又稱為數(shù)據(jù)塊桌肴,定義了一個(gè)不重疊的片鍵范圍Mongodb把數(shù)據(jù)塊與他們存儲(chǔ)的文檔分布到集群中的不同分布中皇筛,當(dāng)一個(gè)數(shù)據(jù)塊的大小超過數(shù)據(jù)塊最大大小的時(shí)候,Mongodb會(huì)宜聚片鍵的范圍將數(shù)據(jù)塊分裂為更小的數(shù)據(jù)塊


    14.png
  • 片鍵的使用語法
    1坠七、在分片集合水醋,必須制定目標(biāo)集合和片鍵的sh.shardCollection()
sh.shardCollection(namespace, key)

2、哈希片鍵使用單字段的哈希索引進(jìn)行數(shù)據(jù)在分片之間的平均分發(fā)彪置,除數(shù)取余一致性哈希
3拄踪、被選為片鍵的字段必須有足夠大的基數(shù),或者有足夠多的不同的值拳魁,對(duì)于單調(diào)的遞增的字段如果ObjectID或是時(shí)間戳惶桐,哈希索引效果更好
4、如果在一個(gè)空集合創(chuàng)建哈希片鍵潘懊,Mongodb會(huì)自動(dòng)創(chuàng)建并遷移數(shù)據(jù)塊姚糊,以保證每個(gè)分片上都有兩個(gè)數(shù)據(jù)塊,也可以執(zhí)行shardCollection指定numInitialChunks參數(shù)以控制初始化時(shí)Mongodb創(chuàng)建數(shù)據(jù)塊數(shù)目授舟,或者手動(dòng)調(diào)用split命令在分片上分裂數(shù)據(jù)塊
5救恨、對(duì)使用了哈希片鍵分片的集合進(jìn)行請(qǐng)求時(shí),Mongodb會(huì)自動(dòng)計(jì)算哈希值释树,應(yīng)用不需要解析哈希值

shard集群部署

  • 部署ip規(guī)劃
    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   # 在配置文件添加此項(xiàng)就行
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


  • 啟動(dòng)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配置文件
    遇到坑了肠槽,在啟動(dòng)mongos的時(shí)候啟動(dòng)失敗,結(jié)果是mongodb3.0以后的版本config server必須是復(fù)制集才行奢啥,結(jié)果我的版本是3.4最新的版本署浩,所以說還需要添加兩臺(tái)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   #如果有多個(gè)mongo confi的話就用逗號(hào)分隔開 

  • 啟動(dòng)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


  • 啟動(dòng)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

  • 啟動(dòng)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 }

分片配置
  • 分片集合中是否有數(shù)據(jù)
    默認(rèn)第一個(gè)添加的shard就是主shard,存放沒有被分割的shard就是主shard
    在創(chuàng)建分片的時(shí)扫尺,必須在索引中創(chuàng)建的,如果這個(gè)集合中有數(shù)據(jù)炊汤,則首先自己先創(chuàng)建索引正驻,然后進(jìn)行分片弊攘,如果是分片集合中沒有數(shù)據(jù)的話,則就不需要?jiǎng)?chuàng)建索引姑曙,就可以分片

  • 登陸mongos配置分片襟交,向分區(qū)集群中添加shard服務(wù)器和副本集

[root@My-Dev bin]# ./mongo mongos:40004    #登陸到mongos中

mongos> sh.status()  #查看分片狀態(tài)
--- 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副本集中查看那個(gè)是主節(jié)點(diǎn),本次實(shí)驗(yàn)室使用了兩個(gè)shard副本集 sh.addShard("<replSetName>/主節(jié)點(diǎn)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()  #查看分片集群已經(jīng)成功把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

  • 指定那個(gè)數(shù)據(jù)庫使用分片伤靠,創(chuàng)建片鍵
mongos> sh.enableSharding("zhao")  #指定zhao數(shù)據(jù)庫中使用分片
{ "ok" : 1 }

mongos> sh.shardCollection("zhao.call",{name:1,age:1})   #在zhao數(shù)據(jù)庫和call集合中創(chuàng)建了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) 

  • 測(cè)試批量插入數(shù)據(jù)驗(yàn)證
mongos> for ( var i=1;i<10000000;i++){db.call.insert({"name":"user"+i,age:i})};

  • 查看當(dāng)前是否已經(jīng)分片到兩個(gè)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:   #數(shù)據(jù)已經(jīng)分片到兩個(gè)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) 


  • 查看當(dāng)前分片中是否均勻的分配到連個(gè)shard當(dāng)中,true是均勻的
    捣域,false不是均勻的

mongos> sh.getBalancerState()
true

選擇sharing kes'注意點(diǎn)
  • 考慮應(yīng)該在哪里儲(chǔ)存數(shù)據(jù)?
  • 應(yīng)該在哪里讀取數(shù)據(jù)宴合?
  • sharding key 應(yīng)該是主鍵
  • sharding key 應(yīng)該你能盡量保證避免分片查詢

sharing 進(jìn)級(jí)

  • 如果sharing 分片不均勻沒有分片均勻
  • sharding : 新增shard和移除shard
mongos> sh.addShard("sha4/192.168.2.10:21001")

Balancer
  • 開啟Balncer
    開啟Balancer之后焕梅,chunks之后會(huì)自動(dòng)均分
mongos> sh.startBalancer()

  • 設(shè)置Balancer進(jìn)程運(yùn)行時(shí)間窗口
    默認(rèn)情況ixaBalancing進(jìn)程在運(yùn)行時(shí)為降低Balancing進(jìn)程對(duì)系統(tǒng)的影響,可以設(shè)置Balancer進(jìn)程的運(yùn)行時(shí)間窗口卦洽,讓Balancer進(jìn)程在指定時(shí)間窗口操作
#設(shè)置時(shí)間窗口
db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "23:00", stop : "6:00" } } }, true )

  • 查看Balancer運(yùn)行時(shí)間窗口

# 查看Balancer時(shí)間窗口
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進(jìn)程運(yùn)行時(shí)間窗口
 mongos> db.settings.update({ "_id" : "balancer" }, { $unset : { activeWindow : 1 }});
mongos> db.settings.find();
{ "_id" : "chunksize", "value" : 10 }
{ "_id" : "balancer", "stopped" : false }

在shell腳本中執(zhí)行mongodb
[root@My-Dev ~]# echo  -e "use zhao \n  db.call.find()" |mongo --port 60001 

Mongodb片鍵的添加
  • 首先進(jìn)入mongos的的admin數(shù)據(jù)庫中
mongos> use admin
switched to db admin  
mongos> db.runCommand({"enablesharding":"zl"})   #創(chuàng)建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()方法會(huì)返回?cái)?shù)據(jù)庫實(shí)例當(dāng)前操作的信息贞言,是數(shù)據(jù)庫命令currentOp的封裝。

語法:
db.currentOp( )

operations 是可選項(xiàng)阀蒂。 可以是boolean 或者 document 類型该窗。 當(dāng)指定true時(shí),會(huì)包含空閑連接和系統(tǒng)操作蚤霞。當(dāng)指定查詢條件的filter文檔時(shí)酗失,則只返回匹配條件的操作。

db.currentOp()支持的filter文檔有如下3種類型:
“$ownOps”: 布爾型昧绣,當(dāng)設(shè)置為true時(shí)规肴,只返回當(dāng)前用戶的操作信息。
“$all”:布爾型滞乙,當(dāng)設(shè)置為true時(shí)奏纪,返回所有操作的信息,包括空閑連接和系統(tǒng)操作斩启。
:根據(jù)output fields指定過濾條件序调。 當(dāng)”$all”: true 和 output fields 同時(shí)存在時(shí),只有”$all”: true生效兔簇。 
  • 查詢正在等待lock的所有寫操作信息
db.currentOp(
   {
     "waitingForLock" : true,
     $or: [
        { "op" : { "$in" : [ "insert", "update", "remove" ] } },
        { "command.findandmodify": { $exists: true } }
    ]
   }
)
  • 查詢所有活動(dòng)但沒有工作(active but no yield)的操作
db.currentOp(
   {
     "active" : true,
     "numYields" : 0,
     "waitingForLock" : false
   }
)
  • 查詢db1 數(shù)據(jù)庫上所有執(zhí)行超過3秒的活動(dòng)會(huì)話:
db.currentOp(
   {
     "active" : true,
     "secs_running" : { "$gt" : 3 },
     "ns" : /^db1\./
   }
)
  • 查詢正在創(chuàng)建索引的操作
db.adminCommand(
    {
      currentOp: true,
      $or: [
        { op: "command", "command.createIndexes": { $exists: true }  },
        { op: "none", "msg" : /^Index Build/ }
      ]
    }
)
  • db.killOp()方法
  • MongoDB 4.0+ 會(huì)自動(dòng)將kill 操作發(fā)送到其他shard 節(jié)點(diǎn)和mongos 實(shí)例发绢。
  • 在mongos 實(shí)例上執(zhí)行聚合管道命令:$currentOp 來查找查詢操作的shard 節(jié)點(diǎn)。
use admin
db.aggregate( [
{ $currentOp : { allUsers: true } },
{ $match : { op: "getmore", "command.collection": "someCollection" }}
] )

使用命令行批量進(jìn)行替換修改操作

  • 調(diào)整前結(jié)果
> db.fastdfs.find()
{ "_id" : ObjectId("65a9e4cb03febb56295304d4"),  "fastdfs_url" : "http://1.1.1.1:8099/g10/M00/39/D9/CmQA6WEJ5NGAEtsoAABqUGfXheo386.wav" }
  • 詳細(xì)命令如下
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
         }
      }
   );
});
  • 調(diào)整后結(jié)果
> db.fastdfs.find()
{ "_id" : ObjectId("65a9e4cb03febb56295304d4"),  "fastdfs_url" : "http://2.2.2.2:8099/g10/M00/39/D9/CmQA6WEJ5NGAEtsoAABqUGfXheo386.wav" }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末垄琐,一起剝皮案震驚了整個(gè)濱河市边酒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狸窘,老刑警劉巖墩朦,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異翻擒,居然都是意外死亡氓涣,警方通過查閱死者的電腦和手機(jī)牛哺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劳吠,“玉大人引润,你說我怎么就攤上這事⊙魍妫” “怎么了淳附?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蠢古。 經(jīng)常有香客問我奴曙,道長,這世上最難降的妖魔是什么便瑟? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任缆毁,我火速辦了婚禮,結(jié)果婚禮上到涂,老公的妹妹穿的比我還像新娘脊框。我一直安慰自己,他們只是感情好践啄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布浇雹。 她就那樣靜靜地躺著,像睡著了一般屿讽。 火紅的嫁衣襯著肌膚如雪昭灵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天伐谈,我揣著相機(jī)與錄音烂完,去河邊找鬼。 笑死诵棵,一個(gè)胖子當(dāng)著我的面吹牛抠蚣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播履澳,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼嘶窄,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了距贷?” 一聲冷哼從身側(cè)響起柄冲,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎忠蝗,沒想到半個(gè)月后现横,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年长赞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晦攒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡得哆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出哟旗,到底是詐尸還是另有隱情贩据,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布闸餐,位于F島的核電站饱亮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏舍沙。R本人自食惡果不足惜近上,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拂铡。 院中可真熱鬧壹无,春花似錦、人聲如沸感帅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽失球。三九已至岖是,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間实苞,已是汗流浹背豺撑。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留黔牵,地道東北人聪轿。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像荧止,于是被迫代替她去往敵國和親屹电。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 一跃巡、環(huán)境說明: 1危号、操作系統(tǒng):CentOS Linux release 7.4.1708 2、mongodb版本:...
    張偉科閱讀 983評(píng)論 0 1
  • MongoDB基礎(chǔ)請(qǐng)參考:http://blog.51cto.com/kaliarch/2044423 Mongo...
    kaliarch閱讀 2,010評(píng)論 0 0
  • 配置服務(wù)器,全部設(shè)置為靜態(tài)地址 轉(zhuǎn)到/home目錄,創(chuàng)建一個(gè)mongo目錄用做實(shí)驗(yàn),我們需要?jiǎng)?chuàng)建如下的目錄層級(jí)和空...
    justonlyyo閱讀 1,306評(píng)論 0 0
  • 隨著物質(zhì)生活越來越豐富素邪,人們生活水平不斷提高外莲,消費(fèi)觀念也隨之改變。從過去人們只需求物質(zhì)的實(shí)用性,到追求品牌消費(fèi)偷线,后...
    呆萌小馬閱讀 318評(píng)論 0 0
  • 生活從來都不簡單声邦,我想找一個(gè)人乏奥,跟她說:我們做個(gè)約定好不好,對(duì)生活亥曹,都不要說放棄邓了,在放棄之前,先征得彼此同意媳瞪。 以...
    一饃淺笑安然閱讀 215評(píng)論 0 0