1. 程式人生 > >微服務架構 (九): 分散式微服務下的資料一致性

微服務架構 (九): 分散式微服務下的資料一致性

2016.8.21, 深圳, Ken Fang

微服務都擁有各自的資料庫且微服務都是部署在一分散式的環境下的。所以, 微服務間要維持彼此間資料庫中的資料的一致性, 便需採用:

BASE – Basic Availability, Soft State, Eventual Consistency

分散式微服務採用 BASE, 以維持彼此間資料庫中的資料的一致性, 主要的思路是: 當某一個微服務 A 改變了其自身資料庫中的資料時, 因為, 微服務 A 與其他相關的微服務是分散式部署的, 也就是說, 其他的微服務並不會 (也沒辦法) 在與微服務 A 相同的資料庫交易 (DBTransaction) 中, 知道必需針對自身的資料庫, 也做出相對應的改變。

所以, 當微服務 A 改變了其自身資料庫中的資料時, 其他相關的微服務, 並未能實時跟進作出相對應的改變; 此時, 整體微服務架構下的相關資料,便形成了不一致性; 我們便稱這種不一致性的狀態是: Soft State。

當整體微服務架構下的相關資料是 Soft State時, 便需經過一段時間; 也許是幾分鐘, 也許是一個晚上…等等; 整體微服務架構下的相關資料才能達到一致性。

當整體微服務架構下的相關資料是由 Soft State, 經過一段時間後, 整體微服務架構下的相關資料達到一致性, 我們便稱這種一致性的狀態是: Eventual Consistency。

舉個例子說明下 BASE:

下表中有三個微服務。

三個微服務都同時各自擁有 Customer ID: ABC001 的客戶資料。

微服務

Customer ID

customer information

ABC001

customer wish list

ABC001

customer preference

ABC001

當 customer information 微服務, 被其外部的使用者介面要求: 刪去 Customer ID: ABC001 時, customer information 微服務便刪去了自身資料庫中的 Customer ID: ABC001 的資料。但是, customer wish list 微服務與 customer preference 微服務, 因為, 無法與 customer information 微服務同屬於同一個資料庫交易 (DB Transaction) 中, 所以, customer wish list 微服務與 customer preference 微服務, 並未實時跟進刪除自身資料庫中的 Customer ID: ABC001 的資料。

這時, 整體微服務架構下的相關資料, 便形成了如下表中的不一致性; 此時, 整體微服務架構下的相關資料的狀態是: Soft State。      

微服務

Customer ID

customer information

ABC001  [已刪除]

customer wish list

ABC001   [未刪除]

customer preference

ABC001   [未刪除]

架構師在 BASE下, 便能採取以下的四種架構設計方案, 使整體微服務架構下的相關資料從 Soft State 時, 經過一段時間後; 也許是幾分鐘, 也許是一個晚上…等等; 最終, 使得整體微服務架構下的相關資料, 達到一致性; Eventual Consistency。

A.      Batch Data Synchronization:

顧名思義此設計方案, 便是執行一批處理; 也許, 是在夜間執行 :

1.       刪除 customer wish list 微服務的資料庫中的 Customer ID:ABC001的資料。

2.       刪除 customer preference 微服務的資料庫中的 Customer ID:ABC001 的資料。

架構師在採用此方案時,必需先行確認: 未維持資料一致性的微服務; customer wish list 微服務與 customer preference 微服務; 是可以接受從 Soft State 到 Eventual Consistency, 需經過一段較長的時間的; 也許是一天, 或甚至是更久。

另外, 架構師在採用此方案時, 也應該清楚的知道: 此設計方案將使得各微服務間的資料庫, 因為, 批處理而形成了 “藕合”。

這就代表著, 有任何一個微服務在資料庫表節構上的任何的變更, 都將會造成批處理程式碼 (指令碼) 維護上的工作量; 假如, 某一個產品擁有上百或上千個微服務時, 則批處理程式碼 (指令碼) 維護的工作量, 往往會是一不小的負擔。

B.      Periodic Async Data Synchronization:

每隔一特定的週期時間; 5分鐘, 10 分鐘, 一小時…等等; 執行一批處理:

1.       檢查 customer information 微服務, customer wish list 微服務, customer preference 微服務, 是否有變更各自所擁有的資料庫的資料; 假如, 沒有變更, 便進入到下一個週期。

2.       在下一個批處理檢查週期到來前, customer information 微服務, 被其外部的使用者介面要求: 刪去 Customer ID: ABC001。

3.       下一個批處理檢查週期到來, 批處理便執行:

            i.    刪除 customer wish list 微服務的資料庫中的 Customer ID:ABC001的資料。

            ii.   刪除 customer preference 微服務的資料庫中的 Customer ID:ABC001 的資料。

此設計方案, 雖縮短了從 Soft State 到 Eventual Consistency, 所需經過的時間, 但, 也是與 Batch Data Synchronization 有著一樣的問題: 各微服務間的資料庫, 因為, 批處理而形成了 “藕合”。

C.      Request-Based Data Synchronization:

當 customer information 微服務, 被其外部的使用者介面要求: 刪去 Customer ID: ABC001時, customer information 微服務便刪去了自身資料庫中的 Customer ID: ABC001 的資料, 並同時以同步或非同步遠端呼叫的方式呼叫 customer wish list 微服務與 customer preference 微服務; 要求 customer wish list 微服務與 customer preference 微服務, 刪除 Customer ID: ABC001。

此設計方案雖因為微服務間直接的同步或非同步遠端的呼叫, 而不存在著各微服務間資料庫藕合的問題, 但是, 也存在著其他的問題:

1.       當 customer information 微服務, 刪去了自身資料庫中的 Customer ID: ABC001 的資料後, customer information 微服務便必需要知道, 它需同步或非同步遠端呼叫哪些的微服務? 假如, customer information 微服務少呼叫了一個微服務, 則將使得整體微服務的資料, 很難再維持一致性; 因為, 這樣的缺陷, 有時在數百, 甚至是數千個的微服務當中, 是相當不容易被定位到的。

2.       customer wish list 微服務與customer preference 微服務, 將必需要負責處理自身資料庫上的事務; 如:回退、確認是否有回傳資料庫處理確認的資訊給 customer information 微服務…等等。這將增加 customer wish list 微服務與 customer preference 微服務在開發與測試上的複雜度。

3.       當 customer information 微服務是採用同步呼叫 customer wish list 微服務與 customer preference 微服務時, customer information 微服務將必需等待 customer wish list 微服務與 customer preference 微服務回傳資料庫處理確認的資訊, 才能向其外部的使用者介面確認: Customer ID: ABC001 的資料已被成功的刪除。而這將使得 customer information 微服務的外部使用者介面, 將花費時間等待; 在效能上可能會有一不好的使用者體驗。

4.       customer wish list 微服務與 customer preference 微服務都有著重複的程式碼, 處理著自身資料庫上相同的事務。

D.      Event-Based Data Synchronization:

在微服務的架構中置入 Message Queue; 如:JMS, RabbitMQ。

當 customer information 微服務, 被其外部的使用者介面要求: 刪去 Customer ID: ABC001時, customer information 微服務便刪去了自身資料庫中的 Customer ID: ABC001 的資料, 並同時送出個事件到 Message Queue中; 宣告了customer information 微服務, 剛剛刪去了CustomerID: ABC001。

而因為 customer wish list 微服務與 customer preference 微服務訂閱了此事件, 所以, customer wish list 微服務與 customer preference 微服務, 便會因為此事件, 而被觸發並刪除了自身資料庫中的 Customer ID: ABC001 的資料。

這設計方案的優點是顯而易見的:

customer information 微服務、customer wish list 微服務、customer preference 微服務之間是完全解藕的; 微服務間不存在著資料庫間的藕合, 微服務間也不需知道對方是誰?