1.1 MongoDB復(fù)制集簡介
一組Mongodb復(fù)制集,就是一組mongod進(jìn)程,這些進(jìn)程維護(hù)同一個數(shù)據(jù)集合。復(fù)制集提供了數(shù)據(jù)冗余和高等級的可靠性,這是生產(chǎn)部署的基礎(chǔ)。
1.1.1 復(fù)制集的目的
保證數(shù)據(jù)在生產(chǎn)部署時的冗余和可靠性,通過在不同的機(jī)器上保存副本來保證數(shù)據(jù)的不會因?yàn)閱吸c(diǎn)損壞而丟失。能夠隨時應(yīng)對數(shù)據(jù)丟失、機(jī)器損壞帶來的風(fēng)險(xiǎn)。
換一句話來說,還能提高讀取能力,用戶的讀取服務(wù)器和寫入服務(wù)器在不同的地方,而且,由不同的服務(wù)器為不同的用戶提供服務(wù),提高整個系統(tǒng)的負(fù)載。
1.1.2 簡單介紹
一組復(fù)制集就是一組mongod實(shí)例掌管同一個數(shù)據(jù)集,實(shí)例可以在不同的機(jī)器上面。實(shí)例中包含一個主導(dǎo),接受客戶端所有的寫入操作,其他都是副本實(shí)例,從主服務(wù)器上獲得數(shù)據(jù)并保持同步。
主服務(wù)器很重要,包含了所有的改變操作(寫)的日志。但是副本服務(wù)器集群包含有所有的主服務(wù)器數(shù)據(jù),因此當(dāng)主服務(wù)器掛掉了,就會在副本服務(wù)器上重新選取一個成為主服務(wù)器。
每個復(fù)制集還有一個仲裁者,仲裁者不存儲數(shù)據(jù),只是負(fù)責(zé)通過心跳包來確認(rèn)集群中集合的數(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é)點(diǎn)
在三個成員的復(fù)制集中,有兩個正常的主從,及一臺arbiter節(jié)點(diǎn):

說明:
由于arbiter節(jié)點(diǎn)沒有復(fù)制數(shù)據(jù),因此這個架構(gòu)中僅提供一個完整的數(shù)據(jù)副本。arbiter節(jié)點(diǎn)只需要更少的資源,代價(jià)是更有限的冗余和容錯。

1.2.3 Primary選舉
復(fù)制集通過replSetInitiate命令(或mongo shell的rs.initiate())進(jìn)行初始化,初始化后各個成員間開始發(fā)送心跳消息,并發(fā)起Priamry選舉操作,獲得『大多數(shù)』成員投票支持的節(jié)點(diǎn),會成為Primary,其余節(jié)點(diǎn)成為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é)點(diǎn)

1.3.3 Hidden 節(jié)點(diǎn)(隱藏節(jié)點(diǎn))
客戶端將不會把讀請求分發(fā)到隱藏節(jié)點(diǎn)上,即使我們設(shè)定了 復(fù)制集讀選項(xiàng) 。

1.3.4 Delayed 節(jié)點(diǎn)(延時節(jié)點(diǎn))
延時節(jié)點(diǎn)的數(shù)據(jù)集是延時的,因此它可以幫助我們在人為誤操作或是其他意外情況下恢復(fù)數(shù)據(jù)。

1.4 配置MongoDB復(fù)制集
配置分片集群請看我的另一篇文章:? ? http://m.itdecent.cn/p/d9efee400087
MongoDB分片(Sharding)技術(shù)
分片(sharding)是MongoDB用來將大型集合分割到不同服務(wù)器(或者說一個集群)上所采用的方法。盡管分片起源于關(guān)系型數(shù)據(jù)庫分區(qū),但MongoDB分片完全又是另一回事。
和MySQL分區(qū)方案相比,MongoDB的最大區(qū)別在于它幾乎能自動完成所有事情,只要告訴MongoDB要分配數(shù)據(jù),它就能自動維護(hù)數(shù)據(jù)在不同服務(wù)器之間的均衡。
2.1 MongoDB分片介紹
2.1.1 分片的目的
高數(shù)據(jù)量和吞吐量的數(shù)據(jù)庫應(yīng)用會對單機(jī)的性能造成較大壓力,大的查詢量會將單機(jī)的CPU耗盡,大的數(shù)據(jù)量對單機(jī)的存儲壓力較大,最終會耗盡系統(tǒng)的內(nèi)存而將壓力轉(zhuǎn)移到磁盤IO上。
為了解決這些問題,有兩個基本的方法: 垂直擴(kuò)展和水平擴(kuò)展。
垂直擴(kuò)展:增加更多的CPU和存儲資源來擴(kuò)展容量。
水平擴(kuò)展:將數(shù)據(jù)集分布在多個服務(wù)器上。水平擴(kuò)展即分片。
2.1.2 分片設(shè)計(jì)思想
分片為應(yīng)對高吞吐量與大數(shù)據(jù)量提供了方法。使用分片減少了每個分片需要處理的請求數(shù),因此,通過水平擴(kuò)展,集群可以提高自己的存儲容量和吞吐量。舉例來說,當(dāng)插入一條數(shù)據(jù)時,應(yīng)用只需要訪問存儲這條數(shù)據(jù)的分片.
使用分片減少了每個分片存儲的數(shù)據(jù)。

2.1.3 分片機(jī)制提供了如下三種優(yōu)勢
1.對集群進(jìn)行抽象,讓集群“不可見”
MongoDB自帶了一個叫做mongos的專有路由進(jìn)程。mongos就是掌握統(tǒng)一路口的路由器,其會將客戶端發(fā)來的請求準(zhǔn)確無誤的路由到集群中的一個或者一組服務(wù)器上,同時會把接收到的響應(yīng)拼裝起來發(fā)回到客戶端。
2.保證集群總是可讀寫
MongoDB通過多種途徑來確保集群的可用性和可靠性。將MongoDB的分片和復(fù)制功能結(jié)合使用,在確保數(shù)據(jù)分片到多臺服務(wù)器的同時,也確保了每分?jǐn)?shù)據(jù)都有相應(yīng)的備份,這樣就可以確保有服務(wù)器換掉時,其他的從庫可以立即接替壞掉的部分繼續(xù)工作。
3.使集群易于擴(kuò)展
當(dāng)系統(tǒng)需要更多的空間和資源的時候,MongoDB使我們可以按需方便的擴(kuò)充系統(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é)點(diǎn)的信息,分片功能的一些配置信息??梢岳斫鉃檎鎸?shí)數(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è)計(jì)寫入數(shù)據(jù)。
當(dāng)外部語句發(fā)起數(shù)據(jù)查詢時,MongoDB根據(jù)數(shù)據(jù)分布自動路由至指定節(jié)點(diǎn)返回?cái)?shù)據(jù)。
2.2 集群中數(shù)據(jù)分布
2.2.1 Chunk是什么
在一個shard server內(nèi)部,MongoDB還是會把數(shù)據(jù)分為chunks,每個chunk代表這個shard server內(nèi)部一部分?jǐn)?shù)據(jù)。chunk的產(chǎn)生,會有以下兩個用途:
Splitting:當(dāng)一個chunk的大小超過配置中的chunk size時,MongoDB的后臺進(jìn)程會把這個chunk切分成更小的chunk,從而避免chunk過大的情況
Balancing:在MongoDB中,balancer是一個后臺進(jìn)程,負(fù)責(zé)chunk的遷移,從而均衡各個shard server的負(fù)載,系統(tǒng)初始1個chunk,chunk size默認(rèn)值64M,生產(chǎn)庫上選擇適合業(yè)務(wù)的chunk size是最好的。ongoDB會自動拆分和遷移chunks。
分片集群的數(shù)據(jù)分布(shard節(jié)點(diǎn))
(1)使用chunk來存儲數(shù)據(jù)
(2)進(jìn)群搭建完成之后,默認(rèn)開啟一個chunk,大小是64M,
(3)存儲需求超過64M,chunk會進(jìn)行分裂,如果單位時間存儲需求很大,設(shè)置更大的chunk
(4)chunk會被自動均衡遷移。
2.2.2 chunksize的選擇
適合業(yè)務(wù)的chunksize是最好的。
chunk的分裂和遷移非常消耗IO資源;chunk分裂的時機(jī):在插入和更新,讀數(shù)據(jù)不會分裂。
chunksize的選擇:
小的chunksize:數(shù)據(jù)均衡是遷移速度快,數(shù)據(jù)分布更均勻。數(shù)據(jù)分裂頻繁,路由節(jié)點(diǎn)消耗更多資源。大的chunksize:數(shù)據(jù)分裂少。數(shù)據(jù)塊移動集中消耗IO資源。通常100-200M
2.2.3 chunk分裂及遷移


chunkSize 對分裂及遷移的影響
MongoDB 默認(rèn)的 chunkSize 為64MB,如無特殊需求,建議保持默認(rèn)值;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 大小會隨著寫入不斷增長,直到達(dá)到目標(biāo)大小。
2.3 數(shù)據(jù)區(qū)分
2.3.1 分片鍵shard key
MongoDB中數(shù)據(jù)的分片是、以集合為基本單位的,集合中的數(shù)據(jù)通過片鍵(Shard key)被分成多部分。其實(shí)片鍵就是在集合中選一個鍵,用該鍵的值作為數(shù)據(jù)拆分的依據(jù)。
所以一個好的片鍵對分片至關(guān)重要。片鍵必須是一個索引,通過sh.shardCollection加會自動創(chuàng)建索引(前提是此集合不存在的情況下)。一個自增的片鍵對寫入和數(shù)據(jù)均勻分布就不是很好,因?yàn)樽栽龅钠I總會在一個分片上寫入,后續(xù)達(dá)到某個閥值可能會寫到別的分片。但是按照片鍵查詢會非常高效。
隨機(jī)片鍵對數(shù)據(jù)的均勻分布效果很好。注意盡量避免在多個分片上進(jìn)行查詢。在所有分片上查詢,mongos會對結(jié)果進(jìn)行歸并排序。
對集合進(jìn)行分片時,你需要選擇一個片鍵,片鍵是每條記錄都必須包含的,且建立了索引的單個字段或復(fù)合字段,MongoDB按照片鍵將數(shù)據(jù)劃分到不同的數(shù)據(jù)塊中,并將數(shù)據(jù)塊均衡地分布到所有分片中。
為了按照片鍵劃分?jǐn)?shù)據(jù)塊,MongoDB使用基于范圍的分片方式或者 基于哈希的分片方式。
注意:
? ? ? ? 分片鍵是不可變。
? ? ? ? 分片鍵必須有索引。
? ? ? ? 分片鍵大小限制512bytes。
? ? ? ? 分片鍵用于路由查詢。
? ? ? ? MongoDB不接受已進(jìn)行collection級分片的collection上插入無分片
? ? ? ? 鍵的文檔(也不支持空值插入)
2.3.2 以范圍為基礎(chǔ)的分片Sharded Cluster
Sharded Cluster支持將單個集合的數(shù)據(jù)分散存儲在多shard上,用戶可以指定根據(jù)集合內(nèi)文檔的某個字段即shard key來進(jìn)行范圍分片(range sharding)。

假設(shè)有一個數(shù)字的片鍵:想象一個從負(fù)無窮到正無窮的直線,每一個片鍵的值都在直線上畫了一個點(diǎn)。MongoDB把這條直線劃分為更短的不重疊的片段,并稱之為數(shù)據(jù)塊,每個數(shù)據(jù)塊包含了片鍵在一定范圍內(nèi)的數(shù)據(jù)。在使用片鍵做范圍劃分的系統(tǒng)中,擁有”相近”片鍵的文檔很可能存儲在同一個數(shù)據(jù)塊中,因此也會存儲在同一個分片中。
2.3.3 基于哈希的分片

對于基于哈希的分片,MongoDB計(jì)算一個字段的哈希值,并用這個哈希值來創(chuàng)建數(shù)據(jù)塊。在使用基于哈希分片的系統(tǒng)中,擁有”相近”片鍵的文檔很可能不會存儲在同一個數(shù)據(jù)塊中,因此數(shù)據(jù)的分離性更好一些。
Hash分片與范圍分片互補(bǔ),能將文檔隨機(jī)的分散到各個chunk,充分的擴(kuò)展寫能力,彌補(bǔ)了范圍分片的不足,但不能高效的服務(wù)范圍查詢,所有的范圍查詢要分發(fā)到后端所有的Shard才能找出滿足條件的文檔。
2.3.4 分片鍵選擇建議
1、遞增的sharding key
數(shù)據(jù)文件挪動小。(優(yōu)勢)
因?yàn)閿?shù)據(jù)文件遞增,所以會把insert的寫IO永久放在最后一片上,造成最后一片的寫熱點(diǎn)。同時,隨著最后一片的數(shù)據(jù)量增大,將不斷的發(fā)生遷移至之前的片上。
2、隨機(jī)的sharding key
數(shù)據(jù)分布均勻,insert的寫IO均勻分布在多個片上。(優(yōu)勢)
大量的隨機(jī)IO,磁盤不堪重荷。
3、混合型key
大方向隨機(jī)遞增,小范圍隨機(jī)分布。
為了防止出現(xiàn)大量的chunk均衡遷移,可能造成的IO壓力。我們需要設(shè)置合理分片使用策略(片鍵的選擇、分片算法(range、hash))
分片注意:
? 分片鍵是不可變、分片鍵必須有索引、分片鍵大小限制512bytes、分片鍵用于路由查詢。
? MongoDB不接受已進(jìn)行collection級分片的collection上插入無分片鍵的文檔(也不支持空值插入)
參考文獻(xiàn)? ? https://www.cnblogs.com/clsn/p/8214345.html
我這里有一個問題還想請MongoDB大牛解答:
? ? 如何提高M(jìn)ongoDB分片集群數(shù)據(jù)的插入速度:
? ? 現(xiàn)在的插入速度為 :(10次的平均值)2分40秒插入數(shù)據(jù)67634條 每條數(shù)據(jù)3-4kb左右
? ? ? ? 單機(jī)模式的插入速度是集群模式的兩倍
? ? ? ? 插入方式均為? ? insertOne
? ? ? ? 暫不考慮? ? ? ? ? ? insertMany? ? 因?yàn)榭赡軐?dǎo)致數(shù)據(jù)丟失
? ? ? ? 具體的請您聯(lián)系我微信QQ同時在線:772590001
? ? ? ? ? ? ?。。?!謝謝