LMAX+Event Sourcing架構的一些疑惑

tangxuehua發表於2013-02-09
LMAX架構有input events, business logic processor(blp), outputevents三個主要元素,當然disruptor不算,因為它是一種具體的實現技術(能夠實現多生產者-多消費者的併發處理框架)。我現在明白LAMX中的event sourcing是用input events來進行event sourcing, 而不是用output events.在LMAX架構中,任何input event在被blp處理前必須先要被journaler處理,即持久化到log。目的是當BLP在奔潰或日常修改需要重啟時能夠從這些log中讀取input events,然後重新replay這些input events.這個replay的過程叫做event sourcing.在CQRS架構中如果在command端也採用這樣的技術,那相當於就是把command要先持久化起來,這樣以後就可以透過replay commands來重建blp.

這個過程所展示的event sourcing已經和我之前所理解的不同了。看來我之前理解的event sourcing只是其中一種方式。現在我知道event sourcing根據事件的來源來分至少有兩種方式:1)根據input events來溯源;2)根據output events來溯源;以前我只知道可以根據output events來溯源。input event是command,表示要求domain做什麼;output event是由domain 產生,表示domain執行command後domain內發生的event。所以這兩種方式的本質是:前者是透過讓domain再重新執行一遍所有的command來讓domain達到當前最新的狀態;而後者是透過利用domain本身所產生的所有的event來重演從而讓domain自身達到最新狀態。

我在想的一個問題是,為什麼不透過output event來event sourcing呢?當BLP因為某種原因掛了需要重新還原時,我們要重建的是掛了的那個時候的BLP的狀態,那嚴格意義上來說,只有output event才是嚴格的不多不少的讓BLP恢復到掛了的那個時候所對應的所有事件,而input event雖然也能達到重建BLP的目的,但很可能會重建過頭。因為input event記錄的日誌資訊很可能比BLP掛了的時候要多,因為BLP掛了的時候有可能還會有一些input event還未被BLP處理。當然,你會覺得重建過頭也沒什麼關係,卻是問題不大。但是如果用input event來重建BLP,還有另一個問題,就是BLP在處理input event時有時肯定會免不了和外部系統互動,那此時在重建的時候必須要用一些stub來替換外部系統的這些介面,這樣重建BLP的時候才不會導致外部系統的API被不必要的重複呼叫。反過來,如果我們根據output event來重建BLP,那完全沒有這個問題,因為output event都是由domain自己產生,所以domain自己再重建時響應所有的output events時完全能知道該修改自己的哪些狀態。目前我所見過的事件溯源的實現都是根據聚合根產生的事件(即LMAX架構中的output event)來溯源。

另外一點是,如果我們是根據output event來重建BLP,那我們甚至可以不用預先記錄所有的input event,因為我們不需要用它來重建BLP了。要知道journaler記錄input event也是很耗時間的,雖然LMAX團隊已經用了比較快的方式來記錄日誌,就是直接透過寫檔案的方式儲存在磁碟上,順序寫檔案是很快的。但畢竟也要耗時間。也許你會說,journaler和BLP對應的執行緒是兩個執行緒,所以不受影響,其實不是,因為BLP必須只能處理已經被記錄了日誌的input event。換句話說,BLP對應的工作執行緒是依賴於journaler的工作執行緒的。

我希望我們能不僅從技術上分析這兩種溯源方式的好壞,更能從哲學的角度上分析到底怎樣才是真正的event sourcing。

[該貼被tangxuehua於2013-02-09 13:46修改過]

相關文章