從事件溯源到事件驅(qū)動(dòng):事件和事件流相關(guān)技術(shù)盤(pán)點(diǎn)

本文是讀完Martin Kleppmann的《Making sense of stream processing》的一些理解和感悟。

Event Sourcing (事件溯源)、Stream processing(流處理)、Complex Event Processing(復(fù)雜事件處理)、CQRS(Command Query Responsibility Segregation,命令查詢(xún)職責(zé)分離)、Event-driven architecture(事件驅(qū)動(dòng)架構(gòu))等令人眼花繚亂的技術(shù)術(shù)語(yǔ)的本質(zhì)是事件和事件流,這些技術(shù)的區(qū)別在于對(duì)事件的粒度的劃分和對(duì)事件處理過(guò)程的側(cè)重點(diǎn)。

1. Event Sourcing (事件溯源)

Event Sourcing側(cè)重于事件的持久化,這里的事件的粒度可以細(xì)到對(duì)業(yè)務(wù)數(shù)據(jù)的增刪改查,如果和傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)做對(duì)比,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)記錄的數(shù)據(jù)是一種最終狀態(tài),這個(gè)狀態(tài)可以被隨時(shí)增刪改查,而Event Sourcing記錄的數(shù)據(jù)則是對(duì)狀態(tài)進(jìn)行增刪改的有序命令流,每條數(shù)據(jù)本省不可被更改,但依據(jù)這些命令流可以構(gòu)造出最終的狀態(tài):


關(guān)系數(shù)據(jù)庫(kù)和事件溯源的對(duì)比

正如Martin所舉的電商購(gòu)物車(chē)的例子,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)表中記錄的是用戶、商品和數(shù)量的信息,是最終結(jié)果:


購(gòu)物車(chē)案例的數(shù)據(jù)庫(kù)-https://www.confluent.io/blog/making-sense-of-stream-processing

而事件溯源則記錄用戶的每一次添加商品、更新數(shù)量、提交訂單操作,是有序的命令流:


購(gòu)物車(chē)案例的命令流-https://www.confluent.io/blog/making-sense-of-stream-processing

實(shí)現(xiàn)Event Sourcing并不難,Event Store這款開(kāi)源數(shù)據(jù)庫(kù)就可以幫助我們存儲(chǔ)事件以及進(jìn)行復(fù)雜查詢(xún),還有很多新玩法等著我們?nèi)?shí)踐。

2. Stream processing(流處理)

Stream processing側(cè)重于事件處理的過(guò)程,這里的事件的粒度偏向于實(shí)時(shí)的業(yè)務(wù)數(shù)據(jù),Martin稱(chēng)之為Raw Event,如每秒的室內(nèi)溫度數(shù)據(jù)、用戶當(dāng)前發(fā)布的微博等,由于數(shù)據(jù)量大且實(shí)時(shí)要求高,流處理一般采用分布式架構(gòu)?;谶@些原始事件,可以構(gòu)建上層的實(shí)時(shí)統(tǒng)計(jì)、聚合的邏輯,從而生成Aggregated Data,當(dāng)然也可以構(gòu)建離線分析的邏輯,所以原始事件是實(shí)現(xiàn)流處理的基礎(chǔ),聚合數(shù)據(jù)只是最終呈現(xiàn)的結(jié)果。

近年來(lái)隨著Twitter、Facebook等互聯(lián)網(wǎng)公司的發(fā)展,分布式流式計(jì)算逐漸成熟。這些互聯(lián)網(wǎng)公司的業(yè)務(wù)數(shù)據(jù)有一個(gè)共同點(diǎn),即有大量的并發(fā)的讀寫(xiě)操作,在這種業(yè)務(wù)場(chǎng)景下傳統(tǒng)的以關(guān)系型數(shù)據(jù)庫(kù)為核心的系統(tǒng)架構(gòu)已經(jīng)不能勝任,只能將數(shù)據(jù)讀寫(xiě)操作分離,構(gòu)建新的解決方案,保證高可用性和高一致性。分布式流式計(jì)算是可以實(shí)現(xiàn)讀寫(xiě)分離的一種架構(gòu),也正是讀寫(xiě)分離讓流處理和事件溯源的產(chǎn)生了邏輯上的內(nèi)在一致性:在兩種技術(shù)中事件在本質(zhì)上講都是數(shù)據(jù)的寫(xiě)操作,或者說(shuō)是更新操作,流處理中的聚合數(shù)據(jù)和事件溯源里的狀態(tài)及查詢(xún)是數(shù)據(jù)讀操作的結(jié)果:

流處理和事件溯源的內(nèi)在一致性

典型的分布式流式計(jì)算的架構(gòu)是這樣的:


分布式流式計(jì)算-https://www.confluent.io/blog/making-sense-of-stream-processing

關(guān)于讀寫(xiě)分離,Martin在文中還進(jìn)行了一種有意思的抽象:應(yīng)用程序里面產(chǎn)生后臺(tái)交互的Button對(duì)應(yīng)寫(xiě)操作,而Screen頁(yè)面上展示的的結(jié)果對(duì)應(yīng)讀操作,雖然不夠嚴(yán)謹(jǐn)?shù)阋阅軌蛘f(shuō)明,事件的范疇在當(dāng)前的Web端和Mobile端應(yīng)用程序中已經(jīng)不僅僅是傳統(tǒng)的交易數(shù)據(jù),用戶的每一次點(diǎn)擊動(dòng)作和瀏覽記錄都是能產(chǎn)生寫(xiě)操作事件,你打開(kāi)淘寶的一瞬間,事件就會(huì)源源不斷地產(chǎn)生,可謂“買(mǎi)賣(mài)未動(dòng),數(shù)據(jù)先行”。

3. Complex Event Processing(復(fù)雜事件處理)

CEP同樣側(cè)重于事件處理的過(guò)程,但是更強(qiáng)調(diào)事件之間存在復(fù)雜的關(guān)系,如時(shí)間順序關(guān)系/聚合關(guān)系/層次關(guān)系/依賴(lài)關(guān)系。CEP需要構(gòu)建規(guī)則引擎,對(duì)符合一定Pattern的事件進(jìn)行查詢(xún)和處理。這其中比較優(yōu)秀的工具有EsperFlink CEP。

機(jī)架溫度監(jiān)控案例-http://flink.apache.org/news/2016/04/06/cep-monitoring.html

Flink官網(wǎng)的一個(gè)簡(jiǎn)單案例足以說(shuō)明復(fù)雜事件處理和流處理結(jié)合后的威力:數(shù)據(jù)中心機(jī)架的溫度被實(shí)時(shí)監(jiān)控,溫度超過(guò)閾值時(shí)會(huì)產(chǎn)生Warning事件,連續(xù)兩個(gè)Warning事件會(huì)產(chǎn)生Alert事件,Alert事件則會(huì)觸發(fā)降溫的動(dòng)作,在樣的業(yè)務(wù)邏輯在Flink平臺(tái)上用短短幾行代碼就可以實(shí)現(xiàn),而用普通手段則要復(fù)雜得多。CEP可以提高系統(tǒng)的監(jiān)控和分析能力。

4. CQRS (Command Query Responsibility Segregation,命令查詢(xún)職責(zé)分離)

CQRS上升到了系統(tǒng)架構(gòu)這個(gè)層次,事件的粒度是系統(tǒng)中的業(yè)務(wù)數(shù)據(jù)。在架構(gòu)層面,將一個(gè)系統(tǒng)分為寫(xiě)入(命令)和查詢(xún)兩部分。一個(gè)命令表示一種意圖,表示命令系統(tǒng)做什么修改,命令的執(zhí)行結(jié)果通常不需要返回;一個(gè)查詢(xún)表示向系統(tǒng)查詢(xún)數(shù)據(jù)并返回。同樣是讀寫(xiě)分離,互聯(lián)網(wǎng)場(chǎng)景下的流式計(jì)算中的讀寫(xiě)分離是為了解決高并發(fā)讀寫(xiě)操作,而CQRS中的讀寫(xiě)分離則是為了解決復(fù)雜的數(shù)據(jù)模型,是Domain Driven Design(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))的實(shí)踐。


CQRS示意圖-https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf

5. Event-driven architecture(事件驅(qū)動(dòng)架構(gòu))

在事件驅(qū)動(dòng)架構(gòu)中,事件的粒度為多進(jìn)程、多服務(wù)、多系統(tǒng)之間的通信消息。不同于SOA架構(gòu),EDA架構(gòu)是pub-sub模式:Process1處理完邏輯后產(chǎn)生消息,Process2訂閱消息并進(jìn)行處理, Process1不知道Process2的存在,Process間通過(guò)MQ最終數(shù)據(jù)的最終一致性。


事件驅(qū)動(dòng)架構(gòu)示意圖-https://msdn.microsoft.com/en-us/library/dd129913.aspx
事件驅(qū)動(dòng)架構(gòu)示意圖-https://msdn.microsoft.com/en-us/library/dd129913.aspx

參考及擴(kuò)展閱讀

  1. Making sense of stream processing
  2. Introducing Complex Event Processing (CEP) with Apache Flink
  3. 經(jīng)典的應(yīng)用系統(tǒng)結(jié)構(gòu)、CQRS與事件溯源
  4. CQRS\ES架構(gòu)介紹
  5. Using Events in Highly Distributed Architectures
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容