【问题标题】:AWS Aurora Serverless - Communication Link FailureAWS Aurora Serverless - 通信链路故障
【发布时间】:2020-01-31 05:10:18
【问题描述】:

我在我的 python 代码中使用 MySQL Aurora Serverless 集群(启用了数据 API),我收到了 communications link failure 异常。这通常发生在集群休眠一段时间后。

但是,一旦集群处于活动状态,我就不会出错。我必须每次发送 3-4 个请求才能正常工作。

异常详情:

最后一个成功发送到服务器的数据包是 0 毫秒 前。驱动程序没有收到来自服务器的任何数据包。一个错误 调用 ExecuteStatement 时发生 (BadRequestException) 操作:通讯链路故障

我该如何解决这个问题?我正在使用标准 boto3 库

【问题讨论】:

    标签: mysql amazon-web-services amazon-aurora aws-serverless


    【解决方案1】:

    这是来自 AWS Premium Business Support 的回复。

    Summary: It is an expected behavior
    

    详细回答:

    我可以看到您在使用 Aurora Serverless 时收到此错误 实例处于非活动状态,一旦您的实例处于非活动状态,您将停止接收它 主动和接受连接。请注意,这是预期的 行为。通常,Aurora Serverless 的工作方式与 预置的 Aurora ,在 Aurora Serverless 中,而集群是 “休眠”它没有分配给它的计算资源,并且当一个 db. 接收到连接,分配计算资源。因为 这种行为,您将不得不“唤醒”集群,这可能需要 如您所见,第一次连接成功需要几分钟。

    为了避免这种情况,您可以考虑增加 客户端。此外,如果您启用了暂停,您可以考虑 禁用它 [2]。禁用暂停后,您还可以调整 将最小 Aurora 容量单位设置为更高的值,以确保您的 集群总是有足够的计算资源来服务新的 连接 [3]。请注意,调整最小 ACU 可能 增加服务成本 [4]。

    另请注意,仅在某些情况下推荐使用 Aurora Serverless 工作量 [5]。如果您的工作量是高度可预测的并且您的 应用程序需要定期访问数据库,我会 建议您使用预置的 Aurora 集群/实例来确保高 您的业​​务的可用性。

    [2] Aurora Serverless 的工作原理 - Aurora Serverless 的自动暂停和恢复 - https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.how-it-works.html#aurora-serverless.how-it-works.pause-resume

    [3] 设置 Aurora Serverless 数据库集群的容量 - https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.setting-capacity.html

    [4] Aurora Serverless 价格https://aws.amazon.com/rds/aurora/serverless/

    [5] 使用 Amazon Aurora Serverless - Aurora Serverless 用例 - https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.html#aurora-serverless.use-cases

    【讨论】:

    • 非常感谢您发布此答案。听起来很傻,但我永远不会猜到“第二次尝试相同的 aws rds-data execute-statement 命令以查看通信链路故障是否消失”。但是几分钟后第二次运行该命令效果很好
    【解决方案2】:

    如果它对某人有用,这就是我在 Aurora Serverless 唤醒时管理重试的方式。

    客户端返回一个 BadRequestException,因此即使您更改客户端的配置,boto3 也不会重试,请参阅https://boto3.amazonaws.com/v1/documentation/api/latest/guide/retries.html。

    我的第一个选择是尝试使用 Waiters,但 RDSData 没有任何服务员,然后我尝试使用错误匹配器创建自定义服务员,但只尝试匹配错误代码,忽略消息,并且因为 BadRequestException 可以由sql语句中的错误我也需要验证消息,所以我使用了一种服务员函数:

    def _wait_for_serverless():
        delay = 5
        max_attempts = 10
    
        attempt = 0
        while attempt < max_attempts:
            attempt += 1
    
            try:
                rds_data.execute_statement(
                    database=DB_NAME,
                    resourceArn=CLUSTER_ARN,
                    secretArn=SECRET_ARN,
                    sql_statement='SELECT * FROM dummy'
                )
                return
            except ClientError as ce:
                error_code = ce.response.get("Error").get('Code')
                error_msg = ce.response.get("Error").get('Message')
    
                # Aurora serverless is waking up
                if error_code == 'BadRequestException' and 'Communications link failure' in error_msg:
                    logger.info('Sleeping ' + str(delay) + ' secs, waiting RDS connection')
                    time.sleep(delay)
                else:
                    raise ce
    
        raise Exception('Waited for RDS Data but still getting error')
    

    我是这样使用的:

    def begin_rds_transaction():
        _wait_for_serverless()
    
        return rds_data.begin_transaction(
            database=DB_NAME,
            resourceArn=CLUSTER_ARN,
            secretArn=SECRET_ARN
        )
    

    【讨论】:

    • 有趣的方法。我有点惊讶于实现甚至需要这个。我认为 AWS 会简单地保留请求直到启动。当然,延迟可能会有一段时间,但考虑到无服务器方法,这是可以预料的......我猜他们说最好快速失败并让用户决定做什么?
    • 无论如何,我真正的评论是,我认为最好先尝试您的真实请求,如果失败,然后在重试您的真实代码之前执行您的等待代码。这样你就可以避免在理想情况下的等待开销,而不是每次都需要它。想法?
    • 我认为 0 个活动 ACU 不是 AWS 的生产场景。对于我的用例,Aurora 很可能大部分时间都在休眠,因此开始验证它是否处于活动状态是合乎逻辑的。首先尝试您的真实要求,这将取决于使用极光的频率。
    猜你喜欢
    • 1970-01-01
    • 2012-05-27
    • 2018-02-17
    • 2012-10-14
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 2014-12-31
    相关资源
    最近更新 更多