四年运维生产经验分享:Nordstrom的事件溯源系列之二-生产者发布模式


在第一部分中,我分享了在Nordstrom一直在探索和实施事件溯源作为一种架构模式。在第二部分中,我们将分享一些我们见过的常见生产者模式。

你可以把事件生产者看成业务的决策者:他们做出决定 有关或在观察活动的业务,并通知有关刚刚发生了什么事件流。一些事件生成者也会首先使用其他事件,做出决策,然后发布这些决策:您可以在消费者中调用这些决定。事件源系统仅与所生成事件的质量和生产者的可靠性一样好,因此可以很好地与系统其余部分分离。
在Nordstrom,我们的活动是Avro -serialized,它提供压缩,文档,标准化以及跨架构修订的一些前向和后向兼容性。每个事件共享一个公共标题,并符合事件标准。这些事件将写入共享的多租户Kafka群集,并且事件架构将使用中央架构注册表进行注册。在我们的标准中,事件是过去发生的事情的通知 - 而不是将来采取行动的命令。例如,“add to cart”不是事件; “added to cart”才是。

九个事件生产者架构模式
在现有系统中,我们可以找到许多可以生成事件的地方,还有很多可供选择的机制。以下是我们在Nordstrom看到并实施的一些常见模式。希望这些例子激发团队的讨论和创新!

1. 在事件发生时刻生成者立即发布到分类账
在绿地项(新项目)目中,您将事件溯源用作一流的架构模式,这可能是正确的模式。在您的系统中,在观察或决定事件状态时,会在事件流中生成事件对象。在某些系统中,单个组件(如无服务器函数)可能只是一个事件生成器,该事件的结果由一个或多个单独的事件使用者在其他地方处理。这种方法的好处是生产者团队可以专注于可靠地生成具有强保证的事件,而不是实现其他逻辑。在这种模式中,即使在各种条件下,也应尽一切努力确保事件流的事件至少保证一次。

2.转换现有遗留系统的流
您可能拥有质量较低的现有的遗留流 : 可能包含许多特定于实现的技术上下文,重复数据或命令语法。源流也可以是非持久性队列,或者具有较差的扇出或背压问题,或任何其他数量的问题。使用各种流处理方法之一,您可以将此原始“遗留”流转换为高质量的分类帐源。

3.Write-through直写数据库并使用更改数据捕获
对于想要处理事务集或具有强read-after-write要求的现有系统,这种直写生成器模式可能是一种非常实用的方法。在这些系统中,通过从数据库中消费变更数据捕获流,然后转换为流上的事件来检测与数据库的交互。一些云提供商拥有专门为此模式设计的数据库解决方案,例如具有可以订阅无服务器函数的流的NoSQL数据库。当您选择数据库时,拥有实时,低延迟的更改流甚至可能是决定性因素。例如,在撰写本文时,Google Cloud Spanner具有一些真正令人难以置信的功能,但不支持有序事件的流出口的良好解决方案。
该模式还可以用作噪声,部分和/或劣质事件的滤波器或电容器。单个噪声事件会将新行创建或更新现有行,可能使用条件写入来删除重复项(幂等性)。然后可以读取表的更改流,如果完成,则转换为高质量事件并发布到事件流上。

4.轮询现有的请求/响应服务以进行更改并发布
支持许多现有的同步请求/响应服务,获取它们最近的更改。将其转换为事件流的一种简单方法是使用不断轮询的生产者。轮询系统可能还需要做额外的工作来序列化和模式化数据。根据我们的经验,测试这些服务API的数据的陈旧性和完整性非常重要,尤其是在评估第三方服务提供商的全新API时。有些系统在幕后使用批处理或缩放系统,这会给数据带来不可接受的陈旧性。一个简单的综合测试套件应该能够在各种条件下轻松测量这些问题。

5.订阅Web套接字或pub / sub
许多系统都有支持订阅更改的发布/订阅消息总线或WebSocket。由于许多发布/订阅系统不提供持久性保证,因此必须注意在订阅和转换组件暂时不可用时如何恢复事件。这里的一个解决方案是请求源系统通过发布/订阅层重新驱动数据。

6.流式化批量数据
在相对近期的实时数据流作为第一个事实来源的趋势之前,许多系统依赖于定期批量交付的批量数据。在事件源系统中,这些批次可以在收到后立即转换为事件流。但是,如果批次顺序不合理,应注意尽可能尝试进行数据的排序。
这种模式的一个好处是,通过可扩展的消费者系统,以及像Kafka或Kinesis这样的流传输提供的自然解耦,每小时或每天发生大量事件通常都是完美的。此外,这为生产者系统提供了随着时间的推移而不改变消费者的机会,可能转向10或15分钟批次,甚至转向相对实时的流作为其下一个重构目标。

7.在无服务器生态系统中使用事件触发器
无服务器计算产品依赖于整个云提供商的事件触发器生态系统。当发生任何各种事件时,会自动调用无服务器函数,例如在存储桶中创建的对象,或发布到Pub Sub的消息。可以利用此无服务器事件触发器生态系统,以便在每次世界上发生某些事件时将事件发布到流。在许多情况下,调用无服务器事件生成器函数,接收有效负载,对其进行转换,并将其发布到事件流。

8.监视react / redux中有价值的事件动作
在与不同背景的不同工程师交谈时,事件源架构的想法可能完全是外来的不合适,或完全适合。在那些与我交谈过的人中,最熟悉这个想法的是熟悉React-Redux等框架的前端工程师。在这些前端系统中,操作在发生时发布(按钮单击,图像滑动),页面上的各种组件消耗并以不同方式响应这些操作。
利用浏览器中的这些类型的前端操作/事件生态系统,我们可以在页面或客户端应用程序上创建组件,负责监听特定操作以及创建和广播格式正确的事件。无论事件是在客户端上序列化为最终格式还是以某种通用格式传递到云,都是一个重要的决定。

9.偶尔脱机客户端的复制表
在仅偶尔连接事件生成器的情况下,能够首先可靠地将事件写入到稍后与云同步的本地存储可能是一个很好的选择。这些情况的示例包括物联网设备,移动电话或不可靠网络环境中的客户端,或者在具有不完整WiFi覆盖的环境中移动的设备。
这种模式存在许多不同的选择。在撰写本文时,我们正在探索概念验证项目中的几个。这是一种令人兴奋的模式,它可以提供卓越的数据保真度保证,并且在具有挑战性的环