對於mongodb的sharding(分片)技術並不陌生,但是發現裡面其實還是有不少值得深入學習的東西。筆記整理一下發上來跟大家分享。
一、mongodb分片機制:
1、乙個分片包含資料的某一子集。若某一分片包含多台伺服器。則每台伺服器都擁有完整的資料副本。
2、一分片多區間:
乙個區間資料稱為乙個資料塊(chunk)。當我們把乙個塊的區間一分為二時,乙個塊也變成了兩個塊。
當乙個塊變得越來越大時,mongodb會自動將其分割成兩個較小的塊。如果分片間比例失調,則mongodb會通過遷移塊來確保均衡。
3、如何建立塊:
當決定分配資料時,必須為塊區間選擇乙個鍵,這個鍵叫做片鍵,片鍵可以是任意欄位或字段的組合。
分片是對集合分片。在插入更多資料的同時,mongodb會持續地將已有塊分割成更多的新塊。
塊的區間可以只包含乙個值,但是各塊的區間必須互不相同,也不能有區間相互重複的塊,而且每個塊的區間必須緊鄰下乙個塊的區間。
每個文件必須屬於且僅屬於乙個塊。
真實系統中,塊大小預設僅有200m,200m恰好是兼顧可移動性和最小開銷的最佳選擇。
塊是乙個邏輯概念,而非物理實現。乙個塊中的文件在物理上並不連續儲存於磁碟上或以任何形式聚集在一起,它們可能分散在整個集合的任何角落裡。乙個文件屬於乙個塊當且僅當其片鍵值在對應的塊區間內。
4、片鍵:
因為mongodb不強制要求定義文件結構,所以mongodb不允許插入無片鍵的文件(儘管可以使用null作為片鍵值),也不允許更新文件的片鍵值。給文件乙個新片鍵唯一只能先刪除文件,再在客戶端修改片鍵的值後,重新插入文件。
允許一些文件中片鍵使用字串,另一些文件中使用數字。mongodb中型別有嚴格的次序,mongodb會按照型別對其排序:
null《數字《字串《物件《陣列《二進位制資料5、平衡:
如果存在多個可用分片,只要塊的數量足夠多,mongodb就會把資料遷移到其它分片上,整個遷移過程叫平衡。由叫做平衡器的程序負責執行。
平衡器的優點在於自動化,它每天基於分片整體大小來移動塊。要保持資料均勻分布,還要最小化被移動的資料量。
要觸發一輪平衡,乙個分片必須比塊最小的分片多出至少9個塊。通過等待更嚴重的不平衡發生,mongodb能夠最小化無意義的資料傳輸。
6、自定義塊大小與遞增塊大小:
自定義塊大小:--chunksize n (n就是想要的塊大小),請勿隨意改動塊大小。
遞增塊大小:mongodb對於前十幾個塊,mongodb會特意自動降低塊大小,從200m降到64m,這就是為了更好的照顧使用者,當資料塊多起來,它會自動把塊大小遞增回200mb。
7、mongos允許把乙個集群當做一台伺服器。
二、片鍵
1、選擇片鍵:
(1)小基數片鍵:由於片鍵值數量有限,因此稱為小基數片鍵。如果選擇了乙個基數很小的片鍵,到頭來肯定會得到一堆既巨大又無法移動,還不能分割的塊。
如果打算用小基數片鍵的原因是需要在那個欄位上進行大量查詢,請使用組合片鍵(乙個片鍵兩個字段),並確保第二個欄位有非常多不同的值可以供mongodb用來進行分割。
片鍵值無法更新,因此也不可能通過更新所有文件來使用乙個更獨特的片鍵值。
(2)公升序片鍵:
人們往往會嘗試使用諸如時間戳或者ojbectid一類的字段來做片鍵,但這並不像他們所期望的那樣可行。這種片鍵創造了單一且不可分散的熱點。
包括objectid、日期、自增主鍵,只要鍵值趨向於無窮大,就會面臨這個問題。
除非自己清楚在幹什麼,否則不要使用公升序片鍵。
(3)隨機片鍵:
為了避免熱點,人們會選擇乙個取值隨機的字段來分片。這種片鍵一開始還不錯,但隨著資料量增大,它會變得越來越慢。
考慮到資料序列的隨機性,一般情況下這些資料可能不會出現在記憶體中。所以此時的mongodb會給ram帶來更大的壓力,而且還會引發大量磁碟io。
另外片鍵上必須有索引,因此如果選擇了從不依據它進行查詢的隨機鍵,基本上可以說浪費了乙個索引。(每增加乙個索引都會使寫操作變慢,所以保持索參數量盡可能低也是非常重要的)。
2、好片鍵:
(1)準公升序鍵加搜尋鍵:希望資料大致上按照時間排序,但是同時也要均勻分布。這樣既能把我們正在讀寫的資料保持在記憶體,又可以使負載均衡的分散在集群中。
(2)可以通過組合片鍵來實現目標:。
其中coarselyascending鍵的每個值最好能對應幾十到幾百個資料塊,而search鍵則應當是應用程式通常都會依據其進行查詢的字段。search欄位不可以是公升序片鍵,如果是則會遇到使用公升序片鍵同樣的問題。search欄位應該具備非公升序、分布隨機且基數適當的特點。
(3)基於上面的內容,概括出的片鍵公式:.
其中coarselocality欄位用來控制資料區域性化。search欄位則是資料上常用到的乙個檢索字段。
三、集合分片:
1、配置伺服器只是普通的mongod例項,由於需要它們中的部分配置伺服器一直正常執行,所以把它們分到不同的故障域裡。
2、分片還不支援認證,但在2.0版已發生變化。
3、應該使用副本集而非單個伺服器來做每個分片。
4、如果伺服器嚴重失衡,應該使用maxsize選項指定分片能增長到的最大儲存量,單位mb。
5、mongodb不會從maxsize處截斷乙個分片,或是阻止它再增加哪怕乙個位元組,而是會停止將資料移動到該分片,當然還可能會移走一部分資料。所以設定這個值時可以略微低一些。
6、對已經包含資料的集合進行分片,資料片鍵上必須有索引。所有文件必須也都必須有片鍵值(且不能為null)。在集合分片完成後,才可以插入片鍵值為null的文件。
7、如果等伺服器容量耗盡再新增分片,新分片可能會導致應用程式在一系列連鎖反應下逐步癱瘓。要在有足夠空間做排程時新增分片,如果沒有就等到夜間再新增分片,所以新增分片要盡早做,經常做。
四、使用集群:
1、計數:當在乙個分片集合上進行計數時,可能得不到期望結果,可能是乙個比實際文件量多的數。因為如果有乙個遷移正在進行,許多文件就會同時存在於多個分片上,計數值可能會大於實際的文件數。
通過複製將乙個塊遷移到新的分片上,然後再從源分片上將它刪除。
2、通常要確保分片間不存在重複,唯一方法是在每次要執行寫操作時鎖住整個集群,直至寫操作確認成功。這樣系統很難實現高效能寫。
因此,除片鍵以外的任何鍵都難以保證唯一性,可以保證片鍵的唯一性是因為特定文件只能屬於乙個資料塊。只需要在那個分片上唯一,就能保證在整個集群中是唯一的。
因此推出乙個結論:除非在_id上分片,否則能夠建立出不唯一的_id值,這確實是可能的。
3、更新:
如果要更新單個文件,一定要在條件中使用片鍵(update的第乙個引數)。如果不這麼做,會提示錯誤禁止更新。
在批量更新中可以使用任何條件。
如果碰到奇怪的錯誤,考慮一下執行的操作是否對整個集群必須是原子化的,這類操作是不被允許的。
4、mapreduce:
每個分片都會執行它自己的對映(map)及收斂(reduce)。mongos選出乙個領頭羊分片以接受來自其他分片的收斂結果並在此完成最後收斂,一旦資料被收斂到最終形態,就會按照指定的方式輸出。
分片將任務分解到多台機器,因此能比單台伺服器更快地執行mapreduce,但它仍不適合做實時運算。
UIApplication深入學習
新建乙個任意型別的ios應用工程,加入我們在class prefix輸入是tc,我們可以看到工程中生成乙個類 在main函式中,autoreleasepool 函式中 說明 當應用程式將要入非活動狀態執行,在此期間,應用程式不接收訊息或事件。比如來 了。說明 當應用程式入活動狀態執行,這個剛好跟上面...
深入學習CSS
什麼是css?在之前的這篇文章中已經介紹了初步的介紹,詳細請看 div加css進一步講解了css中的內容,先總結如下圖 其實在實際開發中,我們通常採用是外部樣式的匯入,這樣做的好處是對於很對有同樣設計樣式的頁面可以實現樣式的共享,這樣我們不僅僅可以節省了大量的時間,並且也方便我們可以靈活的呼叫的樣式...
block深入學習
block的宣告和使用看上一節就行了。本章主要講block內部的實現過程及原理。block的定義和函式指標非常相似 對比一下 block定義 void someblock 函式指標定義 void functionpionter void functionname 當然區別還是有的,block的返回型...