建議程式設計師都讀一讀的31篇論文系列筆記(1~2)
序:前幾日網上偶然看到”程式設計師必讀論文系列“,順便搜了一下,發現有多個版本共31篇,不過看起來都不錯,故準備花時間都讀一下,可以拓寬下視野。來源論文題目主要參考 http://blog.csdn.net/turingbook/article/details/3946421 和 http://top.jobbole.com/17733/ 。每讀完一篇論文就寫些筆記,或長或短,也就是這幾篇文章的由來。
1. An Axiomatic Basis for Computer Programming. 1969年的一篇論文,主要講用公理基礎證明計算機程式設計的正確性,包括賦值/遞推/組合/迴圈等。不是那麼容易讀懂,特別是一些數理符號,想要完全看懂估計得查不少書。掃過重要的部分,關鍵就是 P{Q}R, 即前置條件滿足assert(P) 為true,Q是一段程式(可以是多個子程式的組合),後置條件R是人們可以期望的正確結果,跟Q的執行輸出有關,若assert(R)為true,可以證明Q是正確的程式。
2. Dynamo: Amazon’s Highly Available Key-value
Store.2007年的這篇論文長達16頁,詳細介紹了曾經服務於Amazon Services的一個key/value 分散式儲存系統,包括背景需求,設計與實現,同類產品的研究工作,生產過程中使用Dynamo的經驗等。Amazon Services是高度去中心化,鬆耦合和以服務為導向的架構,故Dynamo也是去中心化的,對於Amazon Services來說只需要通過Key查詢資料,故傳統關係型資料庫複雜的查詢邏輯在此派不上用場,此外關係型資料庫也沒有很好的複製技術,以便支撐因為負載均衡而產生的資料庫的擴充套件和分割槽需求。如下圖所示。一個客戶端請求需要多個services服務,需要Aggregator
Services來做聚合。一個node認為是一臺host,一個instance是多個node的集合,一個services使用自己的instances。
Dynamo
的可擴充套件性和可用性採用的都比較成熟的技術,資料分割槽並用改進的(virtual node)一致性雜湊[3](consistent hashing)方式進行復制,利用資料物件的版本化和vector clock實現最終一致性。更新時因為副本之間產生的一致性問題的維護採取類似 quorum[1] 的機制以及去中心化的複製同步協議[2]。
Dynamo的實現是一個最終一致性的資料儲存,對於分散式系統的CAP原理來說,犧牲了部分一致性,也就是弱一致性模型,提高可用性,即”always writeable"。
對於資料衝突的解決並不是傳統的 read only write all,而是類似quorum機制把部分壓力給了read。而解決衝突的執行者不是application而是data store,使用的是簡單的"last write wins" 策略。
資料分割槽策略:採用改進的一致性雜湊演算法,也就是引入virtual nodes,即可以將一個真實物理host對映為n個虛擬nodes,這樣可以實現load balance,特別是不同物理host的容量不一致的情況下,比如容量大的主機的n值可以大些。
資料複製策略:Dynamo 會將資料複製在N臺host上,N是一個instance的配置引數。通常除由一個協調node儲存在本地外,還負責複製到它的兩個順時針走向的N-1個node上。注意,如果使用了virtual node,則負責如下圖Key K (K=hash(dataobject))的 preference list 會跳過一些位置,以保證list只包含真正的物理nodes。To account for node failures, preference list contains more than N nodes.
如上圖所示,Key K 的資料會存在node B, C, D(N=3)。同理對於node D來說,Node D will store the keys that fall in the ranges (A, B], (B, C], and (C, D].
資料同步策略:採用類似於 Quorum 系統的一致性協議實現(“sloppy quorum”: all read and write operations are performed on the first N healthy nodes from the preference list, which may not always be the first N nodes encountered while walking the consistent hashing ring.)。這個協議有兩個關鍵值:R 與 W。R 代表一次成功的讀取操作中最小參與節點數量,W 代表一次成功的寫操作中最小參與節點數量。R + W>N ,則會產生類似 quorum 的效果。該模型中的讀(寫)延遲由最慢的 R(W)副本決定,為得到比較小的延遲,通常R 和 W各自的值設定得比 N 小。
若(N,R,W) 的值設定為 (3, 2 ,2)。舉例get()和put()操作來說,讀寫通常由一個協調node來處理(preference list的第一個node)。
對於一個key的put()操作,協調node會為此版本的資料產生vector clock 類似[Sx, 1](Sx表示node),並將資料寫在本地,此外會將資料帶上vector clock資訊傳送給另外N-1=2個node,但只要W-1=1個node回應就表示說寫成功(當然最後一個node的寫程式還是在進行的)。
同樣地,對於一個key的get()操作,協調node會向所有存在此資料任何版本的node發起請求(包括自己),如果有R=2個node響應表示讀取成功。如果此時兩個版本的資料不一致,協調node會進行合併操作並將最新的版本write back。
注:對於一般的session資訊儲存,是由協調node來執行"last write wins" 合併資料版本。而類似購物車資訊之類的是由application logic 自己來執行合併資料版本。
資料容災策略:以上圖N=3為例,如果在一次寫操作時發現節點A掛了,那麼本應該存在A上的副本就會傳送到D上,同時在D中會記錄這個副本的元資訊(MetaData)。其中有個標示,表明這份資料是本應該存在A上的,一旦節點D之後檢測到A從故障中恢復了,D就會將這個本屬於A的副本回傳給A,之後刪除這份資料。Dynamo中稱這種技術為“Hinted Handoff”。另外為了應對整個機房掉線的故障,Dynamo中應用了一個很巧妙的方案。之前說過“Preference List”,每次讀寫都會從這個列表中取出R或W個節點。那麼只要在這個列表生成的時候,讓其中的節點是分佈於不同機房的,自然資料就寫到了不同機房的節點上。
“Hinted Handoff”的方式在少量的或是短暫的機器故障中表現很好,但是在某些情況下仍然會導致資料丟失。如上所說,如果節點D發現A重新上線了,會將本應該屬於A的副本回傳過去,這期間D發生故障就會導致副本丟失。為了應對這種情況,Dynamo中用了基於 Merkle Tree[4]的Anti-Entropy系統,如下圖所示:
A Merkle tree is a hash tree where leaves are hashes of the values of individual keys. Parent nodes higher in the tree are hashes of their respective children. 也就是說如果比對兩個副本,只需要從root節點開始比對,如果相等則資料一致,否則繼續找子節點比對下去,直至找到hash值不一致的節點,同步這部分資料即可。
夥伴關係和失敗發現策略:
由於各種各樣的原因,暫時性的節點掉線是時有發生的。如果因為一個節點暫時性的掉線,而導致副本遷移等代價高昂的操作顯然是不合適的。所以Dynamo提供了一組命令列介面和HTTP介面供管理員手工新增,刪除節點。一旦一個節點的角色發生改變(上線或下線等),它都會將狀態改變的時間儲存到一個持久的資料庫中,這些資料構成了一個節點的狀態變遷歷史。然後通過一個Gossip-Based Protocol 將這個訊息傳遞出去。節點在收到其它節點的訊息時,會將收到的訊息與自己本地儲存的訊息進行合併,最終每個節點都會得到整個叢集的資訊。為了應對可能出現的“logical partitions”現象,某些Dynamo節點作為“種子”節點,種子節點可以通過全域性的方式被其它所有節點發現,最終所有的節點自己儲存的狀態資訊都與種子節點的狀態資訊合併。與正常節點發現類似,對錯誤節點的發現機制也是使用的Gossip-Based Protocol,每個節點都記錄自己與其它節點的連通狀態。
具體實現:Dynamo的一個儲存node主要由三個元件組成,包括請求處理、夥伴關係與失敗檢測、持久型儲存引擎。這三者都是用java實現。對於儲存引擎來說,提供多種選擇,application可以選擇適合自己的引擎,比如 Berkeley Database (BDB) Transactional Data Store2, BDB Java Edition, MySQL, and an in-memory buffer with persistent backing store.
參考:
[1]. http://www.cnblogs.com/jzhlin/archive/2012/07/23/Quorum.html
[2]. http://dbanotes.net/tech-memo/amazon_dynamo.html
[3]. http://dl.acm.org/citation.cfm?id=258660
[4]. http://blog.csdn.net/xtu_xiaoxin/article/details/8148237
相關文章
- 一個程式設計師的讀書筆記:程式設計的反思程式設計師筆記
- 《程式設計師的吶喊》讀書筆記程式設計師筆記
- 一個程式設計師的讀書筆記——關於程式設計的反思程式設計師筆記
- MapReduce 論文閱讀筆記筆記
- Raft論文讀書筆記Raft筆記
- SSD論文閱讀筆記筆記
- 9/12讀論文筆記筆記
- 《程式設計師的自我修養》-讀書筆記程式設計師筆記
- 讀書筆記 - 《程式設計師的自我修養》筆記程式設計師
- 《程式設計師自我修養》讀書筆記程式設計師筆記
- 《程式設計師修煉之道》讀書筆記程式設計師筆記
- AutoEmbedding論文閱讀筆記筆記
- 程式設計師生存指南讀書筆記-第三篇(學習)程式設計師筆記
- 兩篇知識表示方面的論文閱讀筆記筆記
- 卓有成效的程式設計師 讀書筆記程式設計師筆記
- 《Java程式設計思想》讀書筆記一Java程式設計筆記
- 每個程式設計師都應該讀的書程式設計師
- 《改善python程式的91個建議》讀書筆記Python筆記
- 設計師的讀書筆記!帶你重新全面認識色彩系列之紅色篇筆記
- 【深度學習 論文篇 02-1 】YOLOv1論文精讀深度學習YOLOv1
- 程式設計師生存指南讀書筆記-第四篇(生產力)程式設計師筆記
- 《程式設計師的修煉之道從小工到專家》閱讀筆記2程式設計師筆記
- 高效程式設計師的45個習慣 讀書筆記程式設計師筆記
- week1讀構建之法-讀書筆記筆記
- 國外程式設計師推薦:每個程式設計師都應讀的書程式設計師
- 一個老程式設計師的建議程式設計師
- 每個程式設計師都必讀的10篇文章程式設計師
- 程式設計師修煉之道——從小工到專家讀書筆記2程式設計師筆記
- 共識演算法論文閱讀筆記1-hotstuff演算法筆記
- Rework:每個程式設計師都應該讀的一本書程式設計師
- 程式設計師修煉之道——第一章讀書筆記程式設計師筆記
- 《程式碼整潔之道——程式設計師的職業素養》讀書筆記(一)程式設計師筆記
- CornerNet-Lite論文閱讀筆記筆記
- 每個程式設計師都應該讀《Unix程式設計藝術》程式設計師
- PointNet系列論文解讀
- 《程式設計匠藝》讀書筆記程式設計筆記
- 國外程式設計師推薦:每個程式設計師都應該讀的非程式設計書程式設計師
- 《JavaScript Dom程式設計藝術》讀書筆記(一)JavaScript程式設計筆記