本篇文章將要說明mongodb的分片,上一章節說明了如何將資料同步到其它台節點上,而本篇文章是將要說明,如何將資料分割到其它台節點,讓我們可以更快速、更多容量空間的來做一些哩哩扣扣的事情。
分片是啥 ? 它主要的概念就是將collection拆分,將其分散到不同的機器,來分擔單一server的壓力。
咱們先來看看我們平常單一server的mongodb結構,其中mongod就代表我們實際上存放資料的地方,它平常都是指令和client端通信,client就有點像咱們平常用的mongodb shell之類的。

而咱們在來看看,如果用了分片會變啥樣,如下圖,三個mongod都會統一通信到mongos,在和client進行通訊,mongos不存儲任何資料,它就是個路由server,你要什麼資料就發給它,它在去決定去那個mongod裡尋找資料。

那這邊有個問題來囉~這三個mongod要著麼決定誰要存放那些資料 ? 答案是下面標題片鍵~
Shard Keys片鍵是啥 ? 它就是當你要進行分片時,你選定的collection切分的依據,假設我們有下面的資料。
{ "name":"mark" , "age" :18}
{ "name":"steven" , "age" :20}
{ "name":"ian" , "age" :20}
{ "name":"jack" , "age" :30}
{ "name":"stanly" , "age" :31}
{ "name":"jiro" , "age" :32}
{ "name":"hello" , "age" :41}
{ "name":"world" , "age" :52}
...
...
...
{ "name":"ho","age" : 100}
它就有可能會分片成這樣,假設咱們拆分為三片,然後我們指定片鍵為age欄位,它就大致上可能會分成這樣,會根據片鍵建立chunk,然後再將這堆chunk分散到這幾個分片中,{min~10}就是一個chunk,就是一組document。
| 分片001 | 分片002 | 分片003 |
|---|---|---|
| { min ~ 10 } | { 30 ~ 40 } | { 60 ~ 70 } |
| { 10 ~ 20 } | { 40 ~ 50 } | { 70 ~ max } |
| { 20 ~ 30 } | { 50 ~ 60 } |
這邊事實上有很多東西可以思考,例如片鍵的選者或分片設計等,這些主題將留在後面幾篇在來介紹,你之要先大概只知片鍵是啥的就好了。
首先咱們先在單機上來建立看看,一樣先進入mongodb shell。
mongo --nodb
然後使用ShardingTest來建立分片用的cluster,其中shards為3代表建立3個分片,而chungszie之後會講,先簡單設1就好。
cluster = new ShardingTest({ "shards" : 3 , "chunksize" :1})
執行完我們可以看到它的輸出。

然後就準備換到另一個shell,接下來我們就可以連接到mongos囉,根據我們上面的結果可知,我們的mongos是建立在port : 20006的位置,來連吧~
db = ( new Mongo("127.0.0.1:20006")).getDB("test")
進去以後我們來丟些資料,來測試看看。
var objs = [];
for (var i=0;i<1000000;i++){
objs.push({"name":"user"+i});
}
db.users.insert(objs);
然後我們可以執行sh.status()來看看這個cluster的運行狀況。

但是我們的分片可還沒啟用喔,它還需要執行這行指令。
sh.enableSharding("test")
呃對了~上面的指令只是允許test這資料庫可以使用分片了,但在進行分片前,我們還要先決定要如何針對collection進行拆分,這時我們就要選擇片鍵sharing key,它將根據某個欄位進行拆分,這邊注意,只要索引過的鍵才能夠作為片鍵,所以我們要先建索引。
db.users.ensureIndex({"name":1})
然後再針對collection分片,test.users第一個是資料庫,第二個是collection。
sh.shardCollection("test.users",{"name":1})
然後執行完看到這個結果就代表ok~
{ "collectionsharded" : "test.users", "ok" : 1 }
然後咱們在來看一下sh.status()的結果。

其中可以看到他shared0000裡已經將collection開拆成很多個chunk囉,不過因為我們Balancer的東西還沒啟動,所以還沒分配到其它shard,這篇我們下章節在來說說。

然後我們來搜尋看看詳細資訊,下圖結果可以知道它去這shard0000尋找到doument,並且就如同索引一樣,不需要全部掃描來尋找,是的你可以把片鍵想成索引。
db.users.find({"user889391"}).explain("executionStats")

本篇文章中,我們學習了分片的基本知識,也簡單的介紹建立分片的方法,但事實上還有很多分片的原理我們沒有完全說到,例如如何分片、片鍵的選擇、chunk的拆分,這些我們後面幾篇都會來說明說明。