您分布的巨石正在您身后

哈Ha!

今天的翻译不仅涉及微服务,而且涉及的不是微服务(今天每个人都在谈论这个话题),而且还提醒人们称锹为锹是多么重要。 有时有必要向微服务架构过渡,但是正如作者再次强调的那样,它需要仔细考虑后果。 享受阅读的成果!



我不时问同样的问题。
是否有如此重要的真理,只有少数人同意? -彼得·泰尔
在我坐下这篇文章之前,我在一个问题上尝试了很长时间,而今天这个趋势已经成为一个严重的趋势-它与微服务有关。 我想现在我有话要说; 一些发现是基于反思的,而另一些则是基于实践经验的。 所以,我告诉你。
让我们从一个重要的真理开始,它将像北极星一样一路为我们提供参考。

大多数微服务实现只不过是分布式整体。

巨石时代


任何系统都是从整体应用程序开始的。 在这里,我将不讨论该主题的详细信息-很多已经写了很多。 但是,有关整体资源的信息最多是用于开发人员的生产力和可伸缩性等问题,而在括号中则是互联网公司中最有价值的资产:数据。



典型的整体应用架构

如果数据是如此重要,那么为什么所有注意力都集中在任何其他主题上,而不是所有这些呢? 答案通常很简单:因为它们不像数据问题那样痛苦。
整体可能是系统生命周期中您唯一的阶段:

  • 充分了解您的数据模型;
  • 您可以与数据进行协作(假定已为您的应用程序正确选择了数据库)。

就数据而言,整体是理想的。 而且,由于数据是任何公司中最有价值的资产,因此,最好不要破坏整体,除非您有充分的理由或多种原因结合在一起。 在大多数情况下,这种决定性的原因是需要扩展(因为我们生活在具有固有物理限制的现实世界中)。

当这一时刻到来时,您的系统很可能会陷入新的停滞状态:它变成了分布式整体

分布式巨石时代


假设您的公司进展顺利,并且应用程序需要增长。 您拥有越来越多的大客户,并且就一系列机会及其数量而言,您对计费和报告的要求已经发生了变化。

认真考虑拆除整体组件,尤其是,您将尝试实施两项小型服务,其中一项将提供报告,第二项将是计费。 这些新服务很可能会提供HTTP API并具有用于长期状态存储的专用数据库。 经过多次提交,您就像Unbabel的我们一样 ,可能会得到类似于下图的内容。



将计费和报告服务与主要的整体应用程序分离后,系统架构的一般视图

一切都按计划进行。

  • 团队继续将整体式设备拆分为较小的系统;
  • 持续集成/输送输送机的工作就像发条一样;
  • Kubernetes集群很健康,工程师对所有事情都充满生产力和满意。

生活是美好的。

但是,如果我说现在有邪恶的阴谋在与你交织在一起呢?

现在,查看您的系统,您会发现数据已经分布在许多不同的系统上。 您从拥有一个存储所有数据对象的唯一数据库的阶段开始,现在您的数据对象已散布到不同的地方。 您可能会认为这不是问题,因为需要微服务来创建抽象和密封数据,从而隐藏了系统的内部复杂性。

你是完全正确的。 但是随着规模的扩大,出现了更复杂的问题:现在,您随时都必须满足业务需求(例如,跟踪某些指标),从而需要访问多个系统中的数据。

怎么办 实际上,有很多选择。 但是,您急着需要为最近在您这里注册的大量客户提供服务,因此您必须在“快速”和“良好”之间找到平衡。 在讨论了细节之后,您决定构建一个额外的系统来执行某些ETL工作,从而为最终任务的解决做出贡献。 该系统必须有权访问包含您所需信息的所有只读副本。 下图显示了这样的系统如何工作。



解析ETL系统的一般示例(在Unbabel中,我们将其称为“自动翻译分析”)

在Unbabel,我们采用了这种方法,因为:

  • 它不会过多地影响每个微服务的性能;
  • 它不需要重大的基础架构更改(只需添加新的微服务);
  • 我们能够迅速地满足我们的业务需求。

经验表明,这种方法将在一段时间内起作用-直到达到一定规模。 在Unbabel,他一直为我们服务很好,直到最近,当我们开始面临越来越严重的挑战时。 这让我们有些头疼:

1.数据变更

微服务的主要优势之一是封装。 数据的内部表示可以更改,但这不会影响系统的客户端,因为它们通过外部API进行通信。 但是,我们的策略要求直接访问数据的内部表示,因此,只要团队仅对数据的表示进行了一些更改(例如,将字段重命名或将类型从text更改为uuid ),我们还必须更改并重新部署ETL-服务。

2.需要处理许多不同的数据方案

随着需要连接的系统数量的增加,我们不得不处理越来越多的异构数据呈现方式。 显然,我们无法扩展所有这些方案,它们之间的关系及其表示。

万恶之源

为了全面了解系统中正在发生的事情,我们必须停止采用类似于整体的方法。 整个区别是我们没有一个系统和一个数据库,而是数十个这样的对,每个对都有自己的数据表示形式。 而且,在某些情况下,相同的数据被跨多个系统复制。

我更喜欢将这样的系统称为分布式整体。 怎么了 由于它完全不适合跟踪系统中的更改,因此显示系统状态的唯一方法是收集直接连接到所有微服务的数据仓库的服务。 有趣的是,有多少互联网巨头在其发展的某个时刻也面临着类似的挑战。 在这种情况下,我一直想举一个很好的例子,就是LinkedIn网络。



Linkedin的信息流在2011年左右就是这种数据灾难-来源

此刻,您可能会想:“你们将如何处理所有这些?” 答案很简单:您需要开始跟踪更改并跟踪重要的操作。

使用事件源打破分布式整体

与世界上几乎所有其他地区一样,Internet上的系统也具有响应能力。 因此,对API的请求可能导致将新记录插入数据库。 当前,在大多数情况下,此类细节不会打扰我们,因为我们主要对更新数据库状态感兴趣。 更新数据库状态是某些事件(在这种情况下,是API请求)的条件结果。 事件现象很简单,但是,事件的可能性非常大-它们甚至可以被用来破坏分布式整体。

事件不过是系统中发生的某些修改的不变事实 。 在微服务架构中,事件变得至关重要,并有助于理解数据流,并在事件基础上推断出多个系统的聚合状态。 从整个系统的角度来看,每个执行微操作的微服务都应生成一个事件以及与此事件表示的事实相关的所有基本信息。

也许您有一个问题:
“生成事件的微服务如何帮助我解决分布式整体问题?”

如果您具有生成事件的系统,那么可能存在具有以下属性的事实日志:

  • 缺乏与任何数据仓库的绑定:事件通常使用JSON,Avro或Protobufs等二进制格式进行序列化;
  • 不变性:一旦事件产生,就无法更改;
  • 可重现性:可以恢复任何给定时间点的系统状态; 为此,足以“重播”事件日志。

使用此日志,您可以在应用程序级别使用任何类型的逻辑来显示状态。 您不再与任何一组微服务和N种显示数据的方式相关联。 现在,唯一的事实来源和唯一的数据仓库就是存储事件的存储库。

以下是一些原因,为什么我觉得事件日志是帮助打破Distributed Monolith的方式:

1.真理的唯一来源

在这种新方案中,取代了维护连接到(多个)异构数据库可能需要的N个数据源的方法,最终的事实恰好存储在一个事件库中。

2.通用数据格式

在系统的先前版本中,由于我们直接连接到数据库,因此必须处理许多数据格式。 在新的布局中,我们可以更加灵活地采取行动。

假设您喜欢一个朋友发布的Instagram照片。 可以描述这样的动作:“ 用户X喜欢图片P ”。 这是代表这一事实的事件:



与AVO(演员,动词​​,宾语)方法相对应的事件,用于模拟用户选择自己喜欢的图片的事实。

3.生产者与消费者之间的交流减弱

最后但并非最不重要的一点是,事件操作的最大优势之一是有效削弱了数据生产者与消费者之间的通信。 这种情况不仅简化了扩展,而且减少了它们之间的依赖性。 在这种情况下,系统之间剩余的唯一合同是事件图。



在本文的开头提出了一个问题:是否有一个如此重要的真理,只有少数人同意?

让我在结束这次旅行时回到它。 我相信大多数公司在开始迁移到微服务架构时都不会将数据视为“一流实体”。 有人认为仍然可以通过API进行所有数据更改,但是这种方法最终导致服务本身不断复杂化。

我相信,捕获微服务体系结构中的数据更改的唯一真实方法是使系统根据严格定义的合同发出事件。 具有正确编译的事件日志可让您根据任何一组业务需求显示大量数据。 在这种情况下,您只需要对相同的事实应用不同的规则。 在某些情况下,如果您的公司(尤其是产品经理)将数据视为产品,则可以避免此类数据碎片化。 但是,这是另一篇文章的主题。

Source: https://habr.com/ru/post/zh-CN453470/


All Articles