分布式入门:常用的分布式基础算法
中間件在分布式系統中的地位和角色
為了使種類各異的計算機和網絡都呈現為單個的系統,分布式系統常常通過一個“軟件層”組織起來,該層在邏輯上位于由用戶和應用程序組成的高層與由操作系統組成的低層之間,這樣的分布式系統又稱為中間件。中間件層延伸到了多臺機器上,且為每個應用程序提供了相同的接口。它的重要的目的是提供一定程度的透明性,也就是一定程度上向應用程序隱藏數據處理的分布性。中間件集分布式操作系統與網絡操作系統的優點于一身,既能夠具有網絡操作系統的可擴展性和開放性,又能夠具有分布式操作系統的透明性和與之相關的易用性。
分布式系統進程通信,rpc基本原理步驟
移動agent特點
自主性;反應性;主動/面向目標;推理/學習/自適應能力;可移動性;社會性。
命名服務(優缺點)
移動實體定位
并發,petri網建模
哲學家進餐
圖解:
h-hunger k-thinking f –fork/chopstick e-eating
以哲學家0為例
- T1 變遷1(感到饑餓):哲學家在思考中感到餓了,從庫所k0經過T1到達庫所h0。哲學家從思考狀態進入饑餓狀態。
- T2變遷2(獲得筷子):哲學家和筷子分別從h0,f4,f0庫所經過T2遷移到庫所e0。哲學家從饑餓狀態進入吃飯狀態。
- T3變遷3(釋放筷子):吃完飯后,哲學家經過T3遷移到k0庫所中,從吃飯狀態轉入思考狀態。兩只筷子經過T3,分別遷移到庫所f0,f4,從使用狀態進入備用狀態。
生產者消費者
移動mogent通信失效(本地和異地)的解決方案
- 分析
- 無論本地通信還是異地通信,其通信模型是一致的
- 通信失效本質上都是因為在路由信件和實際信件傳輸過程中,目標agent發生了物理位置的變化,而這種變化是隨機的,不可預計的。
- 結論
- 通信失效現象并不是mogent系統特有的現象.它是一個因agent的移動而帶來的可能會出現在任意一個移動agent系統中的普遍現象
- 其它系統的處理
- Aglets:未見
- Mole:
- 將失效信件扔棄;
- 扔棄的同時回送錯誤信息
- 將失效信件就地保存,待被通信agent在回送時交付
- 根本原因:
- 移動:隨機改變位置信息
- 通信:要求位置信息“暫時”不變
- 通信和移動所共享的“位置”信息未進行同步控制是造成通信失效的根本原因
- 從OS進程互斥考慮,接收者的“位置”在通信失效問題中具有決定性的意義,當通信和移動相矛盾時,該“位置”就成為了一個必須互斥使用的“資源”
- “位置”的互斥 =》 “狀態”的互斥
- 在一個能夠避免通信失效的移動agent系統中,必須且只要做到以下三條 :
- 準確紀錄agent的狀態信息
- 只能向一個處于“靜止態”的agent發送信件
- 信件發送過程中必須限制接收者從“靜止態”向“移動態”的狀態轉換
同步:邏輯時間算法,向量時間戳(將每個時間的向量時間戳標出)
Lamport算法:不能反應因果關系。
向量時鐘 :要求能計算出每個進程中的事件,標出向量的時間戳,不同事件之間的向量時間的大小關系,依賴關系與并發關系。
邏輯時鐘
- 為了同步邏輯時鐘,Lamport定義了一個稱作 “先發生” (happens-before) 的關系。表達式a?b讀作 “a在b之前發生”,意思是所有進程一致認為事件a先發生,然后事件b才發生。這種先發生關系有兩種情況。
- 如果a和b是同一個進程中的兩個事件,且a在之前發生,則a?b為真。
- 如果a是一個進程發送消息的事件,而b為另一個進程接收消息的事件,則a?b也為真。消息不可能在發送之前被修改,也不能在發送的同時被接收,這是因為消息需要一定時間才能到達接收端。
- Lamport邏輯時間鐘具有傳遞性和并發性;
- 對這個算法稍作補充就可以滿足全局時間的需要。即在每兩個事件之間,時鐘必須至少滴答一次。如果一個進程以相當快的速度發送或者接受兩個消息,那么它的時鐘必須在這之間至少滴答一次。
- 在某些情況下還需要一個附加條件,即兩個事件不會精確地同時發生。為了達到這個目標,我們可以將事件發生所在的進程號附加在時間的低位后,并用小數點分開。這樣,如果進程1和進程2中的事件都發生在時刻40,那么前者記為40.1后者記為40.2。
- 使用這種方法,我們現在有了一個為分布式系統中的所有事件分配時間的方法,它遵循下面的規則:
- 若同一進程中a在b之前發生,則C(a)<C(b)。
- 若a和b分別代表發送一個消息和接收該消息的事件,則C(a)<C(b)。
- 對于所有不同的事件a和b,C(a) ≠ C(b)。
- 這個算法為我們提供了一種對系統中所有事件進行完全排序的方法。許多其他的分布式算法都需要這種排序以避免混淆,所以文獻中廣泛引用此算法。
- 使用Lamport時間戳后,只通過比較事件a和b各自的時間值C(a)和C(b),無法說明它們之間的關系。換句話所,C(a)<C(b)不能說明事件a就是在事件b之前發生。還需要另外一些信息。即 Lamport時間戳不能捕捉因果關系(causality)。
向量事件戳
為什么采用向量時間戳可以表示事件因果關系?
- 因果關系可以通過向量時間戳來捕獲。分配給事件a的向量時間戳VT(a)具有下列性質:如果對某一事件b,有VT(a)<VT(b),那么認為事件a在因果關系上處于事件b之前。向量時間戳的創建是通過讓每個進程P維護一個向量V來完成的,該向量具有下面兩個性質:
- Vi[i]是到目前為止進程Pi發生的事件的數量。
- 如果Vi[j]=k,那么進程Pi知道進程Pj中已經發生了k個事件
- 第一個性質是通過在進程Pi中的新事件發生時遞增Vi[i]來維護的。
- 第二個性質時通過在所發送的消息中攜帶向量來維護的。當進程Pi發送消息m時,它將自己的當前向量作為時間戳vt一起發送。
- 使用這種方式,接收者可以得知進程Pi中已經發生的事件數。
- 更重要的是,接收者可以得知進程Pi發送消息m之前其他進程已經發生了多少個事件。換句話說,消息m的時間戳vt告訴接收者其他進程中有多少事件發生在它之前,并且消息m可能在因果關系上依賴于這些事件。
當進程Pj接收到消息m時,它調整自己的向量,將每項Vj[k] 設置為max{Vj[k],vt[k]}。該向量現在反映了進程Pj必須接收的消息數,該消息數目至少是在發送消息m之前見到的消息。此后將Vj[i]項增1,這表示接收消息m的事件是來自于進程Pi的下一個事件。
只在不違背因果關系限制時,才能使用向量時間戳來傳遞消息。我們來再次考慮一下電子公告板的例子。當進程Pi張貼一篇文章時,它將該文章作為消息a廣播出去,并且在該消息上附加一個時間戳vt(a),其值等于V。當另一個進程Pj接收到a時,它將調整自己的向量,以使Vj[i]=vt(a)[i]。現在假設進程Pj張貼了一個該文章的回復。回復是通過該進程廣播一個消息r實現的,消息r攜帶值等于Vj的時間戳vt(r)。注意vt(r)[i]> vt(a)[i]。假設通信是可靠的,包含文章的消息a和包含回復的消息r最終都到達了另一個進程Pk。因為我們沒有對消息的順序關系做出假設,所以消息r可能在消息a之前到達進程Pk。進程Pk接收到消息r時檢查時間戳,并決定推遲提交消息r,直到因果關系上位于r之前的消息都接收到了才提交。消息r只有下列條件滿足時才得到交付:
vt(r)[j]=vk[j]+1;
對于所有滿足i1j的i和j,vt(r)[i]< Vk[i]
第一個條件說明r是進程Pk正在等待的下一條來自進程Pj的消息。
第二個條件說明當進程Pj發送消息r時,進程Pk只看到被進程Pj看到的消息。這意味著進程Pk已經看到了消息。
一致性模型,要能寫出以客戶為中心的四個模型(條件描述)以數據為中心的三種類別(了解))
每一個以客戶為中心的一致性模型是單調讀的一致性模型。如果數據存儲滿足以下條件,那么稱該數據存儲提供單調讀一致性(monotonic-read consistency):
- 如果一個進程讀取數據x的值,那么該進程對執行任何后續讀操作將總是得到第一次讀取的那個值或更新的值。
也就是說,單調讀一致性保證,如果一個進程已經在t時刻看到x的值,那么以后他不再會看到較老的版本的x的值。
在很多情況下,寫操作以正確的順序傳播到數據存儲的所有拷貝是非常重要的。這種性質被描述為單調寫一致性。單調寫一致性(monotonic-write consistency)的數據存儲應該滿足以下條件:
- 一個進程對數據項x執行的寫操作必須在該進程對x執行任何后續寫操作之前完成。
下面介紹一種與單調寫一致性有密切關系的以客戶為中心的一致性模型。如果數據存儲滿足以下條件,那么稱該數據存儲提供寫后讀一致性(read-your-writes consistency)。
- 一個進程對數據項x執行一次寫操作的結果總是會被該進程對x執行的后續讀操作看見。
也就是說,一個寫操作總是在同一進程執行的后續讀操作之前完成,而不管這個后續的讀操作發生在什么位置。
最后一種以客戶為中心的一致性模型是這樣的模型,即更新是作為前一個讀操作的結果傳播的。如果數據存儲滿足以下條件,那么稱該數據存儲提供讀后寫一致性(writes-follow-reads consistency)。
- 同一個進程對數據項x執行的讀操作之后的寫操作,保證發生在與x讀取值相同或比之更新的值上。
也就是說,進程對數據項上x所執行的任何后續的寫操作都會在x的拷貝上執行,而該拷貝是用該進程最近讀取的值更新的。
代碼遷移(基礎、分類)
分布式系統中的代碼遷移是以進程遷移(process migration)的形式進行的,在這種形式下整個進程被從一臺機器搬到另一臺機器上去。其基本的思想是:如果把進程由負載較重的機器上轉移到負載較輕的機器上去,就可以提升系統的整體性能。(遷移的是計算程序本身,而非數據)
分類
- 弱可遷移性:在這種模型中,可以只傳輸代碼段以及某些初始化數據。弱可移動性的典型特征是,傳輸過來的程序總是以初始狀態重新開始執行的。
- 強可移動性(strong mobility):它還可以遷移執行段。強可移動性的典型特征是,可以先停止運行中的進程,然后將它搬到另一臺機器上去,再從剛才中斷的位置繼續執行。
分類(主動方):
- 發送者啟動(sender-initiated)遷移:在這種模型中,代碼當前駐留在哪臺機器上或者正在哪臺機器上執行,就由該機器來啟動遷移。一般來說,在向計算服務器上載程序時進行的就是發送者啟動的遷移。
- 接收者啟動(receiver-initiated)遷移:代碼遷移的主動權掌握在目標機器手中。Java小程序是這種遷移的一個例子。
事務提交:2pc\3pc
兩階段提交協議(2PC):考慮一個分布式事務中有很多進程作為參與者,每個進程都運行在不同的機器上。假定沒有故障發生,協議就由以下兩個階段組成,每個階段又由兩步組成。
- 協調者向所有的參與者發送一個Vote_Request消息。
- 當參與者接收到Vote_Request消息時,就向協調者返回一個Vote_Commit消息通知協調者它已經準備好本地提交事務中屬于它的部分,否則就返回一個Vote_Abort消息。
- 協調者收集來自參與者的所有選票。如果所有的參與者都表決要提交事務,那么協調者就進行提交。在這種情況下它向所有的參與者發送一個Global_Commit消息。但是,如果有一個參與者表決要取消事務,那么協調者就決定取消事務并多播一個Global_Abort消息。
- 每個提交表決的參與者都等待協調者的最后反應。如果參與者接收到一個Global_Commit消息,那么它就在本地提交事務,否則接收到一個Global_Abort消息時,就在本地取消事務。
- The finite state machine for the coordinator in 2PC.(協調者)
- The finite state machine for a participant.(參與者)
兩階段提交的一個問題在于當協調者崩潰時,參與者不能做出最后的決定。因此參與者可能在協調者恢復之前保持阻塞。三階段提交協議(3PC),避免了在出現故障停機時的阻塞過程。
三階段提交(3PC)
3PC的本質在于協調者和每個參與者都滿足以下兩個條件:
- 沒有一個可以直接轉換到Commit或者Abort狀態的單獨狀態。
- 沒有一個這樣的狀態:它不能做出最后決定,而且可以從它直接轉換到Commit狀態。
三階段提交協議(3PC)的基本原理為:在2PC的參與者投票和協調者決策之間增加了“預提交”階段。協調者在接收到所有參與者的提交票后發送一個全局預提交命令,當參與者接收到全局預提交命令之后,它就得知其他的參與者都投了提交票,從而確定自己在稍后肯定會執行提交操作,除非它失敗了。每個參與者都對全局預提交發出確認消息,協調者一旦接收到所有參與者的確認消息就再發出“全局性提交”。3PC協議在站點失敗,甚至是所有的站點都失敗的情況下也不會帶來阻塞。
它們各自的狀態機如圖所示。(a 協調者,b 參與者)
- 二者比較:
與2PC相比,3PC的主要不同點在于以下情況:崩潰的參與者可能恢復到了Commit狀態而所有參與者還處于Ready狀態。在這種情況下,其余的可能操作進程不能做出最后的決定,不得不在崩潰的進程恢復之前阻塞。在3PC中,只要有可操作的進程處于Ready狀態,就沒有崩潰的進程可以恢復到Init、Abort或Precommit之外的狀態。因此存活進程總是可以做出的最后決定。
復制和一致性(四個經典模型(不帶同步變量的))
嚴格一致性
條件定義:對于數據項x的任何讀操作將返回最近一次對x進行的寫操作的結果所對應的值。
嚴格一致性中存在的問題是它依賴于絕對的全局時間(注意由于技術的限制,我們需要處理同一時間間隔內所發生的多個操作)
(a)嚴格的一致性存儲; (b) 非嚴格的一致性存儲
總之,當數據存儲是嚴格一致的時候,對于所有的進程來說,所有寫
操作是瞬間可見的,系統維持著一個絕對的全局時間順序。(如果一
個數據項被改變了,那么無論數據項改變之后多久執行讀操作,無論
哪些進程執行讀操作,無論這些進程的位置如何,所有在該數據項上
執行的后續讀操作都將得到新數值。同樣,如果執行了讀操作,那么
無論多快地執行下一個寫操作,該讀操作都將得到當前的值。 )
順序一致性
條件定義:
任何執行結果都是相同的,就好像所有進程對數據存儲的讀、寫操作 時按照某種序列順序執行的,并且每個進程的操作按照程序所制定的 順序出現在這個序列中。
(a) 順序一致的數據存儲; (b)非順序一致的數據存儲
線性一致性
條件定義:當數據存儲上的每個操作都具有時間戳并滿足以下條件時,稱這個數據存儲是可線性化的。任何執行結果都是相同的,就好像所有進程對數據存儲的讀、寫操作是按某種順序執行的,并且每個進程的操作按照順序所執行的順序出現在這個順序中。另外,如果tsop1(x)<tsop2(y),那么在這個順序中,操作OP1(x)出現在操作OP2之前。 (注意,可線性化的數據存儲也是順序一致的。它們的區別在于:線性化是根據一系列同步時鐘確定序列順序的。在實際應用中,線性化主要用于開發算法的形式驗證。關于根據時間戳維護順序的附加限制使得線性化的實現比順序一致性的實現開銷更大。Tsop(x)---時間戳)。
因果一致性
因果關系理解:考慮一個存儲器的實例。假設進程P1對變量x執行了寫操作。然后進程P2先讀取x,然后對y執行寫操作。這里,對x的讀操作和對y的寫操作具有潛在的因果關系,因為y的計算可能依賴于P2所讀取的x值。沒有因果關系的操作被稱為并發的。
條件定義:所有進程必須以相同的順序看到具有潛在因果關系的寫操作。不同機器上的進程可以以不同的順序被看到并發的寫操作。
實現因果一致性要求跟蹤哪些進程看到了哪些寫操作。這意味著必須構建和維護一張記錄哪些操作依賴于哪些操作的依賴關系圖。一種實現方法是使用上一章所討論的向量時間戳。
分布式系統算法(選舉算法(欺負算法)、互斥算法(集中式帶協調者的、分布式不帶協調者的、recut、令牌環(不一定考)))
選舉算法
欺負算法
1.1 當任何一個進程發現協調者不再響應請求時,它就發起一個選舉。進程P按如下過程主持一次選舉:
- 1.1.1 P向所有編號比它大的進程發送一個election消息;
- 1.1.2 如果無人響應,P獲勝成為協調者;
- 1.1.3 如果有編號比它大的進程響應,則響應者接管選舉工作。P的工作完成。
- (a) 進程4主持一個選舉;
- (b) 進程5和6進行響應,告訴進程4停止選舉;
- (c) 進程5和6此時各自主持一個選舉;
- (d) 進程6通知進程5停止選舉;
- (e) 進程6獲勝,并通知每個進程。
互斥算法
集中式算法
只有一個協調者,無論何時一個進程要進入臨界區,它都要向協調者發送一個請求消息,說明它想要進入哪個臨界區并請求允許。如果當前沒有其他進程在該臨界區內,協調者就發送允許進入的應答消息。
- (a) 進程1請求協調者允許它進入一個臨界區。請求得到了批準;
- (b) 進程2也請求進入同一個臨界區。協調者不應答;進程2進入等待隊列
- (c) 進程1在退出臨界區時通知協調者,協調者然后做出應答。協調者再通知等待隊列中的排在最前面的進程2進入臨界區
- 優點:沒有進程會處于永遠等待狀態(不會出現餓死的情況);易于實現,每使用一次臨界區只需3條消息(請求、允許和釋放);不僅能用于管理臨界區,也可以用于更一般的資源分配。
- 缺點:協調者是一個單個故障點,所以如果它崩潰了,整個系統就可能癱瘓。在一般情況下,如果進程在發出請求之后被阻塞,那么請求者就不能區分“拒絕進入”和協調者已經崩潰這兩種情況,因為上述兩種情況都沒有消息返回。此外,在規模較大的系統中,單個協調者會成為性能的瓶頸。
分布式算法
該算法的工作過程如下:當一個進程想進入一個臨界區時,它構造一個消息,其中包含它要進入的臨界區的名字、它的進程號和當前時間。然后它將消息發送給所有其他的進程,理論上講也包括它自己。
當一個進程接收到來自另一個進程的請求消息時,它根據自己與消息中的臨界區相關的狀態來決定它要采取的動作。可以分為三種情況:
- 2.1 若接收者不再臨界區也不想進入臨界區,它就向發送者發送一個OK消息。
- 2.2 若接收者已經在臨界區,它不進行應答,而是將該請求放入隊列中。
- 2.3 如果接收者想進入臨界區但尚未進入時,它將對收到的消息的時間戳和包含在它發送給其余進程的消息中的時間戳進行比較。時間戳最早的那個進程獲勝。如果收到的消息的時間戳比較早,那么接收者向發送者發回一個OK消息。如果它自己的消息的時間戳比較早,那么接收者將接收到的請求放入隊列中,并且不發送任何消息。
在發送了請求進入臨界區的請求消息后,進程進行等待,直到其他所有進程都發回允許進入消息為止。一旦得到所有進程的允許,它就可以進入臨界區了。當它退出臨界區時,它向其他隊列中的所有進程發送OK消息,并將它們從隊列中刪除。
- (a) 兩個進程同時希望進入同一個臨界區;
- (b) 進程0具有最早的時間戳,所以它獲勝;
- (c) 當進程0退出臨界區時,它發送一個OK消息,所以進程2現在可以進入臨界區
- 優點:不會發生死鎖或者餓死現象;最大的優點是不存在單個故障點。
- 缺點:單個故障點被n個故障點所取代;要求更多網絡通信的算法;要么必須使用組通信原語,要么每個進程都必須自己維護組成員的清單,清單中包括進入組的進程、離開組的進程以及崩潰的進程。
令牌環
當環初始化時,進程0得到一個令牌token。該令牌繞著環運行,用點對點發送消息的方式把它從進程k傳遞到進程k+1(以環大小為模)。進程從它鄰近的進程得到令牌后,檢查自己是否要進入臨界區。如果自己要進入臨界區,那么它就進入臨界區,做它要做的工作,然后離開臨界區。在該進程退出臨界區后,它沿著環繼續傳遞令牌。不允許使用同一個令牌進入另一個臨界區。如果一個進程得到了鄰近進程傳來的令牌,但是它并不想進入臨界區,那么它只是將令牌沿環往下傳遞。
- 優點:不會發生餓死現象,那么最差的情況是等待其他所有進程都進入這個臨界區然后再從中退出后它再進去。
- 缺點:如果令牌丟失了,那么它必須重新生成令牌,檢測令牌丟失是很困難的;如果有進程崩潰,該算法也會出現麻煩,但是恢復起來比其他算法容易。
原文:幾個分布式基礎算法-博客-云棲社區-阿里云,作者:abbey_chenxi
與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的分布式入门:常用的分布式基础算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何构建一个分布式爬虫:实战篇
- 下一篇: 一个数独引发的惨案:零知识证明(Zero