请banq老师解决我对LMAX 架构的一些疑问

  看到<<对LMAX架构的新的理解,让自己对event sourcing的做了更多的思考>>这篇帖子banq老师说的一句话话:“从来就没有所谓input event或output event。event事件贯穿系统前后,系统任何部分包括领域都不会对event做任何改变。”,我有一些问题,想请教banq老师:

1.如果LMAX的ES是先对所有事件进行持久化,那么是否把input event ,output event全部持久化?
2.如果1的回答是yes,那么由于output event是由input event衍生,那么当回放input事件的时候,那么又将产生output event,那么输出事件不就重复了?

可能我对ES的理解有些不正确的地方,请指正!

另:是否有一些es事件持久化及回放的例子供参考了解,banq老师写的一个关于Match的例子也没有涉及到这方面的知识,致谢!


[该贴被fengweili于2013-03-14 15:27修改过]

2013-03-14 15:22 "@fengweili
"的内容
那么输出事件不就重复了? ...

不明白你的意思?ES持久化目的我认为是用来实现类似事务一样机制,事件回放类似事务回滚,事务回滚后再重新执行,新的数据和原来的数据也是重复的,所以,回滚时将原来的数据全部销毁或者备份。

原文意思:
在MAX架构中,你将此单一操作过程分为两个,第一部分将获取订单信息,然后输出事件(请求信用卡检查有效性的请求事件)给信用卡公司. 业务逻辑处理器将继续处理其他客户的订单,直至它在输入事件中发现了信用卡已经检查有效的事件,然后获取该事件来确认该订单有效。

示意图如下:


--> Order ---->Card
<-----------------|

订单将事件发给Card处理,事件类似消息,Card处理完成后,再发事件给Order,这是一个循环。

那么在这个循环中,Order发出的事件可以看成Order的输出事件,也可以看成Card的输入事件,那么哪个更合理些呢?参考状态模式,比如录音机有三个状态:播放 暂停 和停止。

改变这三个状态是发生了三个事件,按下播放键触发播放事件使录音机进入播放状态;按下暂停键触发暂停事件使录音机进入暂停状态;等等。一个事件改变一个状态的思路比较清晰些。

Event Store实现起来并不难,将事件排队进入队列后,进行存储,可以使用RabbitMQ或JMS都可以。MF一直在思考如何将Event以通用数据格式存储,因为现在存储Event,总是有具体数据格式,和业务实体有关系,能否有一种无Schema的存储?


"订单将事件发给Card处理,事件类似消息,Card处理完成后,再发事件给Order,这是一个循环。"

至于Card处理完后的事件,我们就不用持久化了吧?

为什么回放就能保证数据的准备性?还有回放过程失败了,如何检测?回放过程中有什么要注意的问题?

谢谢banq老师

2013-03-14 16:33 "@fengweili
"的内容
Card处理完后的事件,我们就不用持久化了吧 ...

Card处理完的事件不是再次送到Order作为触发事件吗?当然要作为Order实体的事件存储了。

事件触发状态改变,这句话本身的含义就是,事件是导致状态变化的原因,既然是原因,那么事件本质上相对实体状态必然是输入性质的。

如果Order实体发出的事件也是触发其他实体如Card状态变化,那么也就是Card的事件(输入)。

如果理解事件和状态的关系,就不应该分输入输出事件,违背事件本身含义,逻辑上矛盾的。

以Jdon分析法图示如下:

上图展示的是LMAX架构中Order实体的示意,如果Card也是一个实体,也是按照这张图,两个合起来就是两张图,只不过Order的输出变成Card的输入事件了,事件有来源和目的两个点,事件改变了目的状态,所以记录时,事件和目的算一伙,这样才能根据事件推导出目的状态变化的各个场景,正如我这两张图是两个不同边界划分。

至于回放失败怎么办等等问题,都可以参考JMS之类消息机制,比如JMS消息也有事务性,如果消息触发的一系列动作有失败,那么回滚后,消息并没有从消息总线删除(正常完成会删除),有一个最大Retry次数,超过最大次数会主动报警出错显示,这些没有什么新玩意。参考文章:
分布式发布订阅消息系统 Kafka 架构设计
[该贴被banq于2013-03-14 19:23修改过]
[该贴被admin于2013-03-14 19:36修改过]
[该贴被banq于2013-03-14 22:07修改过]

2013-03-14 18:44 "@banq
"的内容
如果理解事件和状态的关系,就不应该分输入输出事件,违背事件本身含义,逻辑上矛盾的。 ...

我觉得不能这样讲,输入输出事件这种叫法本身没有错误,就看你从什么角度去理解。我的意思是只要明确说明输入是相对什么,输出是相对什么,只要把这点讲清楚,那大家就完全能理解为什么叫输入事件,为什么叫输出事件了。

比如现在有一个事件a,由用户发出,由聚合根A响应,
那就是:用户-> 事件a -> 聚合根A

那这种情况下,可以理解为用户是在输出事件或产生事件,而聚合根A是接收事件即处理事件(改变状态)。此时我们可以认为事件a相对于用户是输出事件,因为它是因为用户的某个操作而产生的;而相对于聚合根A则是输入事件,因为是该事件导致聚合根A去响应,然后导致聚合根A改变自己的状态;

接下来如果聚合根A处理事件a后产生了事件b,然后可能聚合根B响应该事件,
那就是:聚合根A-> 事件b -> 聚合根B。

那这种情况下,可以理解为聚合根A是在输出事件或产生事件,而聚合根B是在接收事件或处理事件(改变状态)。此时我们可以认为事件b相对于聚合根A是输出事件,因为它是因为聚合根A而产生的;而相对于聚合根B是输入事件,因为是该事件导致聚合根B去响应,然后导致聚合根B改变自己的状态;

所以我认为理不理解事件与状态的关系不要紧,关键是表达的时候要说清楚,只要描述清楚,别人就不会说你的输入事件或输出事件是错的或矛盾的了。

banq觉得呢?不知道我上面的描述是否清楚?
[该贴被tangxuehua于2013-03-14 22:23修改过]