Redis如何簡化實現微服務的設計模式 – thenewstack

banq發表於2020-10-09

本文討論Redis如何簡化微服務設計模式的實現:例如有界上下文,非同步訊息傳遞,基於編排的sagas,事件源,CQRS,遙測等。
微服務架構繼續變得越來越流行,但是卻被廣泛誤解。儘管大多數概念上都同意微服務應該是細粒度的且面向業務的,但通常對於架構的權衡和複雜性缺乏認識。例如,對於DevOps架構師來說,將微服務與Kubernetes相關聯是很常見的事情,而對於應用程式開發人員來說,將實現歸結為使用Spring Boot的情況很常見。儘管這些技術是相關的,但是容器和開發框架都無法獨自克服微服務架構的陷阱,尤其是在資料層。

Martin FowlerChris Richardson以及其他思想領袖早已解決與微服務架構和定義的相關特性權衡,成功指導實施。包括的原則又:隔離、自主團隊授權、擁抱最終一致性以及基礎設施的自動化。雖然遵循這些原則可以避免早期採用者和DIY者所遭受的痛苦,但將它們合併到體系結構中的複雜性擴大了對最佳實踐和設計模式的需求,尤其是隨著實現擴充套件到數百個微服務時。
隨著Redis迅速成為微服務體系結構的主要組成部分,值得討論如何簡化設計模式的實現-例如有限上下文,非同步訊息傳遞,基於編排的sagas,事件源,CQRS,遙測等。
 

設計模式:受限上下文/有界上下文/界限上下->域驅動設計
我們的第一個挑戰是從邏輯上將業務劃分為多個微子域,以便每個人都可以由一個授權的小型自治團隊提供支援。每個子域的範圍應受其團隊管理其支援的微服務生命週期的能力的約束-從開始到後期製作。這種從臨時專案到自主域所有權的轉變激發了對微服務設計各個方面的責任感,並賦予了敏捷的決策能力-從而縮短了產品上市時間。
考慮一下字首“微”,這暗示了在有限的業務子域中支援微服務的整個生命週期所需的團隊規模。
在我們的模型體系結構的上下文中,讓我們從付款處理域開始,開始組織設計過程,該域包括欺詐檢測,付款,結算等。由於這個範圍對於一個小型團隊來說可能太複雜了,因此,我們選擇將其所有權範圍縮小到欺詐檢測子域。

Redis如何簡化實現微服務的設計模式 – thenewstack
欺詐檢測由工作流的前三個微服務組成-包括數字身份,統計分析和基於AI的交易風險評分。由於他們的範圍可能仍然太小而無法管理,因此讓我們將欺詐檢測進一步分為兩個子域-最終看起來更易於管理。
在非常高的層次上,我們剛剛遵循的過程稱為域驅動設計(DDD),該過程受推薦的模式支援,該模式將每個微服務的範圍和所有權宣告繫結到一個稱為bounded context的業務子域。但是請稍等-Redis適合放置在哪裡?
注意,每個微服務都有其自己的專用資料庫以進行隔離。擁有藍色邊界上下文的授權自治團隊選擇RediSearch支援其“ Authenticate Digital Identity”微服務,並選擇RedisBloom支援其“機率欺詐檢測檢查點”微服務。同時,擁有紫色邊界上下文的另一個團隊選擇RedisAI實時支援“交易風險評分”。
儘管每個微服務都需要自己的最佳資料模型來處理其獨特的資料訪問模式和SLA,但使用Redis就不必需要評估、內建、管理三個不同的資料庫。實際上,使用Redis Enterprise,他們可以在單個多租戶群集中部署所有三個Redis資料庫,而無需考慮其釋出週期。
 

設計模式:非同步訊息傳遞->服務間通訊
既然我們已經為每個微服務確定了一個有限的上下文和最佳資料模型,那麼下一個挑戰就是在不破壞對隔離的合規性的情況下實現它們之間的通訊。這可以透過擁抱最終的一致性來解決,後者假定服務間通訊的接收端上的微服務在出站傳輸期間將不可用,但是,一旦恢復可用性,便可以使用該訊息。

Redis如何簡化實現微服務的設計模式 – thenewstack

服務間通訊的推薦模式是使用釋出-訂閱訊息代理作為其事件分發中心的非同步訊息傳遞。在這種模式下,生產者可以釋出事件,而不必瞭解是否有任何消費者在收聽,並且(以相同的方式)該事件的消費者可以在方便時對其做出反應或完全忽略它。這通常是事件驅動架構的基礎。
由於我們已經選擇Redis作為多個微服務的主要資料庫,因此我們可以透過使用Redis Streams來實現此模式,從而簡化架構。Redis Streams是不可變的按時間排序的日誌資料結構,它允許生產者將非同步訊息釋出到多個訂閱的使用者。這確保了釋出事件的微服務將與使用它們的微服務保持脫鉤狀態,因此不會對可用性和釋出週期產生交叉依賴。此外,Redis Streams可以配置為處理不同的交付保證,支援消費者群體以及本質上類似於Kafka的其他細微差別-也是跨微服務架構的主要內容。
 

設計模式:基於編排的Saga->分散式事務
現在,我們已經啟用了服務間通訊,接下來的挑戰是處理跨越多個有界上下文的事務,而又不會破壞對隔離的合規性。在過去,這是很簡單的實現,因為事務範圍內的所有操作都是針對單個RDBMS執行的,該RDBMS提供行鎖定,死鎖檢測和回滾功能。一旦資料跨多個資料庫分佈,兩階段提交協議(2PC)就成為分散式事務的標準。但是,儘管這兩種方法都可行,但在設計時並沒有考慮到最終的一致性。
如果我們假設在分散式事務期間將不存在依賴項,那麼我們還應該假設頻繁的回滾將導致整個系統的零星不可用性—這既不是雲本機,也不是縮短產品上市時間。
這可以透過放寬對ACID保證的嚴格要求來解決,ACID保證已經支援了大多數傳統體系結構數十年來的關聯式資料庫。儘管關聯式資料庫在微服務體系結構中佔有一席之地,但它們的相關性卻變得越來越重要。例如,如果不要求引用完整性,那麼為什麼沒有授權的自治團隊會選擇使用NoSQL資料庫最佳化其微服務,該資料庫專門用於處理其特定的資料訪問模式和SLA。

Redis如何簡化實現微服務的設計模式 – thenewstack
回想一下,我們的付款處理工作流程由多個微服務組成,這些微服務組織到單獨的有界上下文中,並由Redis(NoSQL資料庫)支援。在這種情況下,推薦的處理分散式事務的模式是基於編排的Saga,它執行一系列隔離的本地事務,併發布事件,從而促進工作流階段之間的過渡。
參與Saga的每個微服務都將僅偵聽其自己的與工作流相關的事件,該事件將通知它執行本地資料庫事務,然後將其自己的事件釋出給訊息代理。這種事件驅動的編排可以包括補償用於回滾的微服務和用於複雜業務流程的決策服務。
值得注意的是,在基於編排的Saga中,沒有中央協調器,這避免了將參與的微服務的釋出週期耦合在一起。但是,它並不總是正確的解決方案。在某些情況下,強一致性是絕對必要的,例如帳戶轉帳。在這種情況下,基於編排的Saga可能會更適合,或者在同一有限上下文中依靠微服務之間的2PC。
 

設計模式:事務發件箱和訊息中繼->一致性
既然我們已經設計了跨越多個有界上下文的事務,那麼我們的下一個挑戰是減輕微服務的資料庫和訊息代理之間的不一致風險,即使兩者都使用Redis。回想一下,在前兩種設計模式中,每個微服務都在本地提交到其資料庫,然後釋出了一個事件。如果使用雙寫模式的某些變體來實現此目的,則通訊可能會丟失並且分散式事務可能會變得孤立(尤其是在雲環境中)。

可以將程式碼複雜性新增到每個微服務中,以處理各種失敗和不一致的情況,但是請考慮將這種工作累加到數百個團隊中,並考慮不正確實施的風險-所有這些都不會增加業務價值。

Redis如何簡化實現微服務的設計模式 – thenewstack
為了避免各種應用程式級別實現的風險和成本,建議的模式是事務發件箱和訊息重播。Redis透過使用Redis Streams作為事務發件箱,並使用RedisGears作為訊息中繼,簡化並支援這兩種模式的組合實現,稱為後。在Redis中,輔助執行緒可以偵聽更改的資料事件,按時間順序持久地儲存它們,並在可用時將其釋出到訊息代理。可以透過基礎架構自動化在每個Redis資料庫上統一啟用或升級此功能。
 

設計模式:遙測->可觀察性
現在,我們已經減輕了主資料庫和輔助資料平臺之間不一致的風險,我們的下一個挑戰是衡量整個體系結構及其支援的業務交易中微服務的執行狀況,即可觀察性
觀測是充滿了數以百計的分散式系統中的一個必須具備的孤立和最終一致的部件。
可觀察性建立在三大支柱上:指標,日誌記錄和可追溯性。我們將首先關注指標,這些指標通常儲存在時間序列資料模型中,該資料模型可以處理大量按時間順序排列的事件和時間點查詢。最佳地,可以實時跟蹤指標,以便可以檢測到SLA / SLO異常,並在發生異常時可以緩解這些異常。

Redis如何簡化實現微服務的設計模式 – thenewstack

為了觀察分散式系統的執行狀況,我們首先需要它的資料。推薦的模式是遙測,它是從遠端源自動收集和傳輸資料以進行監視。Redis透過其後功能將資料無縫推入另一個Redis資料模型RedisTimeSeries中,從而簡化了該模式的實現。注意,使用Redis,我們只需要一個平臺即可實現此模式。
現在,RedisTimeSeries中提供了指標,我們可以跨多個維度實時查詢它們-業務KPI,應用程式SLA / SLO,基礎架構利用率等。使用RedisInsight視覺化基礎架構級別的指標。以及使用用於GrafanaRedis資料來源視覺化業務級別指標。
 

設計模式:事件源->稽核和重播
既然我們已經對度量標準資料實施了遙測,那麼我們的下一個挑戰是啟用可觀察性的其餘支柱-日誌記錄和可追溯性。與指標不同,時間序列資料模型將無法使日誌的固有屬性受益,因為它們無法彙總或縮減取樣。相反,它們需要一個不可變且按時間排序的資料結構,該結構可用於按事件發生的順序稽核,恢復或重放事件鏈。
由於微服務需要隔離,因此它們不能依賴共享的RDBMS來維護捕獲整體中所有事件的事務日誌。因此,推薦的模式是事件源,它在微服務資料庫級別的不可變且按時間排序的日誌中記錄每個更改的資料事件。這種模式在大多數事件驅動的體系結構中很常見。

Redis如何簡化實現微服務的設計模式 – thenewstack
通常使用訊息代理和事件儲存來實現事件源。回想一下,我們已經實現了使用RedisGears捕獲更改資料事件並將其儲存在Redis Streams中的模式,Redis Streams是一個不可變的按時間順序排列的日誌資料結構。因此,Redis可用作資料庫,訊息代理和事件儲存。
Redis Streams還可以透過允許外部程式作為隔離的消費者組訂閱其事件流,從而超出單個微服務的範圍來簡化事件源。這允許在業務流程,域甚至架構級別進行觀察。例如,工作流仲裁器或系統範圍的分析平臺。
現在,我們已經在Redis Streams中捕獲了更改資料事件,我們可以使用可觀察性的不同過濾器(微服務ID,事務關聯ID等)以本地方式視覺化它們。

 
設計模式:命令查詢責任隔離(CQRS)->效能

請注意,當我們定義與欺詐相關的有界上下文時,我們省去了付款處理工作流程的最後階段。這是因為其授權的自治團隊選擇了非Redis資料庫來支援其微服務。

Redis如何簡化實現微服務的設計模式 – thenewstack
因此,現在讓我們假設“批准| 基於磁碟的資料庫支援“拒絕付款”微服務,該資料庫並未針對查詢效能進行最佳化。由於它大概具有強大的耐用性保證,因此它是記錄儲存的合理選擇-但是,如果其有限上下文還包含需要此資料進行查詢的微服務,該怎麼辦。這意味著我們的下一個挑戰是在Redis不是記錄系統時最佳化查詢效能。

Redis如何簡化實現微服務的設計模式 – thenewstack推薦的模式是CQRS,它將資料集的寫(命令)和讀(查詢)責任分開。透過使用單獨的資料庫來實現CQRS,可以最佳化資料結構或資料模型,以適應隔離區兩側的資料訪問模式及其各自的SLA。由於我們的目標是最佳化效能,因此資料複製的方向通常會從基於磁碟的資料庫(例如MongoDB,Cassandra,RDBMS等)匯入Redis。
這就是要抓到的地方–要實現這種模式,我們將需要解決近實時連續資料複製問題,保持異構資料庫之間最終的一致性,並轉換資料以避免Command和Query資料結構之間的阻抗不匹配。這聽起來應該很熟悉,因為我們是在Redis是源資料庫時執行此操作的-回憶事務發件箱和訊息中繼模式。但是,由於在這種情況下,Redis是目標,而其他大多數資料庫都不支援後寫操作,因此我們需要外部實現來複制更改後的資料事件。
在這種情況下,我們可以透過使用可以與Command和Query資料庫整合的Change Data Capture(CDC)框架來簡化CQRS的實現。CDC框架通常使用事務日誌拖尾輪詢釋出者模式來掃描Command資料庫上的更改資料事件,並將它們作為轉換後的有效負載複製到Query資料庫。請注意,這與在快取旁模式中使用Redis有何不同,因為它不會在微服務級別耦合資料庫—保持隔離。
 

設計模式:共享資料->可重用性
既然我們已經解決了在Redis不在記錄系統中時最佳化效能的問題,那麼我們的下一個挑戰是處理微服務之間的共享資料,這些服務由不同的受限上下文或微服務體系結構之外的資料庫分隔。
後者的一個真實示例是一個扼殺程式從單片架構遷移到微服務架構。在這種情況下,作為混合雲部署的一部分,微服務的資料庫可能依賴於外部記錄系統多年,甚至無限期依賴。當我們引入CQRS模式時,我們實際上已經解決了這個問題,但是讓我們擴充套件問題說明,使其包含共享相同資料和資料訪問模式的微服務。
在這種情況下,以下是一些適用的模式,其中Redis簡化了實現:


Redis如何簡化實現微服務的設計模式 – thenewstack
這是要抓住的地方-儘管這些模式解決了一些有限上下文之間的共享資料,但它們都無法在全球範圍內擴充套件。

Redis如何簡化實現微服務的設計模式 – thenewstack
對於全域性資料,建議的模式是API閘道器的隔離資料庫。由於該資料庫可能會被流過體系結構的每個事務訪問,因此我們必須將業務連續性,可伸縮性和效能視為選擇該資料庫的關鍵成功標準。幸運的是,這是Redis Enterprise在數千個生產部署中大放異彩的地方。
Redis Enterprise是關鍵任務會話資料,身份驗證令牌和臨時資料儲存的事實上的標準,具有亞毫秒級的規模效能,並具有Active-Active跨叢集複製和多可用性區域部署的99.999%SLA。

 

相關文章