分布式系統的優勢就是可以將多個計算機結點一起協調工作,完成一個單機難以解決的大任務。如果這個任務是純計算型的,而且可以拆分為若干個獨立的計算,即一個計算結果不需要依附另一個計算結果的完成。那么便可以將這個大的計算任務進行拆分,分配到不同結點來完成,最后匯總結果。
上述任務並不涉及到同步問題,但是在分布式系統中,還有很多的任務需要多個結點間的協同工作,就好比在一個公司內不同的職員需要做不同的工作,大家為了完成一個任務可能需要相互配合來完成,彼此之間的任務具有依賴性,一個人的工作進度可能影響整個任務的完成。不同的職員就好比分布式系統中的結點,為了完成一個任務,不同的結點明確自己在什么時間應該做什么事,就是同步。在現實生活中,這個問題相對好解決,因為每個人無時無刻都知道准確的北京時間,大家可用同一個時間來約束彼此的工作行為,相互配合完成工作,但是在分布式系統中,問題便有些復雜,因為每個機器結點的時間並不一定是一致的,各自的誤差不同導致經過時間的積累導致大家手中的時間不一致,會導致任務同步出錯,甚至導致災難性后果。
要解決同步問題,最先想到的就是和現實生活中一樣,整個集群同步統一時鍾(全局時鍾),可以利用衛星,這種方式確實可行,但是成本開銷比較大,而且很多環境中不一定能接收到衛星信號。
第二種方法就是計算機結點不利用外部的時間去對時,而是自己內部之間的時鍾進行對時。
首先看兩種算法:
Cristian算法有統一的服務器對時,所有的結點和這個內部服務器進行對時,但是不同的結點離服務器距離有一定差距,因為有傳輸時間,所以不夠精確。
可以粗糙的用(t1-t0)/2來估計傳輸時間,來減去誤差。
Berkeley算法沒有統一外部服務器,內部自己來進行。
思想:多個機器求平均,這樣誤差相互抵消,機器越多越接近真實時間。
以上兩種屬於全局統一物理時鍾,都是通過對時來完成。但是對時代價太高(對時頻率需要很高,網絡通信瀏覽大,不去進行昂貴的對時是我們追求的)於是想到邏輯時鍾的概念。
首先介紹Happens-Before概念:因為很多應用的同步問題並不一定需要精確到同樣的時間,可以僅僅是一個先后順序的約束,只定義誰先誰后,去掉不必要的時鍾同步,僅僅在需要同步的兩台機器上進行同步就可以了,解決物理時鍾不知道什么時候同步,頻率難以控制的問題。
規則:
解釋:HB1很好理解,對於單機來說只有一個執行的先后順序;HB2的意思是接收消息的時候調時間。保證接受機器的時間不能小於發送機器發送時的時間;HB3指happens—before關系具有傳遞性。
舉例:
圖中abcdf有happens before關系,而a,e執行先后沒有規定,都可以。
邏輯時鍾就是基於happens before關系建立起來的。
邏輯時鍾的一個實現:
順序計數器 (lamport時鍾)
舉例:
(上圖發送沒問題,回來的過程有問題,需要按規則修改)
ps:ab之間有happenbefore關系則a值小於b值(如H和E),但是如果a值小於b值則不一定a在b之前,比如圖中C3 H1,但是H和C的先后順序不確定。即數字大小並不能推出先后關系。
這就是邏輯時鍾的問題,僅憑數字時間無法推測出時間發生的先后順序,想像QQ群場景,AB發送消息,A先發B后發,按理應該C接受A、B這么一個順序,但是用lamport時鍾,A為3B為5,無論先A,改成4,然后B改成6還是先B改成6后A不變,最后都是6,沒什么差別,這時順序圖都是一樣的,無法保證接收AB的先后性(發送可以保證),也就是之前說的數字沒法控制先后順序。要想實現這種因果序列,則需要矢量時鍾。可以用全局序(QQ場景可以統一server,然后各個節點去拉取,有服務器一般都可以大大簡化系統設計難度。(選舉的集中式比純分布式簡化很多,我的理解就像zab和paxos這種區別。)集中式也是被廣泛運用的),如果沒有服務器或不能做全局序(純分布式lamport時鍾實現代價太大),就要用其他方法。於是就有了第三類向量時鍾。更深入的學習向量時鍾,參考博文:分布式系統:向量時鍾