AWS 기술 블로그

Amazon Aurora를 어플리케이션 개발자가 사용하기 위한 10가지 팁 – 2부

이 글은 AWS Database Delivery Blog에 게시된 10 Amazon Aurora tips for application developers – Part 2 by Rajeev Sakhuja을 한국어 번역 및 편집하였습니다.

이 글은 Amazon Aurora를 어플리케이션 개발자가 사용하기 위한 10가지 팁 (10 Amazon Aurora tips for application developers) 게시물의 2부작 시리즈의 두번째 게시물 입니다. 1부에서는 10가지 팁중 처음 5가지 팁을 공유 했습니다.

  1. 성능을 위해 SQL 읽기와 쓰기 트랜잭션을 분리하기
  2. 빠른 복구를 위한 AWS JDBC Drivers 사용하기
  3. 프로덕션 데이터로 테스트 할 클론 생성하기
  4. 재해 복구 및 성능 향상을 위해 글로벌 데이터베이스를 사용하기
  5. Aurora Serverless v2 를 활용하여 일관된 애플리케이션 성능 확보하기

이 게시물에서는 Aurora 데이터베이스와 직접 통합하거나 이를 보완하는 AWS를 활용하여 앱의 성능, 보안 및 가용성을 향상하는 방법을 보여주는 다음 5가지 팁을 공유합니다.

전제조건

1부 게시물의 전제조건을 검토 하세요. 이 게시물의 예제는 Amazon Aurora PostgreSQL-Compatible Edition 에 대한 것 이지만, Amazon Aurora MySQL-Compatible Edition 과 함께 사용하기 위해 포팅될 수 있습니다.

Tip #6: AWS Lambda를 사용해서 다른 AWS Services와 통합하기

Amazon Aurora MySQL-Compatible Edition 과 Amazon Aurora PostgreSQL-Compatible Edition에서 AWS Lambda 함수를 호출할 수 있습니다. 이 기능은 저장된 프로시저 및 트리거와 같은 데이터베이스 개체에 노출됩니다. Amazon Aurora MySQL-Compatible Edition은 Lambda 함수를 실행하기 위한 기본함수(lambda_sync, lambda_async)를 공개 합니다.

Amazon Aurora PostgreSQL-Compatible Edition을 사용하려면 aws_lambda extension이 설치되어 있어야 합니다. 그런 다음 extension의 기능을 사용하여 Lambda 함수를 호출 할 수 있습니다. Lambda 함수에서 코드를 설정하여 모든 AWS 서비스와 통합할 수 있습니다.

Lambda 함수는 SQL 코드에서 동기식 또는 비동기식으로 호출할 수 있습니다. 동기식 호출은 애플리케이션 성능에 영향을 미칠 수 있는 Lambda 함수가 반환될 때까지 SQL 코드 실행을 차단합니다. Lambda 함수에 대한 동기식 호출을 사용하기로 결정한 경우 애플리케이션의 성능 및 시간 초과를 철저히 테스트 하세요. Lambda 함수에 대한 비동기식 호출은 차단되지는 않지만 SQL 코드는 함수 호출의 결과를 수신하지 않습니다. 동기식 호출은 RequestResponse 호출이라고 하며, 비동기식 호출은 Event 호출이라고 합니다.

이 기능은 애플리케이션이 데이터 변경에 대한 이벤트를 게시해야 할 때 유용할 수 있습니다. 예를 들어 주문 테이블에 insert가 수행되고, Amazon Simple Email Service (Amazon SES)를 통해 주문을 확인하는 이메일이 고객에게 전송되는 시나리오를 생각해 보십시오. 이를 달성하기 위해 주문 테이블에 insert 할 때 트리거가 Lambda 함수를 호출하여 이메일을 보낼 수 있습니다.

애플리케이션에 대한 Lambda 호출 기능을 고려하기로 결정한 경우 애플리케이션 성능을 철저하게 테스트하여 Lambda 함수 호출 오버헤드 (지연시간) 가 워크로드에 허용가능한 수치 인지 확인하십시오.

다음 다이어그램은 이러한 아키텍처를 보여 줍니다.

Lambda 함수가 데이터베이스 VPC 외부에 있을 수 있지만, 데이터베이스 인스턴스와 동일한 VPC에 Lambda 함수를 생성하는 것이 좋습니다. 이는 설정을 단순화하고 낮은 오버헤드로 인해 더 나은 성능을 제공합니다.

Aurora에서 Lambda 함수를 호출하려면 다음 단계를 완료하십시오.

  1. DB 인스턴스가 NAT gateway가 있는 서브넷에 생성되었는지 확인하십시오. 그렇지 않으면 Lambda에 VPC 인터페이스 엔드포인트가 필요합니다.
  2. 클러스터와 동일한 리전에서 Lambda 함수를 생성합니다. Lambda 샘플의 표준 문안 Hello를 사용 할 수 있습니다.
  3. DB 인스턴스가 Lambda 함수를 호출할 수 있도록 AWS Identity and Access Management (IAM)의 role을 설정 합니다.
    1. IAM policy를 생성하려면 bastion 호스트의 shell에서 아래 명령을 실행합니다.
      aws iam create-policy  --policy-name   aurora-dev-tips-policy --policy-document '{
          "Version": "2012-10-17",
          "Statement": [
              {
              "Sid": "AllowAccessToLambdaFunction",
              "Effect": "Allow",
              "Action": "lambda:InvokeFunction",
              "Resource": "<<REPLACE with Lambda function ARN>>"
              }
          ]
      }'
    2. AM role를 생성하려면 bastion 호스트의 shell에서 아래 명령을 실행 합니다.
      aws iam create-role  --role-name aurora-dev-tips-role --assume-role-policy-document '{
          "Version": "2012-10-17",
          "Statement": [
              {
              "Effect": "Allow",
              "Principal": {
                  "Service": "rds.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
              }
          ]
      }'
    3. IAM policy를 IAM role에 연결 합니다.
      aws iam attach-role-policy --policy-arn <<Replace with IAM Policy ARN>> --role-name aurora-dev-tips-role --region <<AWS Region>>
  4. Lambda 호출을 위해 DB 클러스터에 IAM 역할을 추가합니다(DB 클러스터 식별자를 적절하게 조정)
    aws rds add-role-to-db-cluster --db-cluster-identifier <<DB Cluster identifier>> --feature-name Lambda --role-arn  <<Replace with IAM Role ARN>> --region <<AWS Region>>
  5. PostgreSQL에서 테스트하는 코드를 사용하십시오.
    1. aws_lambda extension을 설치 합니다.
      psql => CREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE;
    2. aws_lambda.invoke(..)함수를 실행하여 Lambda 함수를 호출 합니다.
      psql => SELECT * from aws_lambda.invoke(aws_commons.create_lambda_function_arn('<<Replace with Lambda function ARN>> ', '<<AWS Region>>'), '{"body": "Hello from Postgres!"}'::json );
  6. 실험을 마치면 환경을 정리합니다.
    1. Lambda 함수를 삭제합니다.
    2. 데이터베이스에서 role을 제거합니다.
      aws rds remove-role-from-db-cluster --db-cluster-identifier aurora-pg-dev-tips --role-arn <<Replace with Role ARN>>
    3. role에서 policy를 분리합니다.
      aws iam detach-role-policy  --role-name   aurora-dev-tips-role --policy-arn  <<Replace with Policy ARN>>
    4. role을 삭제합니다.
      aws iam delete-role --role-name aurora-dev-tips-role

Tip #7: 트랙잭션 데이터에 대한 기계 학습 및 예측 실행하기

Amazon SageMaker를 사용하면 사용자 지정 기계 학습(ML) 모델을 신속하게 구축, 교육 및 배포할 수 있습니다. Amazon Comprehend는 ML 모델을 사용하여 텍스트에서 인사이트를 찾는 자연어 처리(NLP) 서비스입니다. Amazon Comprehend를 사용하여 UTF-8로 인코딩된 텍스트 문서의 콘텐츠 감정을 확인할 수 있습니다.

Aurora는 감정 분석을 위해 SageMaker ML 및 Amazon Comprehend와 직접 통합됩니다. Amazon Aurora MySQL-Compatible Edition은 저장 프로시저 및 트리거의 SQL 코드에서 이 기능을 사용하기 위한 기본 기능을 제공합니다. Amazon Aurora PostgreSQL-Compatible Edition을 사용하려면 클러스터에 aws_ml 확장을 설치해야 합니다.

트랜잭션 데이터베이스의 일부 데이터에 대해 감정 분석을 실행하려는 시나리오를 고려하십시오. 예를 들어 감정 분석을 사용하여 블로그 게시물에 대한 댓글의 감정을 확인하여 독자가 게시물을 좋아하는지 확인할 수 있습니다. 이를 수행하는 한 가지 방법은 데이터베이스에서 데이터를 내보낸 다음 데이터에서 ML 교육을 실행하여 예측을 위한 ML 모델을 만드는 것입니다. 그런 다음 애플리케이션 코드의 모델을 사용하여 감정 분석을 수행할 수 있습니다. Amazon Comprehend와 Aurora 통합을 통해 사전 훈련된 모델을 사용하여 데이터베이스의 데이터에 대한 감정 분석을 수행할 수 있습니다. 이 통합은 ML 교육으로 부터 당신을 구해주고 어떠한 ML 기술도 요구하지 않습니다.

다음 다이어그램은 이러한 아키텍처를 보여 줍니다.

테이블의 데이터에 대한 감정 분석을 시도해 봅시다. 다음 단계를 완료하십시오.

  1. NAT 게이트웨이가 있는 서브넷에서 DB 인스턴스가 생성되었는지 확인하십시오. 그렇지 않으면 Amazon Comprehend에 VPC 인터페이스 엔드포인트가 필요합니다.
  2. DB 인스턴스가 Lambda 함수를 호출할 수 있도록 IAM role을 설정합니다.
    1. Amazon Comprehend 기능을 호출하는 policy을 생성합니다.
      aws iam create-policy  --policy-name   aurora-dev-tips-comprehend-policy --policy-document '{
        "Version": "2012-10-17",
        "Statement": [
          {
            "Sid": "AllowAuroraToInvokeComprehendDetectSentiment",
            "Effect": "Allow",
            "Action": [
              "comprehend:DetectSentiment",
              "comprehend:BatchDetectSentiment"
            ],
            "Resource": "*"
          }
        ]
      }'
    2. Aurora가 수임하는 role을 생성합니다.
      aws iam create-role  --role-name aurora-dev-tips-comprehend-role --assume-role-policy-document '{
          "Version": "2012-10-17",
          "Statement": [
              {
              "Effect": "Allow",
              "Principal": {
                  "Service": "rds.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
              }
          ]
      }'
    3. IAM policy를 IAM role에 연결 합니다.
      aws iam attach-role-policy --policy-arn <<Replace with Policy ARN>> --role-name aurora-dev-tips-comprehend-role --region <<Replace with AWS Region>>
  3. Lambda 호출을 위해 DB 클러스터에 IAM 역할을 추가합니다(DB 클러스터 식별자를 적절하게 조정).
    aws rds add-role-to-db-cluster --db-cluster-identifier aurora-pg-dev-tips --feature-name Comprehend --role-arn <<Replace with Role ARN>>   --region <<Replace with Region>>
  4. PostgreSQL에서 테스트하는 코드를 사용하십시오.
    1. psql을 사용하여 테스트 테이블을 만듭니다.
      CREATE TABLE IF NOT EXISTS comments (
             comment_id SERIAL PRIMARY KEY,
             comment_text VARCHAR(255) NOT NULL);
    2. 일부 주석 데이터로 테스트 테이블을 채웁니다.
      INSERT INTO comments(comment_text) VALUES("This is very useful, thank you for writing it!");
      INSERT INTO comments (comment_text) VALUES ("I don’t like how this was implemented.");
      INSERT INTO comments (comment_text) VALUES ("Its OK.");
  5. 테이블의 데이터에 대한 감정 분석을 호출합니다; 신뢰 수준에 주의하십시오.
    SELECT comment_text, aws_comprehend.detect_sentiment(comment_text, 'en') AS sentiment  FROM comments;
  6. 실험을 마치면 환경을 정리합니다.
    1. 데이터케이스에서 role을 제거합니다.
      aws rds remove-role-from-db-cluster --db-cluster-identifier aurora-pg-dev-tips --role-arn <<Replace with Role ARN>>
    2. role에서 policy를 분리합니다.
      aws iam detach-role-policy  --role-name aurora-dev-tips-comprehend-role --policy-arn  <<Replace with Policy ARN>>
    3. role을 삭제 합니다.
      aws iam delete-role --role-name aurora-dev-tips-comprehend-role
    4. policy를 삭제 합니다.
      aws iam delete-policy --policy-arn <<Replace with Policy ARN>>

Tip #8: 성능 향상을 위해 Amazon ElastiCache 사용하기

관계형 데이터베이스를 사용하면 성능을 추가로 개선하는 데 비용이 많이 들거나 불가능할 수도 있습니다. Amazon ElastiCacheMemcachedRedis를 지원하는 관리형 캐싱 서비스입니다. ElastiCache를 관계형 데이터베이스와 NoSQL 데이터베이스의 캐싱 계층으로 사용하여 데이터의 읽기 대기시간(Latency)을 줄일 수 있습니다. Aurora 앞 단에 ElastiCache를 사용할 때 얻을 수 있는 또 다른 이점은 데이터베이스와 관련된 I/O 비용도 줄일 수 있다는 것입니다.

다음 다이어그램은 이러한 아키텍처를 보여 줍니다.

일반적으로, 읽기 대기시간(Latency)이 짧아야 하고, 복잡한 조인 또는 리소스 집약적인 계산이 있으며 캐시 계층에서 구체화될 수 있는 워크로드에는 ElastiCache를 사용하는 것이 좋습니다. ElastiCache를 사용하면 두 가지의 캐시 계층 중 선택할 수 있습니다. Memcached는 캐시 목적의 인메모리 DB이며 Redis는 인메모리 DB인 동시에 내구성도 제공합니다. 캐시 계층의 구현은 먼저 요청된 데이터가 있는지 캐시에서 확인하고 해당 데이터가 사용 가능한 경우 캐시에서 데이터를 제공합니다. 그렇지 않은 경우 데이터베이스에서 데이터를 읽고 캐시에 추가하여 동일한 데이터에 대한 후속 요청을 더 빠르게 처리합니다.

Amazon Aurora PostgreSQL 호환 에디션과 함께 ElastiCache for Redis를 사용해 보겠습니다. 이 테스트에서는 Redis의 인메모리 키-값 스토리지 기능을 사용합니다. 데이터를 더 빨리 읽기 위해 Redis 클러스터에 키-값 데이터를 추가할 수 있습니다. 각 키-값 쌍에는 키-값 쌍을 읽을 수 있는 시간 (초) 을 지정하는 TTL (Time to Live) 속성이 있습니다.

이 테스트에서 테이블을 만들고 1,000만 행으로 데이터를 채웁니다. 테이블에서 SELECT를 실행하여 3으로 나눌 수 있는 숫자를 가진 행 수를 구합니다. 결과값은 TTL값이 30초러 Redis 클러스터에 캐싱됩니다. 캐시에서 데이터가 제공(Cache hits)되는 경우 대기시간(Latency)이 크게 줄어드는 것을 확인할 수 있습니다.

  1. ElastiCache 콘솔에서 탐색창에서 Redis Clusters (Redis 클러스터)를 선택합니다.
  2. Create Redis cluster (Redis 클러스터 생성)를 선택합니다.
  3. 다중 AZ 설정을 비활성화합니다. (운영 클러스터의 경우 항상 활성화해야합니다.)
  4. 자동 장애조치(auto-failover) 설정을 비활성화 합니다. (운영 클러스터의 경우 항상 활성화해야합니다.)
  5. Node type(노드 타입)cache.t2.small을 선택합니다.
  6. Number of replicas (복제본의 수)0으로 선택합니다. (운영 클러스터의 경우, 항상 0보다 크게 설정해야합니다)
  7. Subnet group(서브넷 그룹)Create new subnet group(새 서브넷 그룹 생성)을 선택합니다.
  8. Subnet group name(이름)을 입력합니다.
  9. VPC ID는 배스천 호스트가 있는 VPC를 선택합니다.
  10. 그외 다른 설정은 기본값으로 설정하고 클러스터를 생성합니다.
    이제 테이블을 만들고 데이터를 채울 수 있습니다.
  11. 아래 psql을 사용하여 PostgreSQL 인스턴스에 연결합니다.
    => CREATE TABLE redis_test(id int);
    => INSERT INTO redis_test(id) SELECT * FROM generate_series(1,10000000) AS id;
  12. 배스천 호스트에 Python 3.x 환경을 설정합니다.
    1. Python 3 를 설치합니다. :
      sudo yum install python3 -y
    2. Redis 와 PostgreSQL 패키지를 설치합니다. :
      pip3 install redis 
      pip3 install psycopg2-binary
    3. 아래 코드를 복사하여 pgcache.py 파일을 생성합니다. :
      # Package dependencies - pip3 install psycopg2-binary redis
      # Assumes table exists & has data
      import psycopg2 
      import redis 
      import os 
      import sys 
      import timeimport json 
      # Setup the environment variables in terminal/shell 
      USER = os.getenv('PG_USER') 
      PASSWORD = os.environ.get('PG_PASSWORD') 
      DATABASE = os.environ.get('PG_DATABASE') 
      HOST = os.environ.get('PG_HOST') 
      REDIS_URL = os.environ.get('REDIS_URL')
      # Setup time to live in seconds REDIS_TTL = 30
      # Create the connection to the database 
      conn = psycopg2.connect(
          host= HOST, 
          database = DATABASE, 
          user = USER, 
          password = PASSWORD 
      )
      # Create a connection to Redis cluster 
      cache = redis.Redis.from_url(REDIS_URL)
      # Function that gets count of numbers divisible by 3
       def get_count_divisble_by_3(): 
          sql = "SELECT count(*) FROM redis_test WHERE (id % 3) = 0"
          # get the count from cache
          # Using the sql statement as the key 
          res = cache.get(sql)
          if res: print("Cache HIT")
          return res 
          # Not found in cache 
          print("Cache MISS")
          # Get the count from database table 
          cur = conn.cursor() 
          cur.execute(sql) 
          rows = cur.fetchall()
          count=json.dumps(rows)
          # Add to cache with key=sql statement & value=count 
          cache.setex(sql, REDIS_TTL, count)
          return count
      # Time the function call 
      start = time.time() 
      rows = get_count_divisble_by_3() 
      end = time.time() 
      print("Time taken in milliseconds = ",round((end - start)*1000)," ms")
      # Close connections 
      cache.close() 
      conn.close()
  13. 배스천 호스트 쉘에서 환경변수를 설정합니다.
    export PGUSER=<<Your PostgreSQL user name>>
    export PGPASSWORD=<<Your PostgreSQL password>>
    export PGDATABASE=<<Your PostgreSQL database>>
    export PGHOST=<<Cluster endpoint for your Aurora cluster>>
    export REDIS_URL=redis://<<Copy & paste Redis endpoint>>
  14. Python 코드를 실행합니다.
    python3 pgcache.py
  15. 여러번 실행하여 대기시간(Latency) 차이를 확인하십시오.
    캐시 TTL이 30초이므로 30초마다 대기시간이 큰 폭으로 늘어나는 Spike가 나타날 것입니다. 코드에서 TTL을 자유롭게 변경하고 재시도 하십시오.
  16. 실험을 끝냈을 때 아래 순서로 생성한 리소스를 정리하십시오.
    1. ElastiCache 콘솔에서 ElastiCache for Redis 클러스터를 삭제하십시오.
    2. 백업 옵션은 No 로 설정하십시오.
    3. 아래 psql을 사용하여 생성한 table을 삭제하십시오
      => DROP TABLE redis_test;

Tip #9: AWS Secrets Manager를 사용하여 DB 자격증명 (credentials) 보호 하기

애플리케이션은 자격 증명을 사용하여 데이터베이스 및 기타 리소스에 접근합니다. 일반적으로 이러한 자격 증명은 응용 프로그램에서 속성 파일, 환경 변수 또는 기타 구성 관리 시스템의 형태로 관리됩니다. 이러한 기존 방식에서는 데이터베이스 소유자가 자격 증명을 생성하고 이러한 자격 증명을 애플리케이션 개발 팀에 넘겨줘야 합니다. 이러한 메커니즘은 자격 증명이 남용될 가능성이 높고 자격 증명 (암호) 을 교체하려면 수동으로 작업해야하며 자격 증명 전달 및 애플리케이션 변경 등으로 느리게 진행된다는 단점이 있습니다.

AWS Secrets Manager는 Aurora와 통합되어 애플리케이션의 데이터베이스 자격 증명 관리와 관련된 모든 문제를 해결합니다. Secrets Manager는 인증된 보안 주체 (IAM 역할 및 사용자) 만 액세스할 수 있는 암호화된 문자열 형태로 자격 증명을 관리합니다. 자격 증명(Secrets)은 암호화되며, IAM 보안 주체는 암호 해독에 암호화 키를 사용할 권한이 있어야 합니다. 사용자가 설정한 일정에 따라 자동으로 암호를 교체하는 자동 교체 기능을 사용하여 암호를 설정, 저장할 수 있습니다. 암호 교체는 데이터베이스 및 암호에 액세스할 권한이 있는 Lambda 함수에 의해 수행되며 Lambda 함수는 자동으로 생성됩니다.

다음 다이어그램은 이러한 아키텍처를 보여 줍니다.

Secrets Manager에서 Aurora 자격 증명을 관리하는 것이 좋습니다. 이렇게 하면 데이터베이스 관점에서 애플리케이션과 데이터베이스를 더 안전하게 보호할 수 있기 때문입니다.

Secrets Manager를 사용해봅시다. 이 실습에서는 Aurora 클러스터의 암호를 생성합니다. 이 암호는 Secrets Manager에 저장되며 Python 코드를 사용하여 읽습니다.

  1. Secrets Manager 콘솔 검색창에서 Secrets (보안 암호)를 선택합니다.
  2. Store a new secret (새 보안 암호 저장)을 선택합니다.
  3. Secret type (보안 암호 유형)으로 Credentials for Amazon RDS database (Amazon RDS 데이터베이스에 대한 자격 증명)을 선택합니다.
  4. Credentials (자격 증명) 아래에 PostgreSQL DB에서 사용할 user name (사용자 이름)과 password (암호)를 입력합니다.
  5. Database (데이터베이스) 아래에서 암호를 사용할 Aurora PostgreSQL 클러스터를 선택합니다.
  6. Next (다음) 을 선택합니다.
  7. test/auroratips/postgres 로 secret(보안 암호) 이름을 설정합니다.
  8. 선택사항으로 secret (보안 암호) 교체 구성을 설정합니다.
    이 게시물에서는 PostgreSQL 사용자 암호를 교체하지 않습니다. 가장 좋은 방법은 운영환경에서는 항상 이 옵션을 사용하는 것 입니다.
  9. 배스천 호스트 쉘에서 Python 3 환경을 설정합니다. :
    pip3 install boto3
  10. 배스천 호스트 쉘에서 환경변수를 설정합니다. (아래 샘플코드를 사용하십시오.):
    export AWS_REGION=<<Set it to your region e.g., us-east-1>>
    export SECRET_NAME= test/auroratips/postgres
  11. 배스천 호스트에 아래 코드를 복사하여 getsecret.py 파일을 생성합니다.
    # Sample shows how to get the secret 
    # Python dependency - pip3 install boto3
    import boto3
    import os
    import base64
    
    SECRET_NAME = os.getenv('SECRET_NAME')
    AWS_REGION = os.getenv('AWS_REGION')
    
    def get_secret():
        secret_name = SECRET_NAME 
        region_name = AWS_REGION
        # Create a Secrets Manager client
        session = boto3.session.Session()
        client = session.client(
            service_name='secretsmanager',
            region_name=region_name
        )
        # Get the secret
        try:
            get_secret_value_response = client.get_secret_value(
                SecretId=secret_name
            )
        except ClientError as e:
                raise e
        else:
            return get_secret_value_response['SecretString']
    # call function to get the secret
    your_secret = get_secret()
    
    # Put code for connecting with the database
    print(your_secret)
  12. Secrets Manager 콘솔에서 secret(보안 암호)을 삭제합니다.
    secret(보안 암호)은 즉시 삭제되지 않습니다. 7~30일 사이에 삭제될 예정입니다. 이는 여전히 암호를 사용하고 있을 수 있는 앱의 오류를 방지하기 위한 것입니다. secret(보안 암호)의 대기 기간을 7일로 설정한 다음 삭제할 수 있습니다.

Tip #10: Amazon RDS Proxy를 사용하여 확장성, 성능 및 탄력성 확보하기

애플리케이션은 데이터베이스 연결 풀링을 활용하여 성능을 향상시키고 애플리케이션 프로세스 내에서 연결을 공유합니다. 이러한 애플리케이션을 컨테이너와 같은 Auto Scaling 컴퓨팅 인프라에 배포할 경우 부하에 따라 확장 (또는 축소) 될 수 있습니다. 이러한 확장 동작으로 데이터베이스 연결 풀이 생성되거나 삭제되면 데이터베이스 서버 리소스에 부담을 줄 수 있습니다. 각 연결 풀은 격리되어 있고 애플리케이션 인스턴스에서 공유되지 않기 때문에 데이터베이스 연결 리소스는 비효율적으로 사용될 수 있습니다. Lambda 함수로 구축된 서버리스 애플리케이션의 경우 일시적인 특성 때문에 연결 풀링을 활용할 수 없습니다.
Amazon RDS Proxy는 RDS 데이터베이스 연결 풀을 관리하는 완전 관리형 고가용성 서비스입니다. Amazon Aurora MySQL-Compatible Edition, Amazon Aurora PostgreSQL-Compatible Edition, Amazon RDS for MariaDB, Amazon RDS for MySQL, Amazon RDS for PostgreSQL, Amazon RDS for SQL Server 에서 지원됩니다.
RDS Proxy에서 관리하는 DB 연결은 여러 애플리케이션 (또는 동일한 애플리케이션의 인스턴스) 에서 공유되므로 확장성이 향상됩니다. RDS Proxy는 각 트랜잭션 후에 다시 사용할 수 있도록 풀에 대한 연결을 반환합니다. 이를 multiplexing(멀티플렉싱) 이라고 합니다. 이 메커니즘은 데이터베이스 인스턴스의 리소스 사용을 개선합니다.
RDS Proxy는 RDS 데이터베이스의 장애복구(failover)를 지속적으로 모니터링합니다. 장애 조치가 발생하면 새 DB 인스턴스로의 연결이 생성됩니다. 이러한 동작은 애플리케이션에 영향을 미치지 않으므로 장애복구(failover)로 인한 애플리케이션 복구 시간을 최대 66% 까지 줄일 수 있습니다.
RDS Proxy에 액세스하려면 애플리케이션 역할에 프록시 인스턴스에 대한 액세스 권한이 필요합니다. 따라서 데이터베이스 액세스를 위한 추가 보안 계층을 제공합니다. 애플리케이션은 코드 변경 없이 RDS Proxy를 사용할 수 있습니다. Aurora의 프록시 인스턴스는 두 개의 엔드포인트를 사용합니다. 하나는 쓰기 용이고 다른 하나는 읽기 용입니다. 클러스터에 읽기 전용 복제본이 없는 경우에는 프록시 리더 엔드포인트에 대한 연결이 실패한다는 점에 유의하세요.

다음 다이어그램은 RDS Proxy를 사용한 아키텍처 입니다.

애플리케이션, 특히 서버리스 앱에는 RDS Proxy를 고려하는 것이 좋습니다. RDS Proxy를 사용하기 위해 다음 순서로 진행해보세요.

  1. Amazon RDS 콘솔의 탐색 창에서 Proxies(프록시) 를 선택합니다.
  2. Create proxy(프록시 생성) 을 선택합니다.
  3. Engine family(엔진 패밀리)의 경우 PostgreSQL을 선택하십시오.
  4. Proxy identifier(프록시 식별자)aurora-dev-tips 를 입력합니다.
  5. Database(데이터베이스)에서 연결할 Aurora 데이터베이스를 선택합니다.
  6. Secrets Manager secret(Secret Manager 보안 암호) 의 경우 이전에 생성한 암호를 선택합니다.
  7. Subnets(서브넷)의 경우 데이터베이스 서브넷 그룹과 동일한 서브넷을 선택합니다.
  8. VPC security group(VPC 보안 그룹)의 경우 DB 인스턴스에 연결할 수 있는 보안 그룹을 선택합니다.
  9. RDS Proxy 인스턴스가 생성된 후 프록시 세부 정보 페이지에서 Endpoint (엔드포인트)를 복사합니다.
  10. 프록시 엔드포인트를 사용하여 Aurora DB 인스턴스에 연결하려면 배스천 호스트에 SSH를 연결합니다.
    psql  -U <<Provide PostgreSQL user name>>  -h  <<Paste proxy endpoint>>

    암호를 입력하라는 메시지가 표시됩니다. Secrets Manager의 자동 교체 구성 없이 암호를 설정하여 사용자의 원래 암호를 입력할 수 있습니다. 애플리케이션 코드에서는 항상 Secrets Manager로부터 암호를 가져옵니다. psql에서 DB 인스턴스에 연결한 후에는 SQL 쿼리를 실행할 수 있어야 합니다. 프록시 리더 엔드포인트를 사용하려면 클러스터에 하나 이상의 읽기 전용 복제본이 있어야 한다는 점에 유의하세요.

  11. 작업을 마치면 다음 단계에 따라 환경을 정리하실 수 있습니다.
    • Amazon RDS 콘솔에서 RDS Proxy 인스턴스를 삭제합니다.
    • Secrets Manager 콘솔에서 암호를 삭제합니다.

앞서 언급한 것처럼 암호는 즉시 삭제되지 않으며 7~30일 사이에 삭제되게 됩니다. 이 부분은 아직 암호를 사용하고 있을 수 있는 관련 Application의 오류를 방지하기 위한 것입니다. 암호 삭제 대기 기간을 7일로 설정한 다음 삭제를 선택합니다.

환경 정리하기

클러스터가 더 이상 필요하지 않을 경우 Aurora DB 클러스터를 삭제하고 리소스를 정리해야 합니다.

결론

2부로 구성된 시리즈의 두 번째 게시물에서는 AWS 서비스를 Aurora와 함께 사용하기 위한 팁을 다루었습니다. Lambda와 통합된 Aurora 를 사용하면 SQL 코드에서 Lambda 함수를 호출할 수 있으므로 기능이 풍부한 애플리케이션을 구축할 수 있습니다. 또한 Aurora는 SageMaker 및 NLP용 Amazon Comprehend와 통합되므로 SQL 코드에서 직접 학습된 ML 모델을 호출할 수 있습니다. ElastiCache를 사용하면 애플리케이션의 쿼리 성능을 높이고 데이터베이스 인스턴스의 리소스 부담을 줄일 수 있습니다. RDS Proxy는 multiplexing된 데이터베이스 연결 풀을 관리합니다. 코드를 변경하지 않고도 앱에서 RDS Proxy를 사용할 수 있으므로 성능 향상, 장애 조치 시 복구 속도 향상, 앱 보안 상태 개선 등이 가능합니다.
고객 여러분의 Application을 검토해 보시고 Aurora 데이터베이스 클러스터를 활용하여 AWS의 여러 서비스를 통합하여 잘 사용하실 수 있는 방안을 확인해보세요.

Suhyun Kim

Suhyun Kim

김수현 테크니컬 어카운트 매니저는 다양한 인프라 및 컨테이너 환경에 대한 경험을 바탕으로 엔터프라이즈 서포트 고객이 AWS 모범 사례를 기반으로 클라우드 환경을 효율적이고 안정적으로 운영할 수 있도록 도움을 드리고 있습니다.

Mirinae Lee

Mirinae Lee

이미리내 테크니컬 어카운트 매니저는 엔터프라이즈 서포트 고객이 AWS 모범 사례를 기반으로 클라우드 환경을 안정적으로 운영하고 비즈니스 목표를 달성할 수 있도록 도움 드리고 있습니다.

Yujin Cho

Yujin Cho

조유진 테크니컬 어카운트 매니저는 다양한 데이터베이스의 운영과 데이터 분석 경험을 바탕으로 고객이 데이터 기반의 비즈니스 목표를 달성할 수 있도록 고객과 함께 효율적인 아키텍처와 안정적인 운영 환경을 구성하기 위해 노력하고 있습니다.