LMAX+Event Sourcing架构的一些疑惑

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修改过]

LMAX架构用的是command sourcing, 而非传统的event sourcing. 因为CQRS中的command等同于LMAX中的input event.

所以,我希望大家能想想究竟该用command sourcing还是event sourcing呢?