事件溯源的好处在于可在软件中捕获现实世界 – Jessitron


今天在推特上,吉米·博加德(Jimmy Bogard)就事件溯源的权衡取舍发表他的观点:https://www.jdon.com/53732
如果事件溯源架构无法扩展,更快或更简单,为什么要使用它?
Event Sourcing为您提供了由您的软件建模的完整、一致的世界范围模型。那很吸引人。

我们想用软件为现实世界建模
您可以将当今世界视为之前发生的所有事情的总和。环顾我的房间,我可以说我的书架是各种购买的总和,有些是四处走动,是关于阅读和保存物品的一系列决定。
我可以将自己视为发生的一切的总和,再加上我自己告诉自己的故事。我的下一个动作就是这样的结果,加上我目前的环境,以及即将发生的事件。该行动本身是世界上的事件。
在生命中,在生物学中,我们看不到所有这些输入事件,我们无法再次改变响应事件的算法,不断地再试。但是在软件领域,我们可以!
当然,我们需要完美的建模和决策的可追溯性!这样,我们就可以始终回答“为什么”,并且在学习过程中可以改善理解和决策策略。
这就是事件溯源提供的。

我们希望我们的模型是完整且一致的。
遗憾的是,因为完整性和一致性存在冲突,无法为整个世界建模。但是,如果我们将“完整”限制在业务领域和公司范围内,从理论上讲这是可能的。
事件溯源提供了一种方法。
在事件源中,每一项输入都是一个事件:有人要求安排咨询活动。提供者注册可用时间,活动;预约时间,活动。通知客户事件;客户出现事件;会话报告已提交事件。
我们可以总结过去的事件以获得当前状态。
浏览所有事件的时间表,将它们加起来。据此,我们可以计算世界状况。
通过预定约会事件,我们可以构建当天日历。
在月底,我们将构建有关服务客户和提供商使用率的报告。基于此,我们可能会寻求更多的提供商,或者与活动较少的提供商进行交谈。与其他部门相比,总部对我们办公室的绩效进行排名。(banq注:为大数据分析提供基础架构)

我们需要更正
为了准确地模拟现实世界,我们需要考虑现实世界中发生的所有事情。
预约被取消。客户不露面。会话报告提交较晚。(“上周的会议报告在哪儿?”“哦,对了,为时已晚,因为通往停车场的大门失灵了。不要为此收费。”)
数据延迟或丢失。如果您坚持认为不会发生这种情况(“每个提供商都必须在一天结束前输入会话报告”),那么您的模型就无法实现。
适应更正、合并迟到的事件,接受部分数据。您在模型中允许的现实越多,它就越准确。

我们可以根据当时可用的信息评估过去的决定
当数据迟到时,报告在打印后会更改。事件源系统可以处理此类问题。
随着过去几天的新数据的到来,它将与那些日子的数据相加。报告变得更加准确。
我的一个朋友在咨询中心工作,他接到总部的电话,例如“为什么您的十二月使用率如此之低?”,他的回答是:“什么?很好啊。”然后他再次运行报表,果然,情况有所不同。在他运行报告后,获得了有关12月的更多数据,但现在总数有所不同。他无法复制他所看到的报告,这使得很难向总部解释他的行为。
如果他们的软件使用事件源,他可以说:“请从1月2日开始运行报告,您会明白为什么我没有采取任何措施。”
每个事件都记录一个接收到的时间戳(表示我们了解该时间戳的时间)和一个有效时间戳(表示发生在现实世界中的时间戳)。然后,该软件只能汇总1月2日之前收到的事件,以重现当天看到的报告。(大数据)

我们可以用新的逻辑重新评估世界
基于事件的系统不仅可以复制与前一天相同的报告,还可以问:如果更改报告逻辑该怎么办?那会是什么样子?
也许我们想将未报告的约会报告为“可能已取消”以反映不确定性。我们可以针对相同事件运行新逻辑,并将其与旧结果进行比较。
这意味着我们可以针对事件流运行测试并检测行为更改。

我们需要记录外部可见的决策以保持一致性
当我们更换软件时,会危及一致性。
如果我们在2月更新报告逻辑,则总部在“截至1月2日”运行报告时,他们会看到与我朋友在同一天运行报告时看到的不同的东西。为了保持一致性,数据和代码都必须与1月2日的数据匹配。
或者,我们可以将报告本身建模为事件。“在1月2日,我说的大约是12月。”然后我们可以将其合并到报告逻辑中。
我们的系统所做的任何对外界可见的事情本身都是事件,因为它改变了外部人员和软件的行为方式。为了一致地重现我们的行为,我们的系统可以记录自己的行为,也可以保留所有数据和选择它的代码。
到目前为止,这是很好的和确定性的。但是现实世界不是。
如果行为是确定性的,则可以在基于事件的系统中重现行为。在人类行为方面,我们无法获得如此奢侈。我们的选择来自多种影响,其中一些是相互矛盾的。一条推文启发了我写这篇文章。数以千计的其他推文使我分心。

冲突的信息来自现实生活。
根据发生的事件,当我们正在建模的真实世界不一致时,事件源变得棘手。
现在说我们是一家货运公司。当货物在全球范围内移动时,我们对货物在集装箱中的移动进行建模。当集装箱被装载到船上时,这是一个事件,当集装箱被卸载时,这是一个事件。计划船舶行程以及到达每个港口的事件。
一个事件说集装箱1418被装载到奥克兰的Enceladus船上;另一件事是集装箱1418计划下一站在北京;另一事件是集装箱1418在旧金山被卸下。另一人说,集装箱1418在北京被清空了。你相信哪一个?
这个例子来自一个真实的故事,奇怪的事情发生了,您的系统是否允许人们报告现实情况?是否有“要求一个人去寻找那个集装箱?真的是1418吗?”

模棱两可的决定是事件
无论系统做出什么决定,都需要将其记录为事件。

我们可以看到每个报告和决定的来源
如果有一些报告不均衡,并且作为错误反馈到了开发团队,那么事件源将为我们提供很好的跟踪工具。
每个“我做出决定”或“我产生此报告”事件都可以记录输入的事件集以及为产生输出而运行的代码版本。您可以拥有完整的出处。
这种软件是 负责任的。它可以讲述其决策,执行的操作以及原因的故事。当时的世界是什么样的。
这是一个美丽的酒店。有了充分的出处,我们可以了解发生了什么。我们可以互相讲故事。具有可重播性,我们可以更改代码,并查看我们是否下次可以对其进行改进。

记录一切变得荒谬
但是,关于事件的数据很快就变得庞大起来。每个报告消耗了数千个事件。现在,基于事件的当前状态总和的每个决策都依赖于所有这些过去的事件,定义当前状态的代码,从中获取输入的所有其他状态以及它们的代码和事件集。
同时,其中一些事件已过时,不再符合最新代码所期望的格式。同时,我们仍然忽略了系统外发生的所有事情,因此我们完全不了解许多因果关系。“有人单击了此按钮。”为什么?他们在屏幕上看到了什么信息?
在现实生活中,大多数信息都会丢失。历史将永远不会被完全记录。
完整性仅限于非常小的系统。请小心在此投入的精力。有意识地选择边界,在边界之外您不知道发生了什么。您不知道船厂,人的脑袋或另一家公司运行的软件中真正发生了什么。我们看到的世界范围很小。

我们没有为整个世界建模的原因是有原因的
事件溯源将尽最大努力为整个世界建模。我们尝试记住发生的所有重要事件,将其总结到软件中的当前状态中,制定决策并采取行动。
但是事件是乱序的。事件丢失了。事件相互矛盾。事件具有部分数据或旧数据格式。逻辑改变。我们不记录一切事件。
有时值得考虑一下您应在事件源系统中做什么,然后实施足够的事件。保留产生的报告的副本,以便人们可以检索它们而无需重新生成它们。在比日志寿命更长的地方记录困难的决定。
事件溯源功能强大。但这并不容易。希望对不想处理的极端情况进行认真思考。期望处理存储以及速度和最新的权衡。允许人类进行更正,因为现实世界总是会让您感到惊讶。