REL04-BP01 确定所依赖的分布式系统的类型 - AWS Well-Architected 框架

REL04-BP01 确定所依赖的分布式系统的类型

分布式系统可以是同步系统、异步系统或批处理系统。同步系统必须尽可能快地处理请求,并使用 HTTP/S、REST 或远程过程调用(RPC,Remote Procedure Call)协议,同步地发出请求和响应调用,来彼此通信。异步系统在彼此通信时通过中间服务来异步交换数据,无需将各个系统耦合在一起。批处理系统则会接收大量输入数据,无需人工干预即可运行自动数据处理,并生成输出数据。

期望结果:设计能够与同步、异步和批处理依赖项进行有效交互的工作负载。

常见反模式:

  • 工作负载无限期地等待其依赖项的响应,这可能导致工作负载客户端超时,不知道其请求是否已被接收。

  • 工作负载使用会同步调用彼此的依赖系统链。这种模式要求每个系统都可用并能成功处理请求,整个链才能成功运行,这导致很容易出现崩溃行为,影响到整体可用性。

  • 工作负载与其依赖项异步通信,并依赖于保证消息传递且仅传递一次的概念,但仍然会经常收到重复的消息。

  • 工作负载没有使用正确的批处理调度工具,导致允许并行执行相同的批处理作业。

建立此最佳实践的好处:对于给定的工作负载,通常能够在同步、异步和批处理之间实施一种或多种通信方式。此最佳实践可帮助您确定,选择每种通信方式所面对的不同权衡,以便让您的工作负载能够承受其任意依赖项中断所带来的干扰。

在未建立这种最佳实践的情况下暴露的风险等级:

实施指导

以下各节针对每种依赖项,介绍了一般性实施指导和具体实施指导。

一般指导

  • 确保您的依赖项提供的性能和可靠性服务级别目标(SLO,Service-Level Objective),能够满足工作负载的性能和可靠性要求。

  • 使用 AWS 可观测性服务监控响应时间和错误率,确保依赖项提供的服务达到工作负载所需的水平。

  • 确定您的工作负载在与其依赖项进行通信时,可能会遇到的潜在挑战。分布式系统面临着诸多挑战,可能会增加架构的复杂性、运营负担和成本。常见的挑战包括延迟、网络中断、数据丢失、可扩展性和数据复制延迟。

  • 实施强大的错误处理和日志记录,在依赖项遇到问题时帮助排查问题。

同步依赖项

在同步通信中,工作负载会向其依赖项发送请求并停止操作来等待响应。当其依赖项收到请求时,依赖项会尝试尽快处理请求并将响应发送回工作负载。同步通信面临的一个巨大挑战是它会导致时间耦合,这要求您的工作负载及其依赖项同时可用。当您的工作负载需要与其依赖项以同步方式通信时,请考虑以下指南:

  • 工作负载在执行单个功能时,不应依赖多个同步依赖项。这种依赖项链会导致整体更加脆弱,因为要想完成请求,路径中的所有依赖项都必须可用。

  • 请确定当依赖项运行状况不佳或不可用时,您采用的错误处理和重试策略。避免使用双模态行为。双模态行为是指工作负载在正常模式和故障模式下表现出不同的行为。有关双模态行为的更多详细信息,请参阅 REL11-BP05 使用静态稳定性来防止双模态行为

  • 请记住,快速失效机制比让工作负载等待要好。例如,《AWS Lambda 开发人员指南》描述了在调用 Lambda 函数时如何处理重试和失败。

  • 设置工作负载调用其依赖项时的超时。这种技术可以避免等待太长时间或无限期等待响应。有关此主题的实用讨论,请参阅 Tuning AWS Java SDK HTTP request settings for latency-aware Amazon DynamoDB applications

  • 在完成单个请求时,尽可能减少从工作负载对依赖项进行的调用次数。在它们之间进行的频繁调用会增加耦合和延迟。

异步依赖项

要想临时将工作负载与其依赖项解耦,就应该采取异步通信。使用异步方法,您的工作负载无需等待其依赖项或依赖项链发送响应,即可继续进行任何其他处理。

当您的工作负载需要与其依赖项以异步方式通信时,请考虑以下指南:

  • 根据应用场景和要求,确定是使用消息收发还是事件流。消息收发可让工作负载通过消息代理发送和接收消息,从而与其依赖项进行通信。事件流可让工作负载及其依赖项利用流服务来发布和订阅以连续数据流形式交付且需尽快处理的事件。

  • 消息收发和事件流以不同的方法来处理消息,因此您需要根据以下因素作出权衡决策:

    • 消息优先级:消息代理可以先处理高优先级消息,再处理普通消息。在事件流中,所有消息具有相同的优先级。

    • 消息使用:消息代理确保使用者能够收到消息。事件流使用器必须跟踪所读取的每一条消息。

    • 消息排序:除非对消息收发使用先进先出(FIFO)方法,否则无法保证按照发送消息的确切顺序接收消息。事件流则始终保留数据生成的顺序。

    • 消息删除:使用消息收发时,使用者必须在处理消息后将其删除。事件流服务则将消息附加到流并一直保留在流中,直到消息的保留期到期。这种删除策略让事件流非常适合重放消息。

  • 定义如何让工作负载在其依赖项完成工作时了解这一信息。例如,当工作负载异步调用 Lambda 函数时,Lambda 将请求置于队列中并返回成功响应,而不返回其他信息。处理完成后,Lambda 函数可以将结果发送到目标,该目标可根据成功或失败进行配置。

  • 利用幂等性,构建工作负载以处理重复的消息。幂等性意味着,即使您的工作负载针对同一消息多次生成结果,这些结果也会保持不变。需要指出的是,如果发生网络故障或未收到确认,则消息收发服务将重新发送消息。

  • 如果您的工作负载没有从其依赖项获得响应,则需要重新提交请求。请考虑限制重试次数,以保留工作负载的 CPU、内存和网络资源用于处理其他请求。AWS Lambda 文档介绍了如何处理异步调用错误。

  • 利用合适的可观测性、调试和跟踪工具,来管理和操作工作负载与其依赖项的异步通信。您可以使用 Amazon CloudWatch 来监控消息收发事件流服务。您还可以使用 AWS X-Ray 检测工作负载,快速获得洞察来排查问题。

批处理依赖项

批处理系统获取输入数据,启动一系列作业来处理数据,然后生成一些输出数据,整个过程无需人工干预。根据数据大小,作业的运行时间可能只需要几分钟,而在某些情况下,也可能长达数天。当您的工作负载与其批处理依赖项通信时,请考虑以下指南:

  • 定义工作负载应运行批处理作业的时间窗口。工作负载可以设置重复模式来调用批处理系统,例如每小时或每月月底。

  • 确定数据输入的位置,以及处理后数据输出的位置。选择一种能让工作负载大规模读取和写入文件的存储服务,例如 Amazon Simple Storage Service(Amazon S3)Amazon Elastic File System(Amazon EFS)适用于 Lustre 的 Amazon FSx

  • 如果工作负载需要调用多个批处理作业,则可以利用 AWS Step Functions 来简化在 AWS 内部或本地运行的批处理作业的编排。此示例项目演示了使用 Step Functions、AWS Batch 和 Lambda 编排批处理作业。

  • 监控批处理作业以发现异常情况,例如作业完成用时超过了应有的时间。您可以使用 CloudWatch Container Insights 之类的工具来监控 AWS Batch 环境和作业。在这种情况下,工作负载会从头停止下一个作业,并向相关人员通知异常情况。

资源

相关文档:

相关视频:

相关工具: