分割槽容錯如何保證?
在分散式系統設計中,需要遵循CAP理論,如果我們要讓一個服務具有容錯能力,那麼最常用最直接的辦法就是讓一個服務的多個副本同時執行在不同的節點上。但是,當一個服務的多個副本都在執行的時候,我們如何保證它們的狀態都是同步的呢,或者說,如果讓客戶端看起來無論請求傳送到哪一個服務副本,最後都能得到相同的結果?實現這種同步方法就是所謂的狀態機複製(State Machine Replication)。
狀態機複製的理論基礎是:如果叢集裡的每一個節點上都執行著相同的確定性狀態機S,並且所有的狀態機剛開始都處於同樣的初始狀態s0,那麼給予這些狀態機相同的輸入序列:
- {i1, i2, i3, i4, i5, i6, …, in}
這些狀態機必然會經過相同的狀態轉換路徑:
最終達到相同的狀態sn,同時生成相同的輸出序列:
- {o1(s1), o2(s2), o3(s3), …, on(sn)}
狀態機複製在實際應用中的一個例子就是MySQL叢集。我們知道,MySQL叢集中的master會把所有的操作記錄到binlog中,這裡的操作就是輸入序列I,然後slave會把master上的binlog複製到自己的relaylog中,然後再把relaylog裡的操作回放一遍(相當於執行了一遍輸入序列I)。所以,如果master和slave裡的狀態機是完全相同的,並且在執行序列I之前都處於相同的狀態下,那麼執行完序列I後,它們的狀態依舊是相同的(一致性)。
在執行輸入序列I的過程中,根據同步方式的不同,系統就有了強一致性和最終一致性。如果我們要求對於序列I中的每一個in, 都需要所有的服務副本確認成功執行了in,才能執行in+1,那麼這個系統就是強一致性的系統。如果我們取消掉這個限制,僅僅要求所有的服務副本執行相同的輸入序列I,但是完全各自獨立執行,而不需要在中間同步,那麼就有了最終一致性(各服務都會達到相同的最終狀態,但是達到的時間不確定)。
所有一致性演算法都會涉及到狀態機,而狀態機保證系統從一個一致的狀態開始,以相同的順序執行一些列指令最終會達到另一個一致的狀態。
以上是狀態機的示意圖。所有的節點以相同的順序處理日誌,那麼最終x、y、z的值在多個節點中都是一致的。
參考
http://www.mybatis.cn/archives/1194.html