3

我将用 Twitter 说明我的问题。例如,Twitter 具有基于微服务的架构,这意味着不同的进程位于不同的服务器中并拥有不同的数据库。

出现一条新推文,服务器 A 在其自己的数据库中存储一些数据,生成新事件并触发它们。服务器 B 和 C 此时没有收到这些事件,也没有在他们的数据库中存储任何内容,也没有处理任何内容。

创建推文的用户想要编辑该推文。为了实现这一点,所有三个服务 A、B、C 应该已经处理了所有事件并将所有需要的数据存储到 db,但是服务 B 和 C 还不一致。这意味着我们目前无法提供编辑功能

正如我所看到的,一种可能的解决方法是切换到立即一致性,但这会带走所有基于微服务的架构优势,并且可能会导致紧耦合问题。

另一种解决方法是在一段时间内限制用户的操作,直到所有必要服务的数据不一致。可能是一个解决方案,取决于客户及其业务需求。

另一种解决方法是添加额外的逻辑或可能的服务 D,它将编辑存储为用户的操作,并仅在它们一致时将其应用于数据。缺点是大大增加了系统的复杂性。

并且有两阶段提交,但那是 1) 不是很可靠 2) 慢。
我认为在 Twitter 的负载情况下,缓慢是一个巨大的缺点。但也许它可以被解决,而缺乏可靠性则不能,同样,如果不增加解决方案的复杂性。

所以,问题是:

  1. 对于图示的情况是否有任何好的解决方案,或者只有我提到的解决方法?也许一些编程平台或数据库?
  2. 我是否误解了某些东西并且某些解决方法不正确?
  3. 除了最终一致性之外,是否还有其他方法可以保证所有数据都将被存储并且所有必要的操作都将由其他服务执行?

为什么为这个用例选择了最终一致性?正如我所看到的,如果我们谈论的是事件驱动的方法,当某些服务将在某些事件被触发时开始工作时,它是保证某些数据将被存储或某些操作将被执行的唯一方法,并且按照我的示例,该事件将是“已创建推文”。因此,如果服务 B 和 C 出现故障,我需要在它们再次启动时能够成功执行操作。

我想要达到的目标是:可靠性、承受高负载的能力、足够复杂的解决方案。任何相关主题的任何链接将不胜感激。

如果这种方法有自然的局限性,而我想要的不能使用这种范式实现,那也没关系。我只需要知道这个问题真的还没有解决。

4

2 回答 2

0

在这类架构中,关键是让每个服务在写入时都是自治的:即使其他应用程序级服务都没有启动,它也可以进行写入。

因此,在类似 twitter 的服务的示例中,您可以将其建模为

Service A manages the content of a post

因此,当用户发布帖子时,会在服务 A 的数据库中进行写入,并且从那一刻起可以编辑帖子,因为编辑只是对 A 的请求。

如果有其他服务使用来自 A 的“发布内容”更改事件,并且在“新发布”事件公开某些功能之后,该功能将不会公开,直到该服务看到该事件(是的重言式)。但这只是物理学:太阳可能在五分钟前变成超新星,在我们“看到光”之前,我们不能采取任何行动(不是我们可以采取的行动)。

于 2021-02-01T01:39:49.637 回答
0

这都是关于权衡的。在您的示例中使用最终一致性可能意味着用户可能在几秒钟内无法编辑,因为大多数最终一致的技术不会花费太长时间来跨节点复制数据。因此,在这个用例中,这是绝对可以接受的,因为用户的操作非常缓慢。

例如 :

MongoDB 默认是一致的:读取和写入都发给副本集的主要成员。应用程序可以选择从辅助副本中读取,默认情况下数据最终是一致的。

来自官方 MongoDB FAQ

另一个越来越流行的替代方案是使用流平台,例如 Apache Kafka,它取决于您的架构设计,流消费者处理数据的速度(以实现最终一致性)。由于流平台非常快,因此主要取决于流处理器的速度,才能在正确的位置提供数据。因此,在大多数情况下,我们谈论的是毫秒,甚至不是秒。

于 2017-04-05T07:21:18.260 回答