在上一篇文章中說明完基本的分片概念後,我們本章節要更深的了解分片內的chunk,
它是每個分片組成的東西,我們這篇將要說明它的拆分與分配機制。
chunk的分配與拆分。chunk的分配與拆分 ~在上一篇文章中,我們知道每個分片中都包含了多個chunk,而每chunk中,又包含了某個範圍的document組,我們先簡單來畫個圖複習一下。

然後我們接下來要討論的就是,mongodb是如何拆分chunk和如何將chunk分片到shard裡,首先我們先來看看chunk的拆分。
chunk的拆分首先我們先想一下,chunk它本身是一堆document的集合體,大概長降,我們使用上一章節的範例,來看一下chunk的詳細資訊,假設我們都已經分片好了,我們直接看結果。
首先我們需要先移動到一個名為config的資料庫。
use config
> switched to db config
然後再執行db.chunks.find().pretty()來看一下,目前只有一個chunk,它目前窩在shard0000,而它的範圍是min ~ max,呃對了忘了說,我們的資料是1萬筆的{"name":"user"+i}這種物件。

這時我們要問個問題囉,它什麼時後會再分成另一個chunk ?
答案是chunk的大小,mongodb預設chunk最大限制為64MB,當超過時mongos會將它拆分為兩塊chunk,如下圖,此圖為官方圖片。

預設是64MB,當然我們也有辦法修改預設,指令如下,下面32代表為32MB。
use config
> switched to db config
db.settings.save({"_id" : "chunksize" : "value" : 32})
但是這邊要修改大小時有幾點要思考一下。
chunk越小時可以使分片的可以使分片的資料量更均衡,不會有差距太大的狀況,但缺點就是,因為小所以會常移動chunk,所以mongos壓力會比較重。
chunk的拆分實驗咱們來簡單的測試看看chunk的拆分,首先來建立一些資料,大小約為4188890 byte大概為4mb左右,然後我們的chunk大小預設為1mb,所以理論上應會開拆為3~4個chunk。
var objs = [];
for (var i=0;i<100000;i++){
objs.push({"name":"user"+i});
}
db.users.insert(objs);
建好後別忘了執行這兩個指令。
db.users.ensureIndex({"name":1})
sh.shardCollection("test.users",{"name":1})
然後我們指行sh.status()來看看結果,呃我淚囉為什麼會拆分為8個……

我們來檢查一下chunk size的設定,如下圖嗯沒錯~是1。
use config
db.settings.find()

那我們在來檢查一下資料大小是不是我們算錯,呃也沒算也,size為4188890的確是4mb左右。
user test
db.users.stats()

這問題目前無解,官網目前也只說當
chunk成長到超過設定大小時會進行分拆。傳送門給你看。
chunk的分配在說明完chunk的拆分後,我們要說明一下chunk的分配,也就是指mongos如何將chunk分配給分片。
mongos中有個東西叫balancer,這東西就是負責chunk的搬移,它會週期性的檢查分片是否存在不均衡,如果有不均衡情況,它就會自動開始搬遷chunk,你可以根據下面指令來看看balancer的訊息。
use config
db.locks.find()
執行結果如下,其中who就說明了我們的balancer在那個地方,我們的則是在"who" : "LindeMBP:20006這台上面。

這邊也要問題個問題,什麼是不均衡情況?
根據官網的說明,假設某個分片裡的chunk數量,多於其它的分片某個數量,就被認定為不均衡情況,但這邊也有個數量級距,請看下表一下,我們以第一行小於20這個來說明,它主要是說,當你的chunk數量小於20時,你的最多chunk的分片與最少chunk的分片差超過2時,就會開始進行搬遷。
chunk數量 |
遷移閾值 |
|---|---|
| 小於20 | 2 |
| 20-79 | 4 |
| 大於80 | 8 |
這邊也有一點要注意。
mongodb有提供手動分配
chunk的功能,所以在沒打開balancer的情況下也可手動將chunk分配給其它的分片。
chunk分配的實作。首先我們先來看看我們的分片狀態如何,我們執行sh.status(),我們可以發現,所有的chunk都集中在shared0000,正常來說應該是平均分配,為啥了?

我們可以用下面指令,來檢查看看我們上面所說的balancer有沒有開啟。
use config
db.settings.find().pretty()
下圖為結果,你可以看到咱們的balancer的stopped為true,可以知道我們的balancer是停止的,所以咱們要用下面指令來打開來。

use config
sh.setBalancerState(true)
執行完後,balancer就是開始它的工作,來檢查分片有沒有均衡,如果不均衡就重分配,我在來執行看看sh.status()的結果。呼呼~分配完成332。

本篇文章中,我們將上一章節所缺少的一些觀念補齊,讓我們更加的了解到分片的原理,其它包含了chunk的分割條件已經一些資訊查看,並且還有chunk如何分配到分片的說明,接下來的一篇我們將說明片鍵的策略。
您好
看了您的MONGODB設定的教學
想要請教在30-23, 30-24 Sharding的主題
網路上找的資料建議架構是由ROUTER、CONFIG、SHARD 組成的
想請問這三個部分要怎麼設定呢
目前先架了三台MONGO 但是不知道該如何將其個別設定為ROUTER、CONFIG和SHARD
和他們之間關係的設定