標籤:mongodb塊區間
1、如何建立塊
在前面的已經瞭解MongoDB分區架構中塊的基本概念,那麼在此來講述如何建立塊?當你決定分配資料時,必須為塊區間選擇一個鍵(前面我們一直在用username)這個鍵叫做片鍵(shard key),片鍵可以是任意欄位或者欄位的組合,比如如下文檔中:
<pre name="code" class="java"><pre name="code" class="java">{"username":"paul","age":23}{"username":"simon","age":17}{"username":"widdly","age":16}{"username":"grill","age":95}{"username":"bertango","age":55}
如果我們選擇age欄位作為片鍵並得到一個塊區間[20,26),則此塊會包含以下文檔:
{"username":"paul","age":23}{"username":"grill","age":95}{"username":"bertango","age":55}
如你所見,這個塊中的所有文檔其age欄位值都在這個塊的區間內。
2、對集合分區
對一個集合分區時,無論集合裡有什麼資料MongoDB都只會建立一個塊,這個塊的區間使(負無窮,正無窮),其中負無窮是MongoDB可以表示最小值(也叫做$minKey),正無窮是最大值(也叫$maxKey)。
注意:如果被分區的集合中包含大量資料,MongoDB會立刻把這個初始化分割為多個較小的塊。
事實上,由於上面例子中的集合太小並不能觸發分割,所以在插入更多資料之前,都只有一個塊(負無窮,正無窮),儘管如此,為了達到示範的目的,我們假設這個資料量已經足夠大了。
MongoDB會把初始化塊(負無窮,正無窮)分割成為兩個新塊,分割位置一般選在已有資料區間的中點附近,因此,如果大約一半文檔的age欄位小於20,且另外一半大於20.MongoDB就會很可能會選擇20,這樣就得到兩個塊:(負無窮,20]和[20,正無窮),如果我們往塊[20,正無窮)裡繼續插入資料,它會再一次被分割(比如說分割成[20,30)和[30,正無窮)),這樣集合中就有了3個塊(負無窮,20)、[20,30)和[30,正無窮),在插入更多資料的同時,MongoDB會持續地將已有塊分割成更多的新塊。
塊的區間可以只包含一個值(比如僅包含使用者名稱為paul的使用者),但是各塊的區間必須互不相同(不能有兩個塊得區間同為["a","f"),另外也不能有區間有互相重疊的塊,而且每個塊得區間必須緊鄰下一個塊的區間,因此如果要分割一個區間為[4,8)的塊,結果可以使[4,6)好[6,8)(因為二者合起來能覆蓋原塊得區間),但不可以是[4,5)和[6,8)(因為這樣集合將丟失區間[5,6)中的所有資料),也不能是[4,6)和[5,8)(因為會造成塊得部分重疊),每個文檔必須屬於且僅屬於一個塊,如示範一個塊分割成兩個塊:
說明:
由於MongoDB不強制要求任何形式的結構定義,你可能會納悶,那沒有值可以作為片鍵的文檔會被放到哪裡呢?
實際上MongoDB並不允許插入無片鍵的文檔(儘管使用null作為片鍵也是可以的),也不允許修改文檔的片鍵值(如用$set命令)。給文檔一個新片鍵的唯一方法是先刪除文檔,然後在用戶端修改片鍵的值,再重新插入文檔。
如果在一些文檔中使用字串,而在另外一些文檔中使用數字呢?這也是可以的,因為在MongoDB中類型之間有嚴格的次序,如果在age欄位插入一個字串(或者數組、布爾值、null等),MongoDB會按照類型對其排序,類型先後次序如下:
null<數字<字串<對象<數組<位元據<objectId<布爾值<日期<Regex。
在同一種類型內,排序與你所期望的很可能相同:2<4或者a<z,在理解分區的例子中每一個塊都是幾百GB大小,但在真實系統中,塊大小預設僅有200MB,這是因為挪動資料的代價非常大,要花費很長的時間,佔用系統資源,而且會明顯增加網路流量,你可以自己試試看,先插入200MB資料到某一個集合中,然後試著取回所有200MB資料,接著想象一下在建多個索引的系統上做同樣的事情,同時該系統上還有其他資料流量存在的情況,你肯定不會願意看著應用程式逐漸降低效能直到停止,而MongoDB還在後台拖拖拉拉地挪動資料,實際上,如果一個塊過大,MongoDB根本就不會移動它,反過來你也不會希望塊過小,因為每個塊都需要有一點點管理開銷(以便你不必為跟蹤不計其數的資料區塊而煩惱),綜合考慮之下,我們發現200MB恰好是兼顧可移動性和最小開銷的最佳選擇。
總結:
塊是一個邏輯概念,而非物理實現,一個塊中的文檔在物理上並不連續儲存於磁碟上或者以任何形式聚集在一起,它們可能分散在整個集合的任何角落裡,一個文檔屬於一個塊若且唯若其片鍵值在對應的塊區間內。
第五部分 架構篇 第十七章 MongoDB Sharding 架構(理解塊)