如何用事件总线实现数据合约?- mehdio


如果您从事数据工作,那么您很有可能多次遇到这个问题:数据是错误的,您不知道为什么。数据上游似乎有问题,但是您的内部同事都不知道为什么,我们该怎么办?我们应该联系谁?

由于数据不是一等公民,数据团队大多开始对现有基础设施进行分析,以服务于其他初始目标。他们将根据现有的运营数据库“插入”他们的管道,将数据卸载到仓库并处理其余部分。
数据团队被困在他们无法控制的运营数据库和业务部门之间。上游的问题越多,对下游的数据团队的挑战就越大。

这就是数据合同可以提供帮助的地方。数据团队有明确的方式来询问他们需要什么,并采用更严格的流程来处理变更管理。

事件驱动的架构可以帮助支持数据合约,原因有很多:

  • 事件可以是强类型的,并且每个事件都可以与一个模式版本相关联。
  • 如果您使用无服务器事件流并且基础设施是自包含的(每个主题),它会很便宜。
  • 事件平台(又名发布/订阅)为经典的下游数据消费(对象存储、数据仓库)提供内置连接器。

AWS Kinesis 或 Kafka 等技术(使用 AWS MSK 或 Confluent 等托管 Kafka)、Cloud Pub/Sub 是帮助您入门的好选择。
这个想法是与后端创建一个全新的合同,并就(数据)消费者的最佳需求达成一致。
后端人员通常有分析之外的事件驱动模式的用例。例如,微服务之间的通信。这里有两个选项:
  1. 对架构做出妥协,使其适合数据分析及其用例
  2. 创建一个专门用于数据分析用例的事件

定义创建/修改合同的流程
大多数事件平台,如 Kafka 或 AWS MSK 都有其架构注册表(AWS 的情况下为 AWS Glue 注册表)。对于创建的每个主题,您都需要注册一个schema (类似数据结构)。
在数据生产者和数据消费者之间实现这种过程的一种简单方法是重用git 进程。

所有schema 创建/更改/删除都可以通过 git pull 请求。通过明确主题的所有权和消费者,您可以快速了解谁可以批准对架构的更改。CI/CD 管道在合并时使用相应的schema 来获取和部署更改。
这种过程的美妙之处在于它迫使讨论在做出任何改变之前发生。

在用事件总线实现数据合约时,这里有几条建议。

提示1:请使用类型化模式
维护JSON模式是一件很痛苦的事情。太多的自由。类型化事件的一个共同标准是使用Avro。它受到所有模式注册中心的支持,并且与其他处理引擎(Flink、Spark等)有很多互操作性,可以进一步转化。

提示2:不要疯狂地嵌套字段
由于我们通常以柱状格式分析数据,拥有太多嵌套的复杂字段会对模式演进造成挑战,而且处理成本很高。如果你有大量的嵌套字段,可以考虑将事件拆分成多个具有特定模式的字段。

提示3:但你可以对嵌套字段做出一些妥协
如果生产者不确定所有模式的定义(例如,他们依赖于第三方的API),你可以在定义中尽量深入,并将其余的未知部分作为JSON字符串。这将使你在计算上花费更多的时间来爆炸/访问这样的字段,但它在数据生产者方面留下了更多的灵活性。

提示4:在事件中设置额外的元数据字段。
像所有者、域、团队_通道,或者用特定的字段来识别PII列,这对以后明确所有权、脉络和访问管理是有帮助的。

Schemata是一个很好的资源,可以使用或获得关于模式事件建模的灵感。

提示5:不要改变一个给定字段的数据类型。
最好用一个新的类型来重新命名一个字段。虽然我们可以在下游有一个机制来检测模式的版本,但允许在一个字段上改变类型而不重命名,总是会让人头痛。如果你接受一种情况,你将不得不处理所有其他情况。所以,如果把int改成string不会造成伤害,那么当你把int改成floator,把float改成int时会发生什么?

提示6:你仍然可以在没有事件总线的情况下实现数据契约
如果你在git里有一个地方可以保存所有操作数据库的DDL语句,你仍然可以实现上述的大部分内容。例如,在数据库上做的任何改变,都会有一个git流程来提醒需要批准的消费者。然而,这有点难,因为你把合同放在已经存在的东西上,而数据团队在创建模式时没有机会发言。


把所有权还给数据生产者
数据合同只是一种趋势,把所有权还给数据生产者,而不是让数据团队遭受我们扔给他们的任何数据。

而这是很好的;它使下游的一切都变得更容易,并避免了产品和数据之间的隔阂。

最大的挑战是组织上的。数据团队必须跨越障碍,与后端讨论新的流程,这可能是可怕的。突出当前的痛点,并使数据的消费方式变得可见,有助于推动讨论。

对于工具本身,可以使用事件平台的pub/sub服务、模式注册表和数据合同流程的git来逐步建立。

在你的公司内找到一个合适的项目发起人,并从头到尾实施管道。没有必要进行大爆炸式的迁移;从一个小的事件开始,接下来再扩展这个模式!