對于DDS集群實例,如果某個集合的存儲量很高,建議對該集合設置數據分片。分片是將數據按照某種方式拆分,將其分散存放在不同的機器上,以充分利用各分片節點的存儲空間和 計算性能 。
設置數據分片
下面以數據(ju)庫mytable,集合mycoll,字(zi)段“name”為分片鍵(jian)舉例說明。
步驟 1 通(tong)過(guo)mongo shell登錄(lu)分片集(ji)群實例。
步驟 2 判斷集合是否已分(fen)片。
use <database>
db.<collection>.getShardDistribution()
示例:
use mytable
db.mycoll.getShardDistribution()

步(bu)驟 3 對集(ji)合(he)所屬(shu)的數(shu)據庫啟用分片功能。
- 方式一
sh.enableSharding("")
- 示例:
sh.enableSharding("mytable")
- 方式二
use admin
db.runCommand({enablesharding:"<database>"})
步驟 4 對(dui)集合進(jin)行分片(pian)。
- 方式一
sh.shardCollection("<database>.<collection>",{"<keyname>":<value> })
- 示例:
sh.shardCollection("mytable.mycoll",{"name":"hashed"},{numInitialChunks:5})
- 方式二
use admin
db.runCommand({shardcollection:"<database>.<collection>",key:{"keyname":<value> }})
表 參數說明
| 參數 | 說明 |
|---|---|
<database> |
數據庫名稱。 |
<collection> |
集合名稱。 |
<keyname> |
分片鍵。集群實例將根據該值進行數據分片,請結合實際業務為集合選擇合適的分片鍵,具體操作請參見下文選擇合適的分片鍵。 |
<value> |
基于分片鍵的范圍查詢的排序方式。l、 1:表示索引升序。 -1:表示索引降序。 hashed:表示使用Hash分片,通常能將寫入均衡分布到各個分片節點。 更多信息,請參見。 |
numInitialChunks |
可選。當使用Hash分片鍵對空集合進行分片時,指定初始創建的最小分片數。 |
步驟 5 查(cha)看數(shu)(shu)據(ju)(ju)庫(ku)在各分片節(jie)點的(de)數(shu)(shu)據(ju)(ju)存儲情況。
sh.status()
示例:


選擇合適的分片鍵
- 背景
分(fen)(fen)片(pian)集(ji)群(qun)中數(shu)據(ju)的(de)(de)(de)分(fen)(fen)片(pian)以(yi)集(ji)合(he)(he)為(wei)(wei)基礎單位,集(ji)合(he)(he)中的(de)(de)(de)數(shu)據(ju)通(tong)過分(fen)(fen)片(pian)鍵(jian)(jian)被分(fen)(fen)成多個(ge)部分(fen)(fen)。分(fen)(fen)片(pian)鍵(jian)(jian)是(shi)在(zai)集(ji)合(he)(he)中選擇(ze)的(de)(de)(de)一(yi)個(ge)合(he)(he)適(shi)(shi)的(de)(de)(de)字段,數(shu)據(ju)拆分(fen)(fen)時以(yi)該分(fen)(fen)片(pian)鍵(jian)(jian)的(de)(de)(de)值為(wei)(wei)依據(ju)均衡(heng)地分(fen)(fen)布(bu)到(dao)所有分(fen)(fen)片(pian)中。如果您沒有選擇(ze)到(dao)合(he)(he)適(shi)(shi)的(de)(de)(de)的(de)(de)(de)分(fen)(fen)片(pian)鍵(jian)(jian),可能會降低集(ji)群(qun)的(de)(de)(de)使(shi)用性能,出現執行(xing)分(fen)(fen)片(pian)語句時執行(xing)過程卡(ka)住的(de)(de)(de)問(wen)題(ti)。
分(fen)(fen)片(pian)(pian)鍵一(yi)旦設置后不(bu)能再更(geng)改。如(ru)果未選取到合適的(de)分(fen)(fen)片(pian)(pian)鍵,需要使用正確的(de)分(fen)(fen)片(pian)(pian)策略,將數據(ju)遷移(yi)到新的(de)集(ji)合后重(zhong)新執行(xing)分(fen)(fen)片(pian)(pian)。
- 合適的分片鍵的特點
- 所有的插入、更新以及刪除操作,將會均勻分發到集群中的所有分片中。
- key的分布足夠離散。
- 盡量避免scatter-gather查詢。
如果所選分片鍵不具備以上所有特點,將會影響集群的讀寫擴展性。例如,通過 find() 操作(zuo)讀(du)取(qu)(qu)的(de)工(gong)作(zuo)量(liang)在(zai)分片(pian)(pian)中(zhong)非均勻(yun)分布(bu),最(zui)終會產生(sheng)查詢熱分片(pian)(pian)。同樣,如(ru)果寫工(gong)作(zuo)量(liang)(插入、更新和修改)在(zai)分片(pian)(pian)中(zhong)非均勻(yun)分布(bu),最(zui)終會產生(sheng)寫熱分片(pian)(pian),嚴重(zhong)限制分片(pian)(pian)的(de)優(you)勢。因(yin)此(ci),您(nin)需要根據(ju)應用讀(du)寫狀態(tai)(重(zhong)讀(du)取(qu)(qu)還是重(zhong)寫入)、經常查詢及(ji)寫入的(de)數(shu)據(ju)等業務(wu)需求,調整您(nin)的(de)分片(pian)(pian)鍵(jian)。
需要注意,對已有數據分片后,如(ru)果update請(qing)求的filter中(zhong)未攜帶片鍵字段并(bing)且(qie)選(xuan)項upsert:true或(huo)者(zhe)multi:false,那(nei)么update 請(qing)求會報錯,并(bing)返回“An upsert on a sharded collection must contain the shard key and have the simple collation.”
- 判斷標準
您可以通(tong)過下(xia)表中的幾(ji)個維度,判(pan)斷(duan)所選分片鍵(jian)是否能夠滿足業務需求。
合理分片鍵的判斷依據
| 判斷依據 | 說明 |
|---|---|
| 片鍵基數 | 片鍵基數是指劃分數據塊的能力。例如,要記錄某個學校的學生信息,由于學生的年齡比較集中,如果選擇年齡作為分片鍵,同一個數據段中將存儲很多同齡學生的數據,影響集群的性能以及可管理性。由于學生的學號唯一,如果選擇學號作為分片鍵,分片基數較大,有利于數據的均勻分布。 |
| 寫分布 | 若用戶業務在同一時間段有大量寫操作,則希望這些寫操作能夠均勻分布到各個分片上。如果數據分布策略為范圍分片,并以一個單調遞增的值作為分片鍵,此時,大量寫入的數據同樣是片鍵字段遞增,數據將寫入同一個分片。 |
| 讀分發 | 若用戶業務在同一時間段有大量讀操作,則希望這些讀操作能夠均勻分布到各個分片上,以充分利用各分片節點的計算性能。 |
| 定向讀 | mongos查詢路由器可以執行定向查詢(只查詢一個分片)或scatter/gather查詢(查詢所有分片)。只有查詢中存在分片鍵,mongos才能定位到單一分片,因此,您需要選擇在業務運行時可用于普遍查詢的分片鍵。如果您選擇合成的分片鍵,將無法在定向查詢中使用該片鍵,所有的查詢方式將變成scatter/gather查詢,從而限制擴展讀數據的能力。 |
選擇合適的數據分布策略
分(fen)(fen)(fen)片集(ji)(ji)群支(zhi)持將單個集(ji)(ji)合(he)的數(shu)據分(fen)(fen)(fen)散存儲在多(duo)個分(fen)(fen)(fen)片上,用(yong)戶可以根據集(ji)(ji)合(he)內文檔的分(fen)(fen)(fen)片鍵來(lai)分(fen)(fen)(fen)布數(shu)據。
目前,主要支(zhi)持兩種數據分(fen)布(bu)策(ce)略,即范圍分(fen)片(Range based sharding)和Hash分(fen)片(Hash based sharding),設置方式請參見步驟(zou)4。
下面(mian)分(fen)別介紹(shao)這兩(liang)種數據分(fen)布(bu)策略以及(ji)各自的優缺點。
- 范圍分片
基于范圍(wei)進(jin)行分(fen)(fen)片(pian)(pian),即集群按照分(fen)(fen)片(pian)(pian)鍵的(de)(de)范圍(wei)把數(shu)據(ju)分(fen)(fen)成不(bu)同部分(fen)(fen)。假設有一個(ge)(ge)數(shu)字分(fen)(fen)片(pian)(pian)鍵,為(wei)一條從負(fu)無(wu)窮到正無(wu)窮的(de)(de)直(zhi)線(xian),每一個(ge)(ge)片(pian)(pian)鍵的(de)(de)值均在(zai)直(zhi)線(xian)上進(jin)行標記。可以理解為(wei)將該直(zhi)線(xian)劃分(fen)(fen)為(wei)更(geng)短的(de)(de)不(bu)重疊的(de)(de)片(pian)(pian)段,并(bing)稱之(zhi)為(wei)數(shu)據(ju)塊(kuai),每個(ge)(ge)數(shu)據(ju)塊(kuai)包(bao)含了分(fen)(fen)片(pian)(pian)鍵在(zai)一定的(de)(de)范圍(wei)內的(de)(de)數(shu)據(ju)。
圖 數據分布示意圖


如上圖所示,x表示范圍分(fen)片(pian)的片(pian)鍵,x的取(qu)值(zhi)范圍為[minKey,maxKey],且(qie)為整型。將整個(ge)取(qu)值(zhi)范圍劃(hua)分(fen)為多個(ge)chunk,每(mei)個(ge)chunk(通常配置為64MB)包含其中(zhong)一小(xiao)段的數(shu)據(ju)。其中(zhong),chunk1包含x值(zhi)在(zai)[minKey, -75]中(zhong)的所有(you)文檔,每(mei)個(ge)chunk的數(shu)據(ju)都存儲在(zai)同一個(ge)分(fen)片(pian)上,每(mei)個(ge)分(fen)片(pian)可(ke)以存儲多個(ge)chunk,并且(qie)chunk存儲在(zai)分(fen)片(pian)中(zhong)的數(shu)據(ju)會存儲在(zai)config服務器中(zhong),mongos也會根據(ju)各分(fen)片(pian)上的chunk的數(shu)據(ju)自動執(zhi)行負載均衡。
范(fan)(fan)圍分片能夠很好的滿(man)足范(fan)(fan)圍查(cha)詢的需求,例如,查(cha)詢x的取值在[-60,20]中的文檔,僅需mongos將請求路由(you)到(dao)chunk2。
范圍(wei)分片(pian)的(de)缺點(dian)在于(yu),如(ru)果分片(pian)鍵(jian)有明(ming)顯(xian)遞(di)增(或遞(di)減)趨(qu)勢(shi),新插入的(de)文檔很大程度上(shang)會分布(bu)到同一個chunk,從而無(wu)法擴(kuo)展寫的(de)能力。例如(ru),使用“_id”作為分片(pian)鍵(jian),集群自動生成id的(de)高位(wei)值將(jiang)是遞(di)增的(de)時間戳。
- Hash分片
根據(ju)(ju)用戶的(de)分(fen)片鍵值(zhi)(zhi)計算出Hash值(zhi)(zhi)(長度64bit且為整型(xing)),再按照范圍分(fen)片策略,根據(ju)(ju)Hash值(zhi)(zhi)將文檔分(fen)布(bu)到不同的(de)chunk中(zhong)。基(ji)于(yu)Hash分(fen)片主要的(de)優勢為保證數(shu)據(ju)(ju)在各節點上分(fen)布(bu)基(ji)本均勻(yun),具有“相近(jin)”片鍵的(de)文檔很可能(neng)不會(hui)存(cun)儲在同一個(ge)數(shu)據(ju)(ju)塊中(zhong),數(shu)據(ju)(ju)的(de)分(fen)離(li)性更高。
圖 數據分布示意圖


Hash分(fen)(fen)片(pian)與范(fan)圍(wei)分(fen)(fen)片(pian)互補(bu),能將(jiang)文檔隨機分(fen)(fen)散到(dao)各個chunk,充分(fen)(fen)擴展寫能力,彌補(bu)范(fan)圍(wei)分(fen)(fen)片(pian)的(de)不足(zu)。但所有(you)的(de)范(fan)圍(wei)查詢(xun)要(yao)分(fen)(fen)發到(dao)后端所有(you)的(de)分(fen)(fen)片(pian),才能獲取(qu)滿足(zu)條件的(de)文檔,查詢(xun)效率低。