AWS Aurora无服务器-通信链接失败

时间:2019-10-01 21:53:18

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

我在python代码中使用MySQL Aurora Serverless集群(启用了Data API),并且遇到了import pandas as pd from pandas.io.json import json_normalize # create the dataframe df = json_normalize(data, 'laureates', ['year', 'category']) # create a column named 'Full Name' df['Full Name'] = df.firstname.str.cat(df.surname, sep=' ') print(df) id firstname surname motivation share year category Full Name 960 Arthur Ashkin "for the optical tweezers and their application to biological systems" 2 2018 physics Arthur Ashkin 961 Gérard Mourou "for their method of generating high-intensity, ultra-short optical pulses" 4 2018 physics Gérard Mourou 962 Donna Strickland "for their method of generating high-intensity, ultra-short optical pulses" 4 2018 physics Donna Strickland 963 Frances H. Arnold "for the directed evolution of enzymes" 2 2018 chemistry Frances H. Arnold 964 George P. Smith "for the phage display of peptides and antibodies" 4 2018 chemistry George P. Smith 965 Sir Gregory P. Winter "for the phage display of peptides and antibodies" 4 2018 chemistry Sir Gregory P. Winter # search for your criteria df['Full Name'][(df.category == 'physics') & (df.year == '2018')].tolist() >>> ['Arthur Ashkin', 'Gérard Mourou', 'Donna Strickland'] 异常。通常在群集休眠一段时间后才会发生这种情况。

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

异常详细信息:

  

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

如何解决此问题?我正在使用标准的boto3库

2 个答案:

答案 0 :(得分:1)

这是AWS Premium Business Support的回复。

Summary: It is an expected behavior

详细答案:

  

我看到您的Aurora Serverless出现此错误   实例处于非活动状态,一旦实例处于活动状态,您就停止接收它   活动并接受连接。请注意,这是预期的   行为。通常,Aurora Serverless的工作原理与   已配置Aurora,在Aurora Serverless中,而群集是   “休眠”没有分配计算资源,也没有分配给数据库。   接收到连接,分配了计算资源。因为   这种行为,您将不得不“唤醒”群集,这可能需要   几分钟后,第一次连接成功。

     

为避免这种情况,您可以考虑增加   客户端。另外,如果您启用了暂停功能,则可以考虑   禁用它[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无服务器数据库集群的容量-https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.setting-capacity.html

[4] Aurora无服务器价格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

答案 1 :(得分:1)

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

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

我的第一个选择是尝试使用Waiters,但RDSData没有任何侍者,然后我尝试创建一个带有Error匹配器的自定义Waiter,但只尝试匹配错误代码,忽略消息,并且因为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
    )