本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
分散聚集模式
意图
scatter-gather 模式是一种消息路由模式,它涉及向多个收件人广播相似或相关的请求,并使用名为聚合器的组件将他们的响应聚合回一条消息。这种模式有助于实现并行化、减少处理延迟和处理异步通信。使用同步方法实现分散-收集模式很简单,但更强大的方法是在异步通信中将其实现为消息路由,无论有没有消息服务。
动机
在应用程序处理中,一个可能需要很长时间才能按顺序处理的请求可以拆分为多个并行处理的请求。您还可以通过 API 调用向多个外部系统发送请求以获得响应。当您需要来自多个来源的输入时,分散-聚集模式非常有用。Scatter-Gather 汇总结果,以帮助您做出明智的决定或为请求选择最佳响应。
顾名思义,分散-聚集模式由两个阶段组成:
-
分散阶段处理请求消息并将其并行发送给多个收件人。在此阶段,应用程序将请求分散到网络中,并继续运行,无需等待即时响应。
-
在收集阶段,应用程序会收集收件人的回复,并将它们筛选或组合成统一的响应。收集完所有响应后,可以将它们聚合为单个响应,也可以选择最佳响应进行进一步处理。
适用性
在以下情况下使用分散-聚集模式:
-
您计划汇总和整合来自各种 API 的数据,以创建准确的响应。该模式将来自不同来源的信息整合为一个有凝聚力的整体。例如,预订系统可以向多个收件人发出请求,以获取来自多个外部合作伙伴的报价。
-
必须将同一个请求同时发送给多个收件人才能完成交易。例如,您可以使用此模式并行查询库存数据,以检查产品的供货情况。
-
您想实现一个可靠且可扩展的系统,通过在多个收件人之间分配请求来实现负载平衡。如果一个收件人失败或负载过高,其他收件人仍然可以处理请求。
-
在实现涉及多个数据源的复杂查询时,您需要优化性能。您可以将查询分散到相关数据库,收集部分结果,然后将它们组合成一个全面的答案。
-
您正在实现一种 map-reduce 处理,其中数据请求被路由到多个数据处理端点进行分片和复制。对部分结果进行筛选和组合以构成正确的响应。
-
您希望在键值数据库中写入密集型工作负载中跨分区键空间分配写入操作。聚合器通过查询每个分片中的数据来读取结果,然后将它们合并成单个响应。
问题和注意事项
-
容错:这种模式依赖于多个并行工作的接收者,因此必须优雅地处理故障。为了减轻收件人故障对整个系统的影响,您可以实施冗余、复制和故障检测等策略。
-
横向扩展限制:随着处理节点总数的增加,相关的网络开销也会增加。每个涉及网络通信的请求都可能增加延迟,并对并行化的好处产生负面影响。
-
响应时间瓶颈:对于要求在完成最终处理之前处理所有收件人的操作,整个系统的性能会受到最慢接收者的响应时间的限制。
-
部分响应:当请求分散到多个收件人时,某些收件人可能会超时。在这些情况下,实现应告知客户响应不完整。您还可以使用界面前端显示响应聚合详细信息。
-
数据一致性:在处理多个收件人的数据时,必须仔细考虑数据同步和冲突解决技术,以确保最终的汇总结果准确一致。
实施
高级架构
分散收集模式使用根控制器将请求分发给将处理请求的收件人。在分散阶段,此模式可以使用两种机制向收件人发送消息:
-
按分发分布:应用程序有一个已知的收件人列表,必须调用这些收件人才能获得结果。接收者可以是具有独特功能的不同进程,也可以是已扩展以分配处理负载的单个流程。如果任何处理节点超时或出现响应延迟,则控制器可以将处理重新分配给另一个节点。
-
拍卖分散:应用程序使用发布- 订阅模式向感兴趣的收件人广播消息。在这种情况下,收件人可以随时订阅消息或退出订阅。
按分布进行分散
在 scatter by 分发方法中,根控制器将传入的请求划分为独立的任务,并将它们分配给可用的接收者(分散阶段)。每个接收者(进程、容器或 Lambda 函数)独立并行地进行计算,并生成部分响应。当收件人完成任务时,他们会将响应发送给聚合器(收集阶段)。聚合器合并部分响应并将最终结果返回给客户端。下图说明了此工作流程。
![分散-聚集模式的分布方法进行散射](images/scatter-gather-1.png)
控制器(数据文件处理器)负责协调整组调用,并知道要调用的所有预订端点。它可以将超时参数配置为忽略花费时间过长的响应。发送请求后,聚合器会等待来自每个端点的响应。为了实现弹性,可以将每个微服务与多个实例一起部署,以实现负载平衡。聚合器获取结果,将它们组合成一条响应消息,并在进一步处理之前删除重复的数据。超时的响应将被忽略。控制器也可以充当聚合器,而不是使用单独的聚合器服务。
通过拍卖分散
如果控制器不知道收件人或收件人是松散耦合的,则可以使用按拍卖分散的方法。在此方法中,收件人订阅主题,控制器将请求发布到该主题。收件人将结果发布到响应队列。由于根控制器不知道收件人,因此收集过程使用聚合器(另一种消息传递模式)来收集响应并将其提炼成单个响应消息。聚合器使用唯一的 ID 来识别一组请求。
例如,在下图中,按拍卖分散法用于为航空公司的网站实现航班预订服务。该网站允许用户搜索和显示航空公司自己的航空公司及其合作伙伴承运人的航班,并且必须实时显示搜索状态。航班预订服务由三个搜索微服务组成:直飞航班、中途航班和合作伙伴航空公司。合作伙伴航空公司搜索会调用合作伙伴的 API 端点来获取响应。
![通过拍卖方法对分散-聚集模式进行分散](images/scatter-gather-2.png)
-
航班预订服务(控制器)将搜索条件作为客户端的输入,然后处理请求并将其发布到该主题。
-
控制器使用唯一的 ID 来识别每组请求。
-
客户端将步骤 6 的唯一 ID 发送给聚合器。
-
已订阅预订主题的预订搜索微服务会收到请求。
-
微服务处理请求并将给定搜索条件的席位可用性返回到响应队列。
-
聚合器整理存储在临时数据库中的所有响应消息,按唯一 ID 对航班进行分组,创建单个统一响应,然后将其发送回客户端。
使用实现方式 AWS 服务
按分布进行分散
在以下架构中,根控制器是一个数据文件处理器 (Amazon ECS),它将传入的请求数据拆分为单独的亚马逊简单存储服务 (Amazon S3) 存储桶并启动工作流程。 AWS Step Functions 该工作流下载数据并启动并行文件处理。Parallel
状态等待所有任务返回响应。 AWS Lambda 函数会聚合数据并将其保存回 Amazon S3。
![在架构上 AWS 通过分布方法实现分散](images/scatter-gather-3.png)
下图说明了带有Parallel
状态的 Step Functions 工作流程。
![在 AWS -Step Functions 工作流程中实现按分布分散的方法](images/scatter-gather-4.png)
通过拍卖分散
下图显示了按拍卖方法分散的 AWS 架构。root 控制器航班预订服务将航班搜索请求分散到多个微服务。通过亚马逊简单通知服务 (Amazon SNS) Simple Notification Service 实现了发布-订阅渠道,这是一项用于通信的托管消息服务。Amazon SNS 支持分离的微服务应用程序之间的消息或与用户的直接通信。您可以将收件人的微服务部署在亚马逊 Elastic Kubernetes Service (Amazon EKS) 或亚马逊弹性容器服务 (Amazon ECS) 上,以实现更好的管理和可扩展性。飞行结果服务将结果返回给客户端。它可以在其他容器编排服务(例如 Amazon ECS AWS Lambda 或 Amazon EKS)中实现。
![按拍卖方法分散的 AWS 架构](images/scatter-gather-5.png)
-
航班预订服务(控制器)将搜索条件作为客户端的输入,然后处理请求并将其发布到 SNS 主题。
-
控制器将唯一 ID 发布到 Amazon Aurora 数据库以识别请求。
-
客户端将步骤 6 的唯一 ID 发送给客户端。
-
已订阅预订主题的预订搜索微服务会收到请求。
-
在亚马逊简单队列服务 (Amazon SQS) Simple Queue Service 中,微服务处理请求并将给定搜索条件的座位可用性返回到响应队列。聚合器整理所有响应消息并将其存储在临时数据库中。
-
飞行结果服务按唯一 ID 对航班进行分组,创建单个统一响应,然后将其发送回客户端。
如果要在此架构中添加其他航空公司搜索,则可以添加订阅 SNS 主题并发布到 SQS 队列的微服务。
总而言之,分散聚集模式使分布式系统能够实现高效的并行化、减少延迟并无缝处理异步通信。
GitHub 存储库
有关此模式示例架构的完整实现,请参阅 GitHub 存储库,网址为 https://github.com/aws-samples/ asynchronous-messaging-workshop /tree/master/code/lab
研讨会
-
解耦@@ 微服务研讨会中的分散收集实验室