雲端計算設計模式(七)——事件獲取模式
雲端計算設計模式(七)——事件獲取模式
使用僅追加儲存到記錄完整一系列描述在一個域上取資料,而不是儲存僅僅是當前的狀態,從而使儲存區可以被用來實現該域物件的動作事件。該圖案可以通過避免需要同步的資料模型和商業領域中簡化複雜的結構域的任務;提高效能,可擴充套件性和響應能力;提供交易資料的一致性;並保持完整的審計跟蹤和記錄,可能使補償措施。
背景和問題
大多數應用程式使用資料,並在典型的方法是應用到通過更新它作為使用者使用的資料保持資料的當前狀態。例如,在傳統的建立,讀取,更新和刪除(CRUD)模型的典型資料處理將是從存貯器中讀出的資料,進行一些修改,以使其和更新的資料的當前狀態與新的值時─
的CRUD方法有一定的侷限性:
•在CRUD系統直接執行更新操作對資料儲存可能會影響效能和響應能力,並限制可擴充套件性,因為它需要處理開銷的事實。
•在具有許多併發使用者的協作域,資料更新衝突更可能發生,因為在更新操作發生在資料的單個專案。
•除非有另外的稽核機制,它記錄在一個單獨的日誌的每個操作的詳細內容,歷史記錄丟失。
注意:
對於的CRUD方法的侷限性有了更深的瞭解請參見“CRUD,只有當你能負擔得起”MSDN上。
解決方案
事件獲取模式定義了一個方法來處理操作上是受一個事件序列,其中的每一個記錄在僅追加儲存驅動的資料。應用程式程式碼傳送一系列命令性描述
事件持久儲存在一個事件儲存在充當真理或記錄的系統的源(權威資料源給定的資料元素或資訊)有關的資料的當前狀態。事件儲存通常釋出這些事件讓消費者能夠得到通知,如果需要,可以處理它們。消費者可以,例如,啟動該應用中的事件的動作的其他系統的任務或執行完成操作所需的任何其他相關聯的動作。注意,生成該事件的應用程式程式碼從訂閱該事件的系統去耦。
在事件儲存公佈了事件的典型用途是保持實體化檢視的應用程式中的行動改變他們,並與外部系統的整合。例如,系統可保持用於填充UI部分的客戶訂單
注意:
更多資訊請參見物化檢視模式。
此外,在任何時間點,可以對應用程式來讀取事件的歷史,並使用它通過有效地“回放”和消耗所有有關該實體的事件,以實現一個實體的當前狀態。這可能發生在需求,以處理時的要求,或通過計劃任務,使該實體的狀態可以被儲存為一個物化檢視,以支援表示層來實現域物件。
圖1示出的圖案的邏輯的概述,包括一些使用事件流,例如,建立的物化檢視,與外部應用程式和系統整合事件,並重放事件來建立特定實體的當前狀態的突起的選項。
圖1 - 的情況下獲取模式的概述和示例
事件獲取模式提供了許多優點,包括如下:
•活動是不可變的,因此可以使用僅追加操作來儲存。使用者介面,工作流或過程發起產生該事件可以繼續,並且處理這些事件可以在後臺執行的任務的操作。此,結合的事實,有記錄的執行過程中沒有爭用,可以極大地提高效能和可擴充套件性的應用,尤其是對於表示層或使用者介面。
•活動是描述所發生的一些動作,再加上描述的事件所代表的行動所需的任何相關資料的簡單物件。事件不直接更新資料儲存;它們被簡單地記錄用於處理在適當的時間。這些因素可以簡化實施和管理。
•活動通常意味著一個領域的專家,而物件關係的阻抗失配的複雜性可能意味著一個資料庫表可能無法清楚地瞭解該領域的專家。表是表示該系統中,未發生的事件的當前狀態,人工構建體。
•事件的採購可以幫助防止引起衝突,因為它避免了要求直接更新在資料儲存物件的併發更新。然而,領域模型仍然必須用來保護自己免受可能導致不一致的狀態的請求。
•事件的僅追加儲存提供了可用於監測對一個資料儲存所採取的行動的稽核跟蹤,再生的當前狀態作為通過重播事件隨時物化檢視或預測,並協助測試和除錯系統。此外,該規定使用補償事件取消變化提供了被逆轉的變化,這不會是如果模型簡單地儲存在當前狀態的情況下的歷史記錄。事件列表中,也可以用於分析應用程式的效能,並檢測使用者行為趨勢,或獲得其它有用的商業資訊。
•從響應進行操作的事件儲存提出的每個事件的任何任務事件的解耦提供了靈活性和可擴充套件性。例如,用於處理由所述事件儲存引發的事件的任務都知道只有事件的性質和它包含的資料。時所執行的任務的方式是從觸發事件的動作去耦。此外,多個任務可以處理每個事件。這可能使得與其他服務和系統,只需要監聽的事件儲存提出了新的事件,易於整合。然而,該事件採購事件往往是非常低的水平,並且可能有必要以產生特異性整合事件來代替。
注意:
事件來源通常結合CQRS模式通過執行資料管理任務響應於所述事件,並通過物化從所儲存的事件的意見。
問題和注意事項
在決定如何實現這個模式時,請考慮以下幾點:
•建立物化檢視或重放事件產生的資料的預測時,系統只會是最終一致。有一個應用程式新增事件,事件儲存作為處理一個請求的結果之間有一些延遲,被公佈事件,而消費者對事件的處理它們。在此期間,描述該進一步修改實體的新的事件可能已到達的情況下儲存。
注意:
請參閱資料一致性底漆有關最終一致性的資訊。
•事件儲存是資訊不可變源,因此事件資料不應該被更新。要以撤銷變更更新一個實體的唯一辦法是補償的事件新增到事件儲存,就像你會用負數交易的會計核算。如果持久化事件的格式(而不是資料)需要改變,或者在遷移過程中,可能難以對現有的事件結合在商店的新版本。可能有必要通過所有更改的事件來迴圈以使它們符合新格式,或新增使用該新格式的新事件。考慮使用上的每個版本的事件模式的版本標記,以保持舊的和新的事件格式。
•多執行緒應用程式和應用程式的多個例項可以被儲存在事件儲存事件。在事件儲存事件的一致性是非常重要的,是影響到特定實體(的順序改變為一個實體發生影響其當前狀態)的事件的順序。新增時間戳到每一個事件是一個選項,可以幫助避免出現問題。另一種常見的做法是將註釋每一個事件所導致使用增量識別符號的請求。如果兩個動作試圖為同一實體的同時新增的事件,該事件儲存可以拒絕匹配現有實體識別符號和事件識別符號事件。
•有沒有標準的方法,還是準備建機制,如SQL查詢,讀取事件來獲取資訊。可以提取的唯一資料是使用事件識別符號作為條件的事件流。事件ID通常對映到單個實體。一個實體的當前狀態,可以僅通過重放所有涉及到它針對該實體的原始狀態的事件的確定。
•每個事件流的長度可以有上管理並更新該系統的後果。如果流很大,可以考慮建立以特定的間隔的快照,如活動指定數量。可以從該快照,通過重放該時間點之後發生的任何事件中得到的實體的當前狀態。
注意:
有關建立資料快照的更多資訊,請參見Martin Fowler的企業應用架構的網站和主從快照複製MSDN上的快照。
•儘管採購活動減少衝突的更新資料的機會,應用程式必須仍然能夠應付可能出現的通過最終一致性和缺乏交易的不一致。例如,一個事件,指示庫存的庫存的減少可能在資料儲存到達,而對於該產品的訂單被放置,從而導致需求調和這兩種業務;可能是建議客戶或建立後順序。
•事件釋出可能是“至少一次”等消費者的事件,必須冪等。它們不能重新在一個事件描述,如果該事件被處理多於一次的更新。例如,如果一消費者的多個例項保持一些實體的一個屬性的集合,如訂單放置的總數中,只有一個必須在當一個“順序放置”事件發生時,遞增該聚合成功。雖然這不是事件來源的固有特性,它是通常的實現決策。
當使用這個模式
這種模式非常適合以下情況:
•當你想捕捉“意圖”,“目的”或“理”中的資料。例如,如動家,已關閉帳戶,或已故變為一個客戶實體可被捕捉為一系列特定的事件型別。
•當它是至關重要的,儘量減少或完全避免更新衝突的發生資料。
•當你想記錄發生的事件,並能夠重放它們來恢復系統的狀態;用它們來回滾更改的系統;或者簡單地作為一個歷史和審計日誌。例如,當一個任務涉及多個步驟,您可能需要執行恢復更新操作,然後重放一些步驟,使資料恢復到一致狀態。
•當使用事件是應用程式的動作的自然特徵,並且需要很少的額外的開發或實現工作。
•當您需要輸入分離或應用這些行動所需的任務更新資料的過程。這可能是為了提高使用者介面的效能,或分發事件到其它聽眾如其他應用程式或服務,必須採取某些行動的事件發生時。一個例子是有費用提交網站整合了工資制度,使響應的費用提交網站做資料的更新提出的事件儲存事件由兩個網站和工資系統消耗。
•當您想要的靈活性,能夠改變實體化模型和實體資料的格式,如果需求發生變化,或者,當結合使用CQRS,你需要適應的讀模式或公開資料的意見。
•與CQRS一起使用時,和最終一致性是可以接受的,而讀出的模型被更新,或者,在從事件流中再水化的實體和資料發生的效能的影響是可以接受的。
這種模式可能不適合於下列情況:
•小型或簡單的領域,很少或沒有業務邏輯,或者非域系統,自然與傳統的CRUD的資料管理機制,運作良好的系統。
•哪裡的一致性和實時更新資料的意見是必需的系統。
•不要求系統中的審計跟蹤,歷史,功能,回滾和回放操作。
•系統中只有非常低的衝突更新到基礎資料的發生。例如,主要為新增資料而不是更新它的系統。
例子
的會議管理系統需要跟蹤會議完成了預定的數量,以便它可以檢查是否有座位仍然可用時,一個潛在的與會者試圖做一個新的預訂。該系統可以儲存預定的總數為在至少兩個方面的會議:
•該系統可以儲存關於預約的總數作為資料庫中的該擱置預約資訊的獨立的實體的資訊。作為預訂製成或取消訂單,則系統可以增加或減少該數量適當。這種方法在理論上是簡單的,但可引起可擴充套件性問題,如果有大量的與會者試圖進行預訂時的短時間內座位。例如,在最後一天或預約期間閉合,以便之前。
•該系統可以儲存大約預訂和取消如在事件儲存舉辦的活動資訊。然後,它可以計算出可用通過重播這些事件的席位數。這種方法可以更加擴充套件性由於事件的不變性。該系統只需要能夠從事件儲存讀取資料,或將資料追加到該事件儲存。關於預訂和取消事件資訊不會被修改。
圖2顯示瞭如何將會議管理系統的座位子系統可能通過採購活動來實現。
圖2 - 使用事件來源獲取關於座位預訂資訊,在會議管理系統
行動預留兩個座位的順序如下:
1.使用者介面發出命令,以預留座位有兩個人蔘加。該命令是由一個單獨的命令處理程式(一塊邏輯的是從使用者介面分離,並負責張貼的命令處理請求)處理。
包含所有預訂的會議資訊
2.一種聚集通過查詢描述預訂和取消的事件構成。該集合體被稱為SeatAvailability,並且被包含在暴露在聚合查詢和修改的資料的方法的域模型。
注意:
一些優化利用快照(這樣就不需要查詢和重放事件的完整列表,以獲得聚集的當前狀態),並維持聚合的在儲存器中的快取記憶體副本來考慮。
3,命令處理程式呼叫的域模型曝光,使保留的方法。
4. SeatAvailability骨料記錄包含的席位被保留數量的事件。聚合應用事件接下來的時間,所有的預訂將被用來計算的座位有多少仍然存在。
5.系統追加了新的事件在事件儲存的事件列表。
如果一個使用者希望取消一個座位,該系統遵循不同的是,命令處理程式發出,其生成一個座位取消事件,並將其追加到事件儲存區中的命令類似的過程
以及可擴充套件性提供更大的空間,使用事件店內還提供了一個完整的歷史,或審計追蹤,預訂和取消了會議。記錄在事件儲存在事件真相的權威和唯一來源。沒有必要持續聚集體中的任何其他方法,因為該系統可以很容易地重放這些事件和恢復狀態,以任意的時間點。
注意:
您可以找到有關這個例子中,在本章中的模式與實踐指導CQRS之旅MSDN上引入獲取事件的更多資訊。