RDS Proxy를 사용하여 AWS Lambda에서 연결

17082 단어 RDSProxylambdaAWS
개시하다
AWS 람바다는 예측할 수 없는 요청이 왔을 때 처리 요청의 구성을 옆에서 배열하는 사례가 많다는 얘기가 종종 나온다.AWS 람다의 경우 하나의 요청 실례이기 때문에 수요가 늘어날 때 많은 실례가 일어설 수밖에 없다.이때 RDS 연결을 실례로 얻었을 때 여러 개의 데이터베이스 연결을 통해 데이터베이스 측면의 부하가 증가하는 문제가 존재한다.
이러한 문제를 해결하기 위한 선택 중 하나로 RDS Proxy라고 불리는 데이터베이스 연결을 유지하는 데 도움을 줄 수 있는 기능이 있습니다.이것은 Amazon RDS가 갖추고 있는 기능으로 여러 실례 사이에 데이터베이스 연결을 저장할 수 있다.
RDS Proxy의 이점은 다음과 같습니다.
  • 응용의 등급별 가능
  • 데이터베이스의 교차 크로스페이드와 함께 응용 프로그램 측의 교차 크로스페이드와 관련된 시간의 단축
  • AWS IAM 인증을 통해 Secret Manager에 기밀 정보를 보관하여 보안 강화
  • 이번에는 RDS Proxy를 구성하여 AWS Lambda로부터 연결하는 방법을 확인해 보겠습니다.
    Aurora MySQL
    Aurora MySQL 2.08 클러스터가 이미 실행 중인 환경을 활용합니다.Writer Instance 1대, Reader Instance 1대가 있습니다.

    Secret Manager를 통해 Secret 만들기
    RDS Proxy를 만들 때는 Secret Manager를 통해 데이터베이스에 기밀 정보를 정의해야 합니다.Secret Manager 페이지를 열고 Store a new secret 키를 누릅니다.

    User name 및 Password 지정

    객체 Database를 선택한 후 Next 키를 누릅니다.

    이름 입력 후 Next 누르기

    OFF로 전환

    Next

    Store별로 생성

    생성됨

    RDS Proxy 제작
    RDS 페이지에서 Proxies 메뉴를 선택한 후 Create proxy 를 누릅니다.

    매개변수 지정
  • RDS Proxy 이름
  • RDS Engine
  • RDS Proxy를 통해 리본 연결을 close에 연결할 때까지 기간을 지정합니다.프로그램이 검색어를 보내지 않는 idle 시간이 30분을 초과할 때close를 지정합니다.
  • 아래 설명서
  • https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/rds-proxy-setup.html#rds-proxy-creating

  • 매개변수 지정
  • RDS Proxy 통합 데이터베이스 지정
  • RDS Proxy의 플린 연결 비율 지정
  • RDS Proxy의 Reader Endpoint를 유효하게 만듭니다
  • .

    RDS Proxy에서는 Secret Manager에서 데이터베이스에 액세스할 사용자 계정을 준비해야 합니다.방금 만든 시크릿을 선택합니다.

    SecurityGroup을 지정한 후 Create proxy 키를 누릅니다.

    RDS Proxy는 Creating

    일정 시간 후 Available로

    RDS Proxy의 Endpoint 확인
    RDS Proxy의 상세 화면을 열면 RDS Proxy로서의 Endpoint를 확인할 수 있습니다.

    MySQL Celient에서 RDS Proxy 연결
    RDS Proxy가 생성되었으며 연결을 확인하려면 MySQL Client에서 연결하십시오.
    mysql -u admin -h rds-proxy-test01.proxy-chuxmuzmrpgx.ap-northeast-1.rds.amazonaws.com -p
    
    SELECT는 괜찮아요.
    mysql> SELECT * FROM sugi01.sample;
    +----+-------+
    | id | value |
    +----+-------+
    |  1 |     1 |
    |  2 |     2 |
    |  3 |     3 |
    |  4 |     4 |
    |  5 |     5 |
    |  6 |     6 |
    |  7 |     7 |
    |  8 |     8 |
    |  9 |     9 |
    | 10 |    10 |
    +----+-------+
    10 rows in set (0.01 sec)
    
    INSERT도 OK.
    mysql> INSERT INTO sugi01.sample VALUES(11, 11);
    Query OK, 1 row affected (0.02 sec)
    
    mysql> SELECT * FROM sugi01.sample;
    +----+-------+
    | id | value |
    +----+-------+
    |  1 |     1 |
    |  2 |     2 |
    |  3 |     3 |
    |  4 |     4 |
    |  5 |     5 |
    |  6 |     6 |
    |  7 |     7 |
    |  8 |     8 |
    |  9 |     9 |
    | 10 |    10 |
    | 11 |    11 |
    +----+-------+
    11 rows in set (0.01 sec)
    
    mysql>
    
    ReadOnly의 Endpoint 액세스
    mysql -u admin -h rds-proxy-test01-read-only.endpoint.proxy-chuxmuzmrpgx.ap-northeast-1.rds.amazonaws.com -p
    
    예상대로 INSERT에서 오류가 발생했습니다.
    mysql> INSERT INTO sugi01.sample VALUES(11, 11);
    ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
    mysql>
    
    Lambda Function 만들기
    다음은 Lambda Function에서 RDS Proxy로 연결하는 방법을 확인합니다.이번에는 SAM Deploy Lambda Function을 사용합니다.
    SAM Project 제작
    SAM Project 작성이번 보도의 주요 내용이 아니기 때문에 SAM의 설명은 생략하겠습니다.
    SAM Project를 제작해 헬로 월드의 움직임을 확인하고 문제가 없을 때 디플로이를 먼저 진행한다.
    sam init
    cd hello-rdsproxy
    sam build
    sam local invoke
    sam deploy --guided
    
    Docker를 사용하여 MySQL 이동
    로컬에서 Docker를 사용하여 MySQL을 이동합니다.작업을 확인하는 데 사용합니다.
    docker run \
    --name mydb \
    -itd \
    --hostname my-mysql \
    -e MYSQL_ROOT_PASSWORD=mypassword \
    -e BIND-ADDRESS=0.0.0.0 \
    -p 3306:3306 \
    public.ecr.aws/docker/library/mysql:8.0
    
    MySQL에 연결하여 샘플 데이터를 저장합니다.
    mysql -u root -h 127.0.0.1 --port=3306 -pmypassword
    
    CREATE DATABASE sugi01;
    USE sugi01;
    
    CREATE TABLE sample2(
      id INT(11) NOT NULL AUTO_INCREMENT,
      name VARCHAR(10) NOT NULL,
      PRIMARY KEY (id)
    );
    
    INSERT INTO sample2(name) VALUES ("MySQL Data");
    
    파이썬 동작 확인 in Local
    Function의 환경 변수를 정의합니다.samconfig.toml에는 다음과 같은 수치가 추가된다.
  • default.deploy.parameters: RDS Proxy에 연결하는 Endpoint, Username 등을 입력
  • default.local_invoke.parameters: Docker를 통해 활성화된 MySQL에 연결하는 정보를 입력합니다.IP 주소 Linux 시스템의 IP 주소 지정
  • [default.deploy.parameters]
    <省略>
    parameter_overrides = "MysqlHostnameKey=rds-proxy-test01.proxy-chuxmuzmrpgx.ap-northeast-1.rds.amazonaws.com MysqlPortKey=3306 MysqlUsernameKey=admin MysqlPasswordKey=secret"
    
    [default.local_invoke.parameters]
    parameter_overrides = "MysqlHostnameKey=10.0.0.163 MysqlPortKey=3306 MysqlUsernameKey=root MysqlPasswordKey=mypassword"
    
    template.yaml에는 람바다 펀션에 환경 편소를 전달하는 설정이 추가됐다.
    Parameters:
      MysqlHostnameKey:
        Type: String
        Default: default1
      MysqlPortKey:
        Type: String
        Default: default2
      MysqlUsernameKey:
        Type: String
        Default: default3
      MysqlPasswordKey:
        Type: String
        Default: default4
    
    Globals:
      Function:
        Timeout: 10
        MemorySize: 1024
        Environment:
          Variables:
            MYSQL_HOSTNAME: !Ref MysqlHostnameKey
            MYSQL_PORT: !Ref MysqlPortKey
            MYSQL_USERNAME: !Ref MysqlUsernameKey
            MYSQL_PASSWORD: !Ref MysqlPasswordKey
    
    MySQL 연결에 필요한 라이브러리 설치
    cd ~/samdir/hello-rdsproxy
    pip install mysql-connector-python
    
    requirement.txt에 다음 프로그램 라이브러리를 추가합니다.
    mysql-connector-python
    
    파이톤의 소스 코드는 이런 느낌입니다.
  • 환경 변수에서 목적지 MySQL에 대한 정보 얻기
  • sugi01.sample2 데이터를 가져오고 1줄만 출력
  • import json
    import os
    import mysql.connector as mydb
    
    
    def lambda_handler(event, context):
    
        hostname = os.environ['MYSQL_HOSTNAME']
        port = os.environ['MYSQL_PORT']
        username = os.environ['MYSQL_USERNAME']
        password = os.environ['MYSQL_PASSWORD']
    
        connection = mydb.connect(
            host=hostname,
            user=username,
            passwd=password,
            db='sugi01')
    
        cursor = connection.cursor()
    
        cursor.execute("SELECT * FROM sample2")
        selected = cursor.fetchone()
        print(selected)
    
        return {
            "statusCode": 200,
            "body": json.dumps({
                "message": selected,
                # "location": ip.text.replace("\n", "")
            }),
        }
    
    
    Build 실행
    sam build
    
    로컬 작업 확인.
    sam local invoke
    
    실행 예.로컬 MySQL에 정상적으로 연결할 수 있습니다.
    > sam local invoke
    Invoking app.lambda_handler (python3.9)
    Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.9:rapid-1.40.0-x86_64.
    
    Mounting /home/ec2-user/samdir/hello-rdsproxy/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
    START RequestId: 87a77126-7673-4228-bde8-073b187965db Version: $LATEST
    (1, 'MySQL Data')
    END RequestId: 87a77126-7673-4228-bde8-073b187965db
    REPORT RequestId: 87a77126-7673-4228-bde8-073b187965db  Init Duration: 0.06 ms  Duration: 156.75 ms     Billed Duration: 157 ms Memory Size: 1024 MB    Max Memory Used: 1024 MB
    {"statusCode": 200, "body": "{\"message\": [1, \"MySQL Data\"]}"}⏎
    
    Deploy
    저희가 람바다 펀치를 설계해 보도록 하겠습니다.
    우선 SAM의template.yaml를 편집하고 VPC 내부에서 람다의 디자인을 해야 한다.다음과 같이 Security Group 및 Subnet을 지정합니다.
    Resources:
      HelloWorldFunction:
        Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
        Properties:
          CodeUri: hello_world/
          Handler: app.lambda_handler
          Runtime: python3.9
          VpcConfig:
            SecurityGroupIds:
              - sg-00515cac8ae3971b6
            SubnetIds:
              # Subnet IDを書く
              - subnet-0d9a1ae8571fa7c30
              - subnet-0355f72e6534092bf
              - subnet-0c4b7c352a610baf4
    
    SAM deploy를 실행합니다.
    sam deploy
    
    동작 확인
    Deploy 잘 끝냈어요!다음과 같이 방문하면 데이터가 정상적으로 되돌아옵니다.
    > curl https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
    {"message": [1, "MySQL Data"]}⏎      
    
    부하를 넣어보도록 하겠습니다.
    watch -n 0.1 curl https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
    
    RDS Proxy의 양도를 살펴보면 데이터베이스 연결이 증가하는 것을 볼 수 있다.

    참조 링크
    RDS Proxy 시작 방법
    https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/rds-proxy-setup.html#rds-proxy-creating

    좋은 웹페이지 즐겨찾기