【问题标题】:AWS: Why does my RDS instance keep starting after I turned it off?AWS:为什么我的 RDS 实例在我关闭后仍然启动?
【发布时间】:2018-06-25 17:15:47
【问题描述】:

我在 AWS 上有一个 RDS 数据库实例,目前已将其关闭。但是,每隔几天它就会自行启动。我目前没有运行任何其他服务。

我的 RDS 日志中有这个事件: “数据库实例正在启动,因为它超过了允许的最大停止时间。”

为什么我的 RDS 实例可以停止多长时间?我只想将我的项目搁置几周,但 AWS 不允许我关闭我的数据库?闲置的成本为 12.50 美元/月,所以我不想为此付费,我当然也不希望 AWS 为我启动一个不被使用的实例。

请帮忙!

【问题讨论】:

    标签: database amazon-web-services aws-lambda


    【解决方案1】:

    这是new feature的限制。

    您一次最多可以停止一个实例 7 天。 7天后会自动启动。有关停止和启动数据库实例的更多详细信息,请参阅 Amazon RDS 用户指南中的Stopping and Starting a DB Instance

    您可以设置 cron 作业以在 7 天后再次停止实例。您还可以更改为更小的实例大小以节省资金。

    另一个选项是即将推出的Aurora Serverless,它会自动为您停止和启动。 24/7 运行时,它可能比专用实例更昂贵。

    最后,总是有Heroku 为您提供free database instance,它会在一些限制下自行启动和停止。


    您也可以尝试将以下 CloudFormation 模板保存为KeepDbStopped.yml,然后使用此命令进行部署:

    aws cloudformation deploy --template-file KeepDbStopped.yml --stack-name stop-db --capabilities CAPABILITY_IAM --parameter-overrides DB=arn:aws:rds:us-east-1:XXX:db:XXX
    

    确保将 arn:aws:rds:us-east-1:XXX:db:XXX 更改为您的 RDS ARN。

    Description: Automatically stop RDS instance every time it turns on due to exceeding the maximum allowed time being stopped
    Parameters:
      DB:
        Description: ARN of database that needs to be stopped
        Type: String
        AllowedPattern: arn:aws:rds:[a-z0-9\-]+:[0-9]+:db:[^:]*
    Resources:
      DatabaseStopperFunction:
        Type: AWS::Lambda::Function
        Properties:
          Role: !GetAtt DatabaseStopperRole.Arn
          Runtime: python3.6
          Handler: index.handler
          Timeout: 20
          Code:
            ZipFile:
              Fn::Sub: |
                import boto3
                import time
    
                def handler(event, context):
                  print("got", event)
                  db = event["detail"]["SourceArn"]
                  id = event["detail"]["SourceIdentifier"]
                  message = event["detail"]["Message"]
                  region = event["region"]
                  rds = boto3.client("rds", region_name=region)
    
                  if message == "DB instance is being started due to it exceeding the maximum allowed time being stopped.":
                    print("database turned on automatically, setting last seen tag...")
                    last_seen = int(time.time())
                    rds.add_tags_to_resource(ResourceName=db, Tags=[{"Key": "DbStopperLastSeen", "Value": str(last_seen)}])
    
                  elif message == "DB instance started":
                    print("database started (and sort of available?)")
    
                    last_seen = 0
                    for t in rds.list_tags_for_resource(ResourceName=db)["TagList"]:
                      if t["Key"] == "DbStopperLastSeen":
                        last_seen = int(t["Value"])
    
                    if time.time() < last_seen + (60 * 20):
                      print("database was automatically started in the last 20 minutes, turning off...")
                      time.sleep(10)  # even waiting for the "started" event is not enough, so add some wait
                      rds.stop_db_instance(DBInstanceIdentifier=id)
    
                      print("success! removing auto-start tag...")
                      rds.add_tags_to_resource(ResourceName=db, Tags=[{"Key": "DbStopperLastSeen", "Value": "0"}])
    
                    else:
                      print("ignoring manual database start")
    
                  else:
                    print("error: unknown database event!")
      DatabaseStopperRole:
        Type: AWS::IAM::Role
        Properties:
          AssumeRolePolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Action:
                  - sts:AssumeRole
                Effect: Allow
                Principal:
                  Service:
                    - lambda.amazonaws.com
          ManagedPolicyArns:
            - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
          Policies:
            - PolicyName: Notify
              PolicyDocument:
                Version: '2012-10-17'
                Statement:
                  - Action:
                      - rds:StopDBInstance
                    Effect: Allow
                    Resource: !Ref DB
                  - Action:
                      - rds:AddTagsToResource
                      - rds:ListTagsForResource
                      - rds:RemoveTagsFromResource
                    Effect: Allow
                    Resource: !Ref DB
                    Condition:
                      ForAllValues:StringEquals:
                        aws:TagKeys:
                          - DbStopperLastSeen
      DatabaseStopperPermission:
        Type: AWS::Lambda::Permission
        Properties:
          Action: lambda:InvokeFunction
          FunctionName: !GetAtt DatabaseStopperFunction.Arn
          Principal: events.amazonaws.com
          SourceArn: !GetAtt DatabaseStopperRule.Arn
      DatabaseStopperRule:
        Type: AWS::Events::Rule
        Properties:
          EventPattern:
            source:
              - aws.rds
            detail-type:
              - "RDS DB Instance Event"
            resources:
              - !Ref DB
            detail:
              Message:
                - "DB instance is being started due to it exceeding the maximum allowed time being stopped."
                - "DB instance started"
          Targets:
            - Arn: !GetAtt DatabaseStopperFunction.Arn
              Id: DatabaseStopperLambda
    

    它至少对一个人有效。如果您有问题,请报告here

    【讨论】:

    • 这是新“功能”的一个非常令人失望的方面。为了停放这个实例,我现在需要每 7 天登录一次并关闭它,否则我最终会为此付费。 AWS 做出了多么糟糕的决定。通常我喜欢 AWS,但这有点令人沮丧。不过,感谢您的帮助和澄清。
    • 或者您可以使用预定的 Lambda 编写脚本。
    • 好的,我会检查一下,kchick,谢谢。顺便说一句,为什么我的问题会被“否决”为“-1”?我会因为问问题而受到惩罚吗??? /惊奇。这是一个合法的问题,其他人可能也有同样的问题......
    • 同意,这是一个很好的问题,对我肯定有用!我也对该功能的这一方面感到非常失望。 @kichick,您有使用 Lambda 脚本保持 RDS 实例休眠的经验吗?
    • @SH10151 您可以在启动新实例时拍摄快照并删除数据库并使用 AMI。
    猜你喜欢
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    相关资源
    最近更新 更多