解讀NoSQL代表Dynamo

NoSQL在過去的一年裏,逐漸已經成爲了家喻戶曉的東西,我(54chen)自從去年開始人人網的NoSQL系統Nuclear的研發以來,一直 看着NoSQL越來越熱,越來越引來大家的圍觀。受infoQ霍師傅之託,特作此文,一來作過去一年的總結,二來希望以平白的話語對NoSQL系統在國內 的發展獻綿薄之力。

1.我眼中的兩種模式

NoSQL其實並不是什麼妖魔鬼怪,相反的,NoSQL的真諦其實應該是Not Only SQL,其產生是在數據量和訪問量的增大下,人爲地去添加機器、切分數據到不同的機器,變得越來越困難,人力成本越來越高,於是便開始有了這樣的項目,本 意是提高數據存儲的自動化程度,減少人爲干預的時間,讓負載更加均勻。在國際上,真正的代表之作有來自Google的 BigTable 和Amazon 的Dynamo,他們分別使用了不同的基本原理。

1.1 MapReduce

這是歷史最久的一種模型,典型的代表是BigTable。Map表示映射,Reduce表示化簡。MapReduce通過把對數據集的大規模操作分 發給網絡上的每個節點實現可靠性(Map);每個節點會週期性的把完成的工作和狀態的更新報告回來(Reduce)。大多數分佈式運算可以抽象爲 MapReduce操作。Map是把輸入Input分解成中間的Key/Value對,Reduce把Key/Value合成最終輸出Output。這兩 個函數由程序員提供給系統,下層設施把Map和Reduce操作分佈在集羣上運行。

1.2 dynamo

我把dynamo專門歸納成爲了一種,的確是這樣的,它與MapReduce不同,自成一派。來說歷史,Amazon於2006年推出了自己的雲存 儲服務S3,2007年其CTO公佈了S3的設計方案,從此江湖中就不再太平了,開源項目一個個如雨後春筍般地出現了。比較常見的有facebook開發 的Cassandra(如果沒有記錯,在去年來到他們的項目網頁的時候,上面還寫着他們之中的一個開發人員是dynamo的設計人員,現在風頭緊了,去掉 了),還有linkedin的voldemort,國內的話,有豆瓣網的beansDB,人人網的nuclear等等。這次主要講的也是dynamo的方 案細節。

2.入門基礎
Dynamo的意思是發電機,的確,這一整套的方案都像發電機一樣,源源不斷地提供服務,永不間斷。以下內容看上去有點教條,但基本上要理解原理,這每一項都是必須知道的。

2.1 CAP原則
先來看歷史,Eric A. Brewer教授,Inktomi公司的創始人,berkeley大學的計算機教授,Inktomi是雅虎搜索現在的臺端技術核心支持。最主要的是,他們 (Inktomi公司)在最早的時間裏,開始研究分佈計算。CAP原則的提出,可以追溯到2000年的時候(可以想象有多麼早!),Brewer教授在一 次talk中,基於他運作inktomi與在伯克利大學裏的經驗,總結出了CAP原則(後附當年的slide)。圖2.1來自Brewer教授當年所畫的 圖:
cap
圖2.1

Consistency(一致性),數據一致性,簡單的說,就是數據複製到了N臺機器,如果有更新,要N機器的數據是一起更新的。
Availability(可用性),好的響應性能,此項意思主要就是速度。
Partition tolerance(分區容錯性),這裏是說好的分區方法,體現具體一點,簡單地可理解爲是節點的可擴展性。

定理:任何分佈式系統只可同時滿足二點,沒法三者兼顧。
忠告:架構師不要將精力浪費在如何設計能滿足三者的完美分佈式系統,而是應該進行取捨。

2.2 DHT

DHT(Distributed Hash Table,分佈式哈希表),它是一種分佈式存儲尋址方法的統稱。就像普通的哈希表,裏面保存了key與value的對應關係,一般都能根據一個key去對應到相應的節點,從而得到相對應的value。
這裏隨帶一提,在DHT算法中,一致性哈希作爲第一個實用的算法,在大多數系統中都使用了它。一致性哈希基本解決了在P2P環境中最爲關鍵的問題——如何 在動態的網絡拓撲中分佈存儲和路由。每個節點僅需維護少量相鄰節點的信息,並且在節點加入/退出系統時,僅有相關的少量節點參與到拓撲的維護中。至於一致 性譁然的細節就不在這裏詳細說了,要指明的一點是,在Dynamo的數據分區方式之後,其實內部已然是一個對一致性哈希的改造了。

3.進入Dynamo的世界

有了上面一章裏的兩個基礎介紹之後,我們開始進入Dynamo的世界。

3.1 Dynamo的數據分區與作用

在Dynamo的實現中提到一個關鍵的東西,就是數據分區。
假設我們的數據的 key 的範圍是0到2的64次方(不用懷疑你的數據量會超過它,正常甚至變態情況下你都是超不過的,甚至像伏地魔等其他類Dynamo系統是使用的 2^31-1),然後設置一個常數,比如說1000,將我們的key的範圍分成1000份。然後再將這1000份key的範圍均勻分配到所有的節點(s個 節點),這樣每個節點負責的分區數就是1000/s份分區。
如圖3.1,假設我們有A、B、C三臺機器,然後將我們的分區定義了12個。
dynamo數據分區
圖3.1

因爲數據是均勻離散到這個環上的(有人開始會認爲數據的key是從1、2、3、4。。。這樣子一直下去的,其實不是的,哈希計算出來的值,都是一個 離散的結果),所以我們每個分區的數據量是大致相等的。從圖上我們可以得出,每臺機器都分到了三個分區裏的數據,並且因爲分區是均勻的,在分區數量是相當 大的時候,數據的分佈會更加的均勻,與此同時,負載也被均勻地分開了(當然了,如果硬要說你的負載還是隻集中在一個分區裏,那不是這裏討論的問題了,有可 能是你的哈希函數是不是有什麼樣的問題了)。

爲什麼要進行這樣的分佈呢,分佈的好處在於,在有新機器加入的時候,只需要替換原有分區即可,如圖3.2所示:
dynamo數據分區
圖3.2

同樣是圖3.1裏的情況,12個分區分到ABC三個節點,圖3.2中就是再進入了一個新的節點D,從圖上的重新分佈情況可以得出,所有節點裏只需要 轉移四分之一的數據到新來的節點即可,同時,新節點的負載也伴隨分區的轉移而轉移了(這裏的12個分區太少了,如果是1200個分區甚至是12000個分 區的話,這個結論就是正確的了,12個分區只爲演示用)

3.2 從Dynamo的NRW看CAP法則

在Dynamo系統中,第一次提出來了NRW的方法。
N – 複製的次數
R – 讀數據的最小節點數
W – 寫成功的最小分區數
這三個數的具體作用呢,是用來靈活地調整Dynamo系統的可用性與一致性的。
舉個例子來說,如果R=1的話,表示最少只需要去一個節點讀數據即可,讀到即返回,這時是可用性是很高的,但並不能保證數據的一致性,如果說W同時爲1的 話,那可用性更新是最高的一種情況,但這時完全不能保障數據的一致性,因爲在可供複製的N個節點裏,只需要寫成功一次的話就返回了,也就意味着,有可能在 讀的這一次並沒有真正讀到需要的數據(一致性相當的不好)。如果W=R=N=3的話,也就是說,每次寫的時候,都保證所有要複製的點都寫成功,讀的時候也 是都讀到,這樣子一定讀出來的數據是正確的,但是這中間的性能大打折扣,也就是說,數據的一致性非常的高,但系統的可用性卻非常低了。如果R + W > N能夠保證我們“讀我們所寫”,Dynamo推薦使用322的組合使用可。
Dynamo系統的數據分區讓整個網絡的可擴展性其實是一個固定值(你分了多少區,實際上網絡裏擴展節點的上限就是這個數),通過NRW來達到另外兩個方向上的調整。

3.3 Dynamo的一些增加可用性的補救
針對一些經常可能出現的問題,Dynamo還提供了一些解決的方法。
第一個是hinted handoff數據的加入:在一個節點出現臨時性故障時,數據會自動進入列表中的下一個節點進行寫操作,並標記爲handoff數據,在收到通知原節點恢復時重新把數據推回去。這能使系統的寫入成功大大提升。
第二個是向量時鐘來做版本控制:用一個向量(比如說[a,1]表示這個數據在a節點第一次寫入)來標記數據的版本,這樣在有版本衝突的時候,可以追溯到出 現問題的地方。這可以使數據的最終一致成爲可能。(Cassandra未用vector clock, 而只用client timestamps也達到了同樣效果。)
第三個是Merkle tree來提速數據變動時的查找:使用Merkle tree爲數據建立索引,只要任意數據有變動,都將快速反饋出來。
第四個是Gossip協議:一種通訊協議,目標是讓節點與節點之間通信,省略中心節點的存在,使網絡達到去中心化。提高系統的可用性。

關於作者
54chen(陳臻),人人網分佈式存儲研究人員,業餘時間混跡於各技術組織且樂此不疲。目前關注實施PHP培訓。對flex等前端技術有一點研究。個人 技術站點:http://www.54chen.com/ 。可以通過電子郵件 [email protected] 聯繫到他。

參考的網站

http://project-voldemort.com/

http://cassandra.apache.org/

http://s3.amazonaws.com/AllThingsDistributed/sosp/amazon-dynamo-sosp2007.pdf

http://timyang.net/data/dynamo-flawed-architecture-chinese/

http://www.cs.berkeley.edu/~brewer/

http://www.54chen.com/document/dynamo-based-systems.html

http://www.cs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf

http://en.wikipedia.org/wiki/Distributed_hash_table

http://en.wikipedia.org/wiki/Consistent_hashing

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章