分散式資料管理 - 實作 AWS 上的微型服務

分散式資料管理

整合型應用程式的背後,通常具有大型的關聯式資料庫,此資料庫會定義所有應用程式元件共同的單一資料模型。如果使用微型服務方法,建置分散式和各自獨立元件的目標,會因為此等中央資料庫而無法達成。每個微型服務元件,都應該擁有自己的資料持久層。

不過,分散式資料管理也帶來了新的挑戰。根據 CAP 定理的推論,分散式的微型服務架構,本質上就在一致性與效能之間做了權衡取捨,需要追求最終的一致性。

在分散式系統中,商業交易可能橫跨多個微型服務。由於不能使用單一 ACID 交易,所以可能會產生部分執行的情況。在此情況下,我們將需要某些控制邏輯,來重做已處理的交易。而分散式 Saga 模式經常用於此目的。發生商業交易失敗時,Saga 會協調一系列的補償性交易,以復原先前交易所做的變更。AWS Step Functions 可讓您輕鬆實作 Saga 執行協調器,如下圖所示。

Saga 執行協調器

使用核心資料管理工具和程序,來策劃建置重要參考資料的集中存放區,這為微型服務提供了方法,將重要的資料進行同步,亦可回復狀態。使用 Lambda 搭配排程的 Amazon CloudWatch 事件,可讓您建置簡單的清除與重複資料刪除機制。

狀態的變更,經常會影響不只一個微型服務。在這些案例中,事件來源已經過驗證為實用的模式。事件來源的核心概念,是將每次應用程式的變更,以事件記錄的方式呈現和保存。事件來源並未保存應用程式的狀態,而是將資料儲存為事件的串流。資料庫的交易記錄與版本控制系統,是廣為人知的兩個事件來源範例。事件來源具有幾項優點:可以判斷和重建任何時間點的狀態。這自然地就會產生持久的稽核軌跡,也有助於進行除錯。

在微型服務架構的脈絡中,事件來源可利用發佈/訂閱模式,將應用程式的不同部分解耦,並且將相同的事件資料,饋送給不同微型服務的不同資料模型。事件來源經常搭配 命令、查詢、權責、隔離 (CQRS) 模式使用,將讀取與寫入工作負載分開,並同時針對讀取與寫入作業,進行效能、可擴展性和安全性的最佳化。在傳統的資料管理系統中,會對同一個資料儲存庫執行指令與查詢。

下圖顯示如何在 AWS 上實作事件來源模式。Amazon Kinesis Data Streams 會做為集中事件存放區的主要元件,將應用程式的變更擷取為事件,並將這些事件保存於 Amazon S3 中。該圖顯示三種不同的微型服務,這些服務由 Amazon API Gateway、AWS Lambda 和 Amazon DynamoDB 組成。箭頭代表事件的流程:當微型服務 1 發生事件狀態變更時,會藉由將訊息寫入 Kinesis Data Streams,來發佈事件。所有的微型服務,都會在 AWS Lambda 中,執行自己的 Kinesis Data Streams 應用程式,來讀取訊息的副本、根據微型服務的相關性篩選此副本,也可能轉傳此副本,以進行進一步的處理。如果您的函式傳回錯誤,Lambda 會不斷重試批次直到處理成功或資料過期。若要避免停滯的碎片,您可設定事件來源映射以較小的批次大小進行重試、限制重試次數,或捨棄太舊的記錄。若要保留已捨棄的事件,您可設定事件來源映射將失敗批次的相關詳細資訊傳送至 Amazon Simple Queue Service (Amazon SQS) 佇列或 Amazon Simple Notification Service (Amazon SNS) 主題。

AWS 上的事件來源模式

Amazon S3 可以將所有的事件,持久地儲存到所有的微型服務,在除錯、回復應用程式狀態或進行應用程式變更的稽核時,也是真確事實的單一來源。有兩個主要原因可能會導致多次將記錄交付至您的 Kinesis Data Streams 應用程式:生產者重試和消費者重試。您的應用程式必須預料並妥善因應多次處理個別記錄的問題。