1.1 MongoDB復(fù)制集簡介
一組Mongodb復(fù)制集洲愤,就是一組mongod進程夫否,這些進程維護同一個數(shù)據(jù)集合。復(fù)制集提供了數(shù)據(jù)冗余和高等級的可靠性局待,這是生產(chǎn)部署的基礎(chǔ)斑响。
1.1.1 復(fù)制集的目的
保證數(shù)據(jù)在生產(chǎn)部署時的冗余和可靠性,通過在不同的機器上保存副本來保證數(shù)據(jù)的不會因為單點損壞而丟失钳榨。能夠隨時應(yīng)對數(shù)據(jù)丟失舰罚、機器損壞帶來的風(fēng)險。
換一句話來說薛耻,還能提高讀取能力营罢,用戶的讀取服務(wù)器和寫入服務(wù)器在不同的地方,而且饼齿,由不同的服務(wù)器為不同的用戶提供服務(wù)饲漾,提高整個系統(tǒng)的負載。
1.1.2 簡單介紹
一組復(fù)制集就是一組mongod實例掌管同一個數(shù)據(jù)集候醒,實例可以在不同的機器上面能颁。實例中包含一個主導(dǎo),接受客戶端所有的寫入操作倒淫,其他都是副本實例伙菊,從主服務(wù)器上獲得數(shù)據(jù)并保持同步。
主服務(wù)器很重要敌土,包含了所有的改變操作(寫)的日志镜硕。但是副本服務(wù)器集群包含有所有的主服務(wù)器數(shù)據(jù),因此當(dāng)主服務(wù)器掛掉了返干,就會在副本服務(wù)器上重新選取一個成為主服務(wù)器兴枯。
每個復(fù)制集還有一個仲裁者,仲裁者不存儲數(shù)據(jù)矩欠,只是負責(zé)通過心跳包來確認集群中集合的數(shù)量财剖,并在主服務(wù)器選舉的時候作為仲裁決定結(jié)果。
1.2 復(fù)制的基本架構(gòu)
基本的架構(gòu)由3臺服務(wù)器組成癌淮,一個三成員的復(fù)制集躺坟,由三個有數(shù)據(jù),或者兩個有數(shù)據(jù)乳蓄,一個作為仲裁者咪橙。
1.2.1 三個存儲數(shù)據(jù)的復(fù)制集
具有三個存儲數(shù)據(jù)的成員的復(fù)制集有:
1.2.2 當(dāng)存在arbiter節(jié)點
在三個成員的復(fù)制集中赠叼,有兩個正常的主從擦囊,及一臺arbiter節(jié)點:
說明:
由于arbiter節(jié)點沒有復(fù)制數(shù)據(jù)涧郊,因此這個架構(gòu)中僅提供一個完整的數(shù)據(jù)副本。arbiter節(jié)點只需要更少的資源眼五,代價是更有限的冗余和容錯妆艘。
1.2.3 Primary選舉
復(fù)制集通過replSetInitiate命令(或mongo shell的rs.initiate())進行初始化诵姜,初始化后各個成員間開始發(fā)送心跳消息汽煮,并發(fā)起Priamry選舉操作,獲得『大多數(shù)』成員投票支持的節(jié)點棚唆,會成為Primary暇赤,其余節(jié)點成為Secondary。
『大多數(shù)』的定義
假設(shè)復(fù)制集內(nèi)投票成員(后續(xù)介紹)數(shù)量為N宵凌,則大多數(shù)為 N/2 + 1鞋囊,當(dāng)復(fù)制集內(nèi)存活成員數(shù)量不足大多數(shù)時,整個復(fù)制集將無法選舉出Primary瞎惫,復(fù)制集將無法提供寫服務(wù)溜腐,處于只讀狀態(tài)。
1.3 復(fù)制集中成員說明
1.3.2 Priority 0節(jié)點
1.3.3 Hidden 節(jié)點(隱藏節(jié)點)
客戶端將不會把讀請求分發(fā)到隱藏節(jié)點上黍檩,即使我們設(shè)定了 復(fù)制集讀選項 叉袍。
1.3.4 Delayed 節(jié)點(延時節(jié)點)
延時節(jié)點的數(shù)據(jù)集是延時的,因此它可以幫助我們在人為誤操作或是其他意外情況下恢復(fù)數(shù)據(jù)棵里。
1.4 配置MongoDB復(fù)制集
配置分片集群請看我的另一篇文章:? ? http://www.reibang.com/p/d9efee400087
MongoDB分片(Sharding)技術(shù)
分片(sharding)是MongoDB用來將大型集合分割到不同服務(wù)器(或者說一個集群)上所采用的方法典蝌。盡管分片起源于關(guān)系型數(shù)據(jù)庫分區(qū),但MongoDB分片完全又是另一回事头谜。
和MySQL分區(qū)方案相比骏掀,MongoDB的最大區(qū)別在于它幾乎能自動完成所有事情,只要告訴MongoDB要分配數(shù)據(jù)柱告,它就能自動維護數(shù)據(jù)在不同服務(wù)器之間的均衡截驮。
2.1 MongoDB分片介紹
2.1.1 分片的目的
高數(shù)據(jù)量和吞吐量的數(shù)據(jù)庫應(yīng)用會對單機的性能造成較大壓力,大的查詢量會將單機的CPU耗盡,大的數(shù)據(jù)量對單機的存儲壓力較大,最終會耗盡系統(tǒng)的內(nèi)存而將壓力轉(zhuǎn)移到磁盤IO上。
為了解決這些問題,有兩個基本的方法: 垂直擴展和水平擴展际度。
垂直擴展:增加更多的CPU和存儲資源來擴展容量葵袭。
水平擴展:將數(shù)據(jù)集分布在多個服務(wù)器上。水平擴展即分片乖菱。
2.1.2 分片設(shè)計思想
分片為應(yīng)對高吞吐量與大數(shù)據(jù)量提供了方法坡锡。使用分片減少了每個分片需要處理的請求數(shù),因此块请,通過水平擴展娜氏,集群可以提高自己的存儲容量和吞吐量。舉例來說墩新,當(dāng)插入一條數(shù)據(jù)時贸弥,應(yīng)用只需要訪問存儲這條數(shù)據(jù)的分片.
使用分片減少了每個分片存儲的數(shù)據(jù)。
2.1.3 分片機制提供了如下三種優(yōu)勢
1.對集群進行抽象讯沈,讓集群“不可見”
MongoDB自帶了一個叫做mongos的專有路由進程郁岩。mongos就是掌握統(tǒng)一路口的路由器,其會將客戶端發(fā)來的請求準確無誤的路由到集群中的一個或者一組服務(wù)器上,同時會把接收到的響應(yīng)拼裝起來發(fā)回到客戶端问慎。
2.保證集群總是可讀寫
MongoDB通過多種途徑來確保集群的可用性和可靠性萍摊。將MongoDB的分片和復(fù)制功能結(jié)合使用,在確保數(shù)據(jù)分片到多臺服務(wù)器的同時如叼,也確保了每分數(shù)據(jù)都有相應(yīng)的備份冰木,這樣就可以確保有服務(wù)器換掉時,其他的從庫可以立即接替壞掉的部分繼續(xù)工作笼恰。
3.使集群易于擴展
當(dāng)系統(tǒng)需要更多的空間和資源的時候踊沸,MongoDB使我們可以按需方便的擴充系統(tǒng)容量。
2.1.4 分片集群架構(gòu)
分片集群的構(gòu)造
? ? (1)mongos :數(shù)據(jù)路由社证,和客戶端打交道的模塊逼龟。mongos本身沒有任何數(shù)據(jù),他也不知道該怎么處理這數(shù)據(jù)追葡,去找config server
(2)config server:所有存审轮、取數(shù)據(jù)的方式,所有shard節(jié)點的信息辽俗,分片功能的一些配置信息〈鄯蹋可以理解為真實數(shù)據(jù)的元數(shù)據(jù)崖飘。
(3)shard:真正的數(shù)據(jù)存儲位置,以chunk為單位存數(shù)據(jù)杈女。
Mongos本身并不持久化數(shù)據(jù)朱浴,Sharded cluster所有的元數(shù)據(jù)都會存儲到Config Server,而用戶的數(shù)據(jù)會議分散存儲到各個shard达椰。Mongos啟動后翰蠢,會從配置服務(wù)器加載元數(shù)據(jù),開始提供服務(wù)啰劲,將用戶的請求正確路由到對應(yīng)的碎片梁沧。
Mongos的路由功能
當(dāng)數(shù)據(jù)寫入時,MongoDB Cluster根據(jù)分片鍵設(shè)計寫入數(shù)據(jù)蝇裤。
當(dāng)外部語句發(fā)起數(shù)據(jù)查詢時廷支,MongoDB根據(jù)數(shù)據(jù)分布自動路由至指定節(jié)點返回數(shù)據(jù)。
2.2 集群中數(shù)據(jù)分布
2.2.1 Chunk是什么
在一個shard server內(nèi)部栓辜,MongoDB還是會把數(shù)據(jù)分為chunks恋拍,每個chunk代表這個shard server內(nèi)部一部分數(shù)據(jù)。chunk的產(chǎn)生藕甩,會有以下兩個用途:
Splitting:當(dāng)一個chunk的大小超過配置中的chunk size時施敢,MongoDB的后臺進程會把這個chunk切分成更小的chunk,從而避免chunk過大的情況
Balancing:在MongoDB中,balancer是一個后臺進程僵娃,負責(zé)chunk的遷移概作,從而均衡各個shard server的負載,系統(tǒng)初始1個chunk悯许,chunk size默認值64M,生產(chǎn)庫上選擇適合業(yè)務(wù)的chunk size是最好的仆嗦。ongoDB會自動拆分和遷移chunks。
分片集群的數(shù)據(jù)分布(shard節(jié)點)
(1)使用chunk來存儲數(shù)據(jù)
(2)進群搭建完成之后先壕,默認開啟一個chunk瘩扼,大小是64M,
(3)存儲需求超過64M垃僚,chunk會進行分裂集绰,如果單位時間存儲需求很大,設(shè)置更大的chunk
(4)chunk會被自動均衡遷移谆棺。
2.2.2 chunksize的選擇
適合業(yè)務(wù)的chunksize是最好的栽燕。
chunk的分裂和遷移非常消耗IO資源;chunk分裂的時機:在插入和更新改淑,讀數(shù)據(jù)不會分裂碍岔。
chunksize的選擇:
小的chunksize:數(shù)據(jù)均衡是遷移速度快,數(shù)據(jù)分布更均勻朵夏。數(shù)據(jù)分裂頻繁蔼啦,路由節(jié)點消耗更多資源。大的chunksize:數(shù)據(jù)分裂少仰猖。數(shù)據(jù)塊移動集中消耗IO資源捏肢。通常100-200M
2.2.3 chunk分裂及遷移
chunkSize 對分裂及遷移的影響
MongoDB 默認的 chunkSize 為64MB,如無特殊需求成肘,建議保持默認值卖局;chunkSize 會直接影響到 chunk 分裂、遷移的行為双霍。
chunkSize 越小砚偶,chunk 分裂及遷移越多批销,數(shù)據(jù)分布越均衡;反之染坯,chunkSize 越大均芽,chunk 分裂及遷移會更少,但可能導(dǎo)致數(shù)據(jù)分布不均单鹿。
chunkSize 太小掀宋,容易出現(xiàn) jumbo chunk(即shardKey 的某個取值出現(xiàn)頻率很高,這些文檔只能放到一個 chunk 里仲锄,無法再分裂)而無法遷移劲妙;chunkSize 越大,則可能出現(xiàn) chunk 內(nèi)文檔數(shù)太多(chunk 內(nèi)文檔數(shù)不能超過 250000 )而無法遷移儒喊。
chunk 自動分裂只會在數(shù)據(jù)寫入時觸發(fā)镣奋,所以如果將 chunkSize 改小,系統(tǒng)需要一定的時間來將 chunk 分裂到指定的大小怀愧。
chunk 只會分裂侨颈,不會合并,所以即使將 chunkSize 改大芯义,現(xiàn)有的 chunk 數(shù)量不會減少哈垢,但 chunk 大小會隨著寫入不斷增長,直到達到目標(biāo)大小扛拨。
2.3 數(shù)據(jù)區(qū)分
2.3.1 分片鍵shard key
MongoDB中數(shù)據(jù)的分片是温赔、以集合為基本單位的,集合中的數(shù)據(jù)通過片鍵(Shard key)被分成多部分鬼癣。其實片鍵就是在集合中選一個鍵,用該鍵的值作為數(shù)據(jù)拆分的依據(jù)啤贩。
所以一個好的片鍵對分片至關(guān)重要待秃。片鍵必須是一個索引,通過sh.shardCollection加會自動創(chuàng)建索引(前提是此集合不存在的情況下)痹屹。一個自增的片鍵對寫入和數(shù)據(jù)均勻分布就不是很好章郁,因為自增的片鍵總會在一個分片上寫入,后續(xù)達到某個閥值可能會寫到別的分片志衍。但是按照片鍵查詢會非常高效暖庄。
隨機片鍵對數(shù)據(jù)的均勻分布效果很好。注意盡量避免在多個分片上進行查詢楼肪。在所有分片上查詢培廓,mongos會對結(jié)果進行歸并排序。
對集合進行分片時春叫,你需要選擇一個片鍵肩钠,片鍵是每條記錄都必須包含的泣港,且建立了索引的單個字段或復(fù)合字段,MongoDB按照片鍵將數(shù)據(jù)劃分到不同的數(shù)據(jù)塊中价匠,并將數(shù)據(jù)塊均衡地分布到所有分片中当纱。
為了按照片鍵劃分數(shù)據(jù)塊,MongoDB使用基于范圍的分片方式或者 基于哈希的分片方式踩窖。
注意:
? ? ? ? 分片鍵是不可變坡氯。
? ? ? ? 分片鍵必須有索引。
? ? ? ? 分片鍵大小限制512bytes洋腮。
? ? ? ? 分片鍵用于路由查詢箫柳。
? ? ? ? MongoDB不接受已進行collection級分片的collection上插入無分片
? ? ? ? 鍵的文檔(也不支持空值插入)
2.3.2 以范圍為基礎(chǔ)的分片Sharded Cluster
Sharded Cluster支持將單個集合的數(shù)據(jù)分散存儲在多shard上,用戶可以指定根據(jù)集合內(nèi)文檔的某個字段即shard key來進行范圍分片(range sharding)徐矩。
假設(shè)有一個數(shù)字的片鍵:想象一個從負無窮到正無窮的直線滤灯,每一個片鍵的值都在直線上畫了一個點坪稽。MongoDB把這條直線劃分為更短的不重疊的片段,并稱之為數(shù)據(jù)塊鳞骤,每個數(shù)據(jù)塊包含了片鍵在一定范圍內(nèi)的數(shù)據(jù)窒百。在使用片鍵做范圍劃分的系統(tǒng)中,擁有”相近”片鍵的文檔很可能存儲在同一個數(shù)據(jù)塊中豫尽,因此也會存儲在同一個分片中篙梢。
2.3.3 基于哈希的分片
對于基于哈希的分片,MongoDB計算一個字段的哈希值榴嗅,并用這個哈希值來創(chuàng)建數(shù)據(jù)塊妄呕。在使用基于哈希分片的系統(tǒng)中,擁有”相近”片鍵的文檔很可能不會存儲在同一個數(shù)據(jù)塊中嗽测,因此數(shù)據(jù)的分離性更好一些绪励。
Hash分片與范圍分片互補,能將文檔隨機的分散到各個chunk唠粥,充分的擴展寫能力疏魏,彌補了范圍分片的不足,但不能高效的服務(wù)范圍查詢晤愧,所有的范圍查詢要分發(fā)到后端所有的Shard才能找出滿足條件的文檔大莫。
2.3.4 分片鍵選擇建議
1、遞增的sharding key
數(shù)據(jù)文件挪動小官份。(優(yōu)勢)
因為數(shù)據(jù)文件遞增葵硕,所以會把insert的寫IO永久放在最后一片上眉抬,造成最后一片的寫熱點。同時懈凹,隨著最后一片的數(shù)據(jù)量增大蜀变,將不斷的發(fā)生遷移至之前的片上。
2介评、隨機的sharding key
數(shù)據(jù)分布均勻库北,insert的寫IO均勻分布在多個片上。(優(yōu)勢)
大量的隨機IO们陆,磁盤不堪重荷寒瓦。
3、混合型key
大方向隨機遞增坪仇,小范圍隨機分布杂腰。
為了防止出現(xiàn)大量的chunk均衡遷移,可能造成的IO壓力椅文。我們需要設(shè)置合理分片使用策略(片鍵的選擇喂很、分片算法(range、hash))
分片注意:
? 分片鍵是不可變皆刺、分片鍵必須有索引少辣、分片鍵大小限制512bytes、分片鍵用于路由查詢羡蛾。
? MongoDB不接受已進行collection級分片的collection上插入無分片鍵的文檔(也不支持空值插入)
參考文獻? ? https://www.cnblogs.com/clsn/p/8214345.html
我這里有一個問題還想請MongoDB大牛解答:
? ? 如何提高MongoDB分片集群數(shù)據(jù)的插入速度:
? ? 現(xiàn)在的插入速度為 :(10次的平均值)2分40秒插入數(shù)據(jù)67634條 每條數(shù)據(jù)3-4kb左右
? ? ? ? 單機模式的插入速度是集群模式的兩倍
? ? ? ? 插入方式均為? ? insertOne
? ? ? ? 暫不考慮? ? ? ? ? ? insertMany? ? 因為可能導(dǎo)致數(shù)據(jù)丟失
? ? ? ? 具體的請您聯(lián)系我微信QQ同時在線:772590001
? ? ? ? ? ? @焖А!3赵埂忙干!謝謝