複習Amazon Dynamo設計的一點分享

2021-08-29 19:45:36 字數 4461 閱讀 7023

author

:文初

email

[email protected]

blog

:什麼是

dynamo? dynamo

是amazon

的高效key-value

儲存基礎元件(類似於現在被廣泛應用的

memcached cache

),當前被用於

amazon

很多系統中作為狀態管理元件。在

2007

年年底amazon

的cto

就寫了一篇介紹

dynamo

eventual consistency

」。這也讓我再次仔細的去回顧了一下

dynamo

的設計思想,其中很多設計技巧是當前分布式系統設計也可以借鑑的。

在說幾個設計技巧以前先說幾個分布式設計的需求和概念。 1.

eventual consistency

。這個概念在阿里系中支付寶架構設計貫徹的最徹底,記得看魯肅的關於支付寶事務處理中提出的軟事務的概念其實就是

eventual consistency

的一種表現。對於系統設計來說,系統中的事件往往都會相互關聯,孤立的事件在當前的網際網路行業中變得微乎其微。事件與事件之間存在著一系列的約束和因果關聯,就需要靠事務來保證。事務的特質就是

acid

,而acid

在當前分布式系統設計的模式下常常會和可用性以及高效性產生衝突。

acid

中其他三者都很好理解,而

c 「一致性」往往是初學者比較難以理解的乙個特質。用銀行存款操作的比喻就較為容易理解,銀行帳戶在操作前有

100元,存入了

50元以後,就有了

150元,操作前和操作後保持了銀行帳戶的一致性,存入

50元以後帳戶僅僅增加了

50元,總額沒有超過

150或者少於

150,在常規看來是在正常不過的了,但是試想,如果有兩個操作在乙個瞬間作操作,乙個需要給賬戶增加

50元,乙個要給賬戶增加

30元,前乙個操作是基於

100元的基礎增加,後乙個也是基於

100元增加,然後後乙個操作晚於前乙個操作提交,那麼最後帳號裡面就只有

130,這就是可以認為銀行帳號在兩次操作以後出現了狀態不一致性。一致性就好比自然界平衡,降水、蒸發維持生態平常。

eventual consistency

其實是對一致性的一種延展,過程中允許部分不一致,但是在事務處理結束或者有限的時間內保持事務的一致性。一句話簡單概括就是:「過程松,結果緊,最終結果必須保持一致性」。 2.

可用性,容錯性,高效性。這三個非功能性需求在當前架構設計中已經成為最基本的設計要求,但三者常常在設計中又存在矛盾。容錯性要高就需要作更多額外的工作,而更多的額外工作必將降低高效的特點,同時額外工作也會間接增加系統複雜度進而影響可用性。在設計中協調者三者的關係,沒有什麼準則可以遵循,只有根據實際的系統狀況來判斷如何達到最好的效果,在後面的

dynamo

的三個引數配置設計就可以看到通過配置如何平衡三者關係並且將元件應用到上層系統中。 3.

分布式設計中兩類一致性問題:單點資料讀寫一致性問題和分布式資料讀寫一致性問題。前者通常通過資料儲存的服務端控制即可(類似於

db的控制),後者通常通過訊息傳播的方式來實現(類似於

jgroup

在多播通道傳播同步訊息)。 4.

衝突解決。這個我想大部分開發者每天都會接觸到,**控制(

svn)就是版本控制發現衝突的具體體現。衝突檢測通常最簡單採用

last write

的方式,也就好比資料庫的解決方式,誰最後修改就以誰的為準。其他衝突檢測和版本合併就十分複雜,有些不得不靠人工干預。這點也是在資料一致性通過多版本方式來解決的時候遇到的問題。

dynamo

設計中的學習點 1.

consistent hashing

演算法支援分布式多節點 簡單

hash

演算法:n

為node

數量。處理主鍵為

key的節點為:

key.hashvalue() mod n。

consistent hashing

演算法:環狀結構。虛擬節點來替換實體節點被分配到環狀某一位置上(根據處理能力不同可以將乙個實體節點對映到多個虛擬節點上)。主鍵為

key的節點

position = hash(key),

在環上按照順時針查詢

value

大於position

的第乙個虛擬節點,由它對應的實體節點處理。下圖中

k就優先由虛擬節點

b來處理。  

的優點:(其實主要作用是在虛擬節點以及環狀負責制上) a.

支援不同能力節點的權重設定。由於採用了虛擬節點,通過虛擬節點和實體節點多對一的配置可以實現處理能力權重配置。 b.

新增或者刪除節點動態配置成為可能,比較上一種簡單演算法,由於實體節點的數目直接影響到了

hash

演算法,因此導致新增或者刪除節點影響全域性資料的重新對映。而

consistent hashing

演算法不受節點數目影響,它的區間負責以及多節點冗餘處理降低動態增減節點的內容失效影響。在一些情況下需要不重新啟動而動態的增加或者減少處理節點,因此採用了

consistent hashing

的區間負責制,就好比上圖

key k

的內容落在了a和

b的區間內,根據規則由

b優先來處理,當

b失效的時候也可以由

c,d來處理,根據環狀最近可用節點來選擇。如果在

b節點和

a節點新增乙個節點或者刪除

b節點,影響的資料處理對映也僅僅是是a和

b區間內資料。 c.

同時對於壓力分攤也有幫助。這個優勢還是沿用

b來說,新增、刪除或者失效乙個實體節點,它可能對應的是多個虛擬節點,此時資料壓力會分攤到環狀其他的多個節點,新增也是同樣,這樣可以降低壓力分攤的風險。

consistent hashing

演算法其實也可以採用

tree

方式來實現

,memcached

的客戶端版本中就有支援採用

tree的。

2.vector clock

管理資料多版本

為什麼會存在資料多版本,其實這個在高併發分布式處理中經常會遇到,同時也是容錯性和高可用性的一種解決方式。兩方面來看,首先在高併發分布式處理過程中,對於單個資源的操作要麼採用阻塞方式要麼採用多版本方式,前者效率相對較低但是處理簡單,後者效率高但是處理複雜。對於容錯性和高可用性要求高的情況下,多版本也是一種解決手段,就好比

amazon

的購物車就要求任何時候都要支援修改,如果某一些處理節點當前不可用,那麼就需要支援多個節點的處理以及資料多點的儲存,這樣就出現了不同節點資料的不同版本問題。

vector clock

根據操作者的不同為乙個物件建立了多個版本計數器,並且通過多個版本計數器來判斷這些版本是否屬於並行分支還是序列分支,由此來確定是否需要解決衝突。

解決衝突分成兩種方式,一種是客戶端選擇如何解決衝突,一種是服務端解決衝突。前者適用於較為複雜的衝突解決,後者適用於簡單的版本衝突解決。不過不論哪一種方式,在

dynamo

的處理中,客戶端和服務端之間對於物件的操作互動過程都會帶有版本歷史資訊。  

上圖是描述乙個物件d的

vector clock

歷史狀況。首先d被

sx節點處理,那麼處理以後產生了第乙個版本

d1([sx,1])

,然後又被

sx處理了,產生了第二個版本

d1([sx,2])

,因此需要判斷是否需要版本衝突解決。判斷版本衝突主要是檢查

vector clock

中的多個版本與上乙個歷史

vector clock

的關係,如果歷史的和當前的

vector clock

中所有的節點版本都是大於等於的關係,那麼就認為兩個版本不衝突,可以忽略前乙個版本。就拿d2和

d1來看,裡面只有乙個

sx的版本記錄,對比2大於

1,因此就認為可以忽略前乙個版本。d3和

d4分別是基於

d2版本,兩個不同節點處理後的結果,根據上面的衝突檢測可以認為d3和

d4版本無法忽略任何乙個版本,因此此時對於

d物件來說存在兩個版本d3和

d4,當

sx從服務端獲取到資料以後做處理,此時就產生了三個版本。至於這三個版本由客戶端

sx來解決還是服務端後期自動通過後台完成這個就需要根據應用來決定了。

vector clock

android layout weight設定解讀

參考文章 android layout weight的真實含義是 一旦view設定了該屬性 假設有效的情況下 那麼該 view的寬度等於原有寬度 android layout width 加上其在剩餘空間中的佔比!設螢幕寬度為l,在兩個view的寬度都為match parent的情況下,原有寬度為l...

Android RecyclerView設定空布局

1 自定義乙個emptyrecyclerview繼承recyclerview 2 採用adapterdataobserver觀察者模式來監聽資料的變化,如果有資料就隱藏空布局,反之,則顯示。view memptyview private adapterdataobserver emptyobserv...

Capacity Scheduler 佇列設定

先附乙個官網位址 capacity scheduler是yarn中預設的資源排程器。資源分配相關引數 1 capacity 佇列的資源容量 百分比 當系統非常繁忙時,應保證每個佇列的容量得到滿足,而如果每個佇列應用程式較少,可將剩餘資源共享給其他佇列。注意,所有佇列的容量之和應小於100。2 max...