Chronicle事件溯源的最佳实践

18-12-15 banq
    

Chronicle Microservices Framework是一个商业解决方案,您可以获得评估副本,您也可以从使用Chronicle Queue开始;Chronicle Decentred是一个开源项目,在github上提供了一些示例项目。

Chronicle Software有两个截然不同的事件溯源框架Chronicle Microservices Framework(CMF)和Chronicle Decentred。本演讲有助于突出它们彼此之间的差异以及其他事件采购解决方案。

CMF建立在Chronicle Queue之上,专为低延迟交易系统而设计。复制通常是异步的,以最小化延迟。

Chronicle Decentred是一个用于构建安全分散式分类账(例如区块链)的框架。它侧重于高吞吐量而不是低延迟和拜占庭容错。

David Schmitz 就他认为使用事件采购的最佳实践进行了精彩的演讲。大卫的演讲适用于所有事件驱动系统,并且在演讲中也有10分钟时间适用于Chronicle的框架。

再交付

他指出,确保一次交付很难。

CMF方法是假设每个有效输入都将输出到已知队列。这允许服务在上次成功发布消息后立即重新启动。这种方法的好处是:

  • 如果输入消息已传送但服务在完成之前消失,则重新处理。
  • 如果输入消息已处理但输出消息未成功写入,则假定应对其进行重新处理,直到输入消息为止。
  • 假设任何输出消息没有输出,没有副作用并且可以重放,或者如果不能,则可以产生虚拟的“成功”消息。

Chronicle Decentred定期检查点,例如每周一次。通过重播所有事件,可以从这一点恢复任何单个服务的状态。

在这两种情况下,默认情况下不会删除事件,也不能单独删除(不加密,请参阅下文)。事件以滚动方式存储在文件中,并在删除文件时删除。

命令与查询

CMF和Decentred旨在实时执行命令。要支持查询,您需要维护事先知道的“实时”查询或临时查询,维护您选择的外部数据库。

性能

这是CMF和Decentred差别很大的方式之一。

在他的演讲中,David给出了一个服务示例,该服务在66毫秒内执行100次操作。这是0.66毫秒的平均延迟。

CMF旨在实现始终如一的低延迟,其中重点是系统看到的最差延迟。一个关键的衡量标准通常是99.9%达到低延迟,而不是平均或典型的延迟。

我们最近帮助一级银行客户构建了一个带有3个微服务的订单管理系统,其中线到线延迟低于20微秒,99.9%的时间用于每秒20,000条消息的吞吐量。

Chronicle Decentred专为高吞吐量而设计。每个链可以在服务器集群中处理大量消息,例如50K / s到400K / s,具体取决于硬件。但是,延迟是达到共识的时间,可能是5毫秒到500毫秒,具体取决于它们之间的网络

人类可读的格式

为了支持模式更改,David提出了一种人类可读的格式,可以在数据模型更改时更轻松地翻译不同版本的数据传输对象JSON是这样做的常见选择,但是,我发现它不像YAML那样易读。

人类可读格式的一个缺点是它们没有二进制格式那么快,因此,CMF和Decentred都支持YAML的二进制格式,它可以自动转换为YAML,但速度提高了2-3倍,并且作为较低级别的二进制格式,它更快但不易维护。

YAML优于JSON的一些优点

  • 更简洁。
  • 更好地支持复杂的数据类型。
  • 直接支持类型和评论。

YAML的缺点

  • 有关如何编写数据的更多选项。
  • 人类可读性在旁观者的眼中,使得编码变得更加困难。
  • 一个更简单的规范,mroe跨语言的一致支持。
  • YAML几乎是一套超级JSON,但并不完整。例如,在属性名称之后,您需要YAML中的冒号空间,而JSON不需要空格。

有了各种可用的序列化选项,我们倾向于从最简单的方法开始,并在我们拥有一个工作系统后再进行优化。这使我们能够识别需要优化的性能最敏感的消息,例如订单和市场数据,并使大多数消息包括更复杂但更少延迟敏感的消息,例如静态数据和配置。

批处理

在交易系统中,通常每天或每周执行一次。这可以通过以新事件开始时加载的事件形式拍摄快照来实现。大多数交易系统在一夜之间或周末都有很长的停机时间。

更新事件

事件驱动的系统不是为编写事件而编写的。事件失败,在这种情况下,可以添加新的正确事件,或者事件成功但不正确,并且需要添加一个或多个事件来纠正或撤消操作。在设计之前,没有简单的方法来编辑事件。

拥有控制事件的优先级队列是相当普遍的,只要尚未处理修改的事件,这可用于注入删除,取消或更正事件。

必须非常小心避免或管理任何可以执行的事件,但以后不能撤销。

GDPR和加密数据

在不破坏整个队列或流的情况下删除数据的一种方法是使用与具有用户特定密钥的用户相关的密钥来加密所有数据。要“删除”用户,您只需删除密钥即可。Chronicle Queue支持插件在编写和读取时加密和解密消息,可以与密钥管理集成。

另一种方法是匿名化数据,因此没有任何流识别用户,而是由其他系统处理。