關於弱一致性、強一致性、順序一致性
在分散式資料系統中,也有一個帽子原理(CAP Theorem),不過此帽子非彼帽子。CAP原理中,有三個要素,CAP原理指的是,這三個要素最多隻能同時實現兩點,不可能三者兼顧:
- 一致性(Consistency)
- 可用性(Availability)
- 分割槽容忍性(Partition tolerance)
一致性就是資料保持一直,可以理解為多個節點中資料的值是一致的,一致性又可以分為強一致性與弱一致性。對於一致性,可以分為從客戶端和服務端兩個不同的視角。
從客戶端來看:一致性主要指的是多併發訪問時更新過的資料如何獲取的問題。多程序併發訪問時,更新過的資料在不同程序如何獲取的不同策略,決定了不同的一致性。
從服務端來看:則是更新如何複製分佈到整個系統,以保證資料最終一致。一致性是因為有併發讀寫才有的問題,因此在理解一致性的問題時,一定要注意結合考慮併發讀寫的場景。對於關係型資料庫,要求更新過的資料能被後續的訪問都能看到,這是強一致性。如果能容忍後續的部分或者全部訪問不到,則是弱一致性。如果經過一段時間後要求能訪問到更新後的資料,則是最終一致性。
1.強一致性:也稱為原子一致性、線性一致性。強一致性可以理解為在任意時刻,所有節點中的資料是一樣的。同一時間點,你在節點A中獲取到key1的值與在節點B中獲取到key1的值應該都是一樣的。任何一次讀都能讀到某個資料的最近一次寫的資料,系統中的所有程序,看到的操作順序,都和全域性時鐘下的順序一致。
2.順序一致性:任何一次讀都能讀到某個資料的最近一次寫的資料,系統的所有程序的順序一致,而且是合理的。即不需要和全域性時鐘下的順序一致,錯的話一起錯,對的話一起對。
3.弱一致性:弱一致性包含很多種不同的實現,目前分散式系統中廣泛實現的是最終一致性。
最終一致性是弱一致性的一種特例,保證使用者最終能夠讀取到某操作對系統特定資料的更新。但是隨著時間的遷移,不同節點上的同一份資料總是在向趨同的方向變化。也可以簡單的理解為在一段時間後,節點間的資料會最終達到一致狀態。對於最終一致性最好的例子就是DNS系統,由於DNS多級快取的實現,所以修改DNS記錄後不會在全球所有DNS服務節點生效,需要等待DNS伺服器快取過期後向源伺服器更新新的記錄才能實現。最終一致性根據更新資料後各程序訪問到資料的時間和方式的不同,又可以區分為:
1.因果一致性:如果程序A通知程序B它已更新了一個數據項,那麼程序B的後續訪問將返回更新後的值,且一次寫入將保證取代前一次寫入。與程序A無因果關係的程序C的訪問遵守一般的最終一致性規則。
2.讀己之所寫一致性:當程序A自己更新一個數據項之後,它總是訪問到更新過的值,絕不會看到舊值。這是因果一致性模型的一個特例。
3.會話一致性:這是上一個模型的實用版本,它把訪問儲存系統的程序放到會話的上下文中。只要會話還存在,系統就保證“讀己之所寫”一致性。如果由於某些失敗情形令會話終止,就要建立新的會話,而且系統的保證不會延續到新的會話。
4.單調讀一致性:如果程序已經看到過資料物件的某個值,那麼任何後續訪問都不會返回在那個值之前的值。
5.單調寫一致性:系統保證來自同一個程序的寫操作順序執行。要是系統不能保證這種程度的一致性,就非常難以程式設計了。
同時最終一致性的不同方式可以進行組合,從服務端角度,如何儘快將更新後的資料分佈到整個系統,降低達到最終一致性的時間視窗,是提高系統的可用度和使用者體驗非常重要的方面。對於分散式資料系統:
- N — 資料複製的份數
- W — 更新資料是需要保證寫完成的節點數
- R — 讀取資料的時候需要讀取的節點數
1.如果W+R>N:則是強一致性,寫的節點和讀的節點重疊。例如對於典型的一主一備同步複製的關係型資料庫。N=2,W=2,R=1,則不管讀的是主庫還是備庫的資料,都是一致的。
2.如果W+R<=N:則是弱一致性。例如對於一主一備非同步複製的關係型資料庫,N=2,W=1,R=1,則如果讀的是備庫,就可能無法讀取主庫已經更新過的資料,所以是弱一致性。
對於分散式系統,為了保證高可用性,一般設定N>=3。不同的N,W,R組合,是在可用性和一致性之間取一個平衡,以適應不同的應用場景。
- 如果N=W,R=1,任何一個寫節點失效,都會導致寫失敗,因此可用性會降低,但是由於資料分佈的N個節點是同步寫入的,因此可以保證強一致性。
- 如果N=R,W=1,只需要一個節點寫入成功即可,寫效能和可用性都比較高。但是讀取其他節點的程序可能不能獲取更新後的資料,因此是弱一致性。這種情況下,如果W<(N+1)/2,並且寫入的節點不重疊的話,則會存在寫衝突