개발로 자기계발
728x90

Aurora PostgreSQL 16 버전 사용 중, RDS 인스턴스 재기동 시 통계 정보가 초기화되는 문제가 발생했습니다. 이는 성능 최적화와 모니터링, 트러블슈팅에 큰 영향을 미치며, AWS 지원팀 확인 결과 Aurora PostgreSQL 15 버전부터 발생하는 문제임을 확인했습니다.

이에 따라 재기동 시 통계 정보를 새로 수집하고 갱신하는 방향으로 자동화 프로세스를 설계했습니다. 이를 구현하기 위해 AWS의 EventBridge, Lambda, Aurora PostgreSQL을 활용하였습니다.

 

작업 개요

사용 AWS 서비스

  • AWS EventBridge: RDS 이벤트 감지
  • AWS Lambda: 통계 쿼리 실행
  • AWS Aurora PostgreSQL: 데이터베이스

작업 흐름

  • RDS PostgreSQL 재기동 이벤트 발생
  • AWS EventBridge가 이벤트를 수집
  • EventBridge가 Lambda를 트리거
  • Lambda에서 PostgreSQL 통계 수집 쿼리 실행

 

구현 단계

IAM 역할 생성

1. AWS 콘솔에서 IAM 역할 생성

2. AWS 서비스 선택 후 Lambda 사용 사례 선택

3. 아래 권한 정책 추가:

  • AWSLambdaBasicExecutionRole: Lambda의 CloudWatch 로그 기록
  • AmazonRDSFullAccess: RDS 연결 권한
  • (선택 사항) SecretsManagerReadWrite: 데이터베이스 자격 증명 관리 시 필요
  • (선택 사항) AmazonEventBridgeFullAccess: EventBridge 규칙 추가 및 관리 시 필요

4. 역할 이름: Lambda_RDS_Role (예시)

5. 역할 생성 완료

 

Lambda 함수 생성

1. AWS Lambda 콘솔 접속

2. 함수 생성 클릭

3. 새로 작성 선택 후 아래 값 입력:

  • 함수 이름: PostgreSQLAnalysisExecute
  • 런타임: Python 3.9 (해당 언어는 선택사항)
  • 아키텍처: x86_64
  • 실행 역할: 기존 역할 사용 > Lambda_RDS_Role 선택

4. 추가 구성:

  • 데이터베이스가 VPC 내부망에 있다면 VPC 연결 활성화

5. 함수 생성 완료

 

Lambda 코드 작성

1. 코드 소스에서 lambda_function.py 선택

2. 아래 코드를 입력:

import psycopg2
import os
import json

# 데이터베이스 연결 정보
host = # RDS 엔드포인트
username = # 데이터베이스 사용자 이름
password = # 데이터베이스 비밀번호
database = # 대상 데이터베이스 이름
port = # PostgreSQL 기본 포트

def lambda_handler(event, context):
    # Lambda 함수가 호출되었을 때 실행되는 메인 함수
    print("Event Received:", json.dumps(event))
    
    # 이벤트 상세 정보 추출
    detail = event.get('detail', {})
    event_category = detail.get('EventCategories', [])
    db_instance = detail.get('SourceIdentifier', 'Unknown DB')

    # 이벤트가 RDS 사용 가능 상태로 전환되었는지 확인
    if "availability" in event_category:
        print(f"RDS instance {db_instance} is now available. Executing post-reboot tasks...")
        perform_post_reboot_tasks(db_instance)
    else:
        # 처리 대상이 아닌 이벤트는 무시
        print(f"Event {event_category} for {db_instance} ignored.")

    return {
        'statusCode': 200,
        'body': f"Event handled for DB: {db_instance}"
    }

def perform_post_reboot_tasks(db_instance):
    # RDS 재기동 후 실행할 작업 정의
    print(f"Performing tasks for {db_instance} after reboot.")

    # PostgreSQL 데이터베이스 연결 설정
    conn = psycopg2.connect(
        host=host,
        user=username,
        password=password,
        dbname=database,
        port=port
    )

    try:
        cursor = conn.cursor()

        # PostgreSQL 통계 갱신 실행
        analyze_query = """ANALYZE;"""  # 통계 정보를 갱신하는 명령어
        cursor.execute(analyze_query)
        print("ANALYZE executed successfully.")

        # 갱신된 통계 정보를 확인하기 위한 쿼리 실행
        stats_query = """
        SELECT
            datname AS database_name,
            numbackends AS active_connections,
            xact_commit AS committed_transactions,
            xact_rollback AS rolled_back_transactions,
            blks_read AS blocks_read,
            blks_hit AS blocks_hit
        FROM pg_stat_database
        WHERE datname = %s;
        """
        cursor.execute(stats_query, (database,))
        stats = cursor.fetchall()
        print("PostgreSQL Stats after ANALYZE:", stats)
    finally:
        # 커넥션 및 커서 닫기
        cursor.close()
        conn.close()

3. 배포 클릭

 

Lambda Layer 추가

1. 특정한 디렉터리 구조를 따라야 함

  • 최상위 디렉토리에 반드시 python 폴더가 있어야 함
  • 라이브러리 파일들이 그 안에 포함되어야 함
mkdir -p python/lib/python3.9/site-packages/psycopg2

2. 로컬에서 Lambda 환경에 맞는 사전 빌드된 psycopg2 패키지 설치

  • 사전에 생성했 던 폴더 구조에 복사
  • 해당 폴더 구조로 압축
git clone https://github.com/jkehler/awslambda-psycopg2.git
cp awslambda-psycopg2/psycopg2-3.9/* python/lib/python3.9/site-packages/psycopg2
zip -r9 psycopg2-py39.zip python

3. AWS Lambda Console로 이동하여 계층 추가:

  • 이름: psycopg2-layer
  • 설명: psycopg2-3.9
  • 파일: 사전에 압축한 .zip 파일 업로드
  • 호환 런타임: Python 3.9

4. 실행할 함수로 돌아와 추가 리소스에 계층 추가

 

EventBridge 규칙 생성

1. EventBridge 콘솔 접속

  • 규칙 생성 > 이름: RDSInstanceStateChangeRule

2. 이벤트 소스 설정:

  • AWS 서비스 > Relational Database Service (RDS) 선택
  • 이벤트 유형: RDS DB Instance Event

3. 사용자 지정 패턴:

{
  "source": ["aws.rds"],
  "detail-type": ["RDS DB Instance Event"],
  "detail": {
    "EventCategories": ["reboot", "availability"],
    "SourceIdentifier": ["analysis-test-instance-1"]
  }
}

4. 대상 유형 설정

  • 대상: Lambda 함수
  • 생성했던 Lambda 선택

5. 규칙 생성 완료

 

테스트 및 결과 확인

1. 해당 RDS 인스턴스 재부팅

2. EventBridge 규칙 확인

3. EventBridge 콘솔 > 규칙 모니터링 선택

4. Lambda 로그 확인

5. CloudWatch 로그 그룹에서 로그 데이터 확인

6. 결과 예시:

Event Received: {
    "version": "0",
    "id": "319395fd-a19a-86c8-1c5b-206adcb28e76",
    "detail-type": "RDS DB Instance Event",
    "source": "aws.rds",
    "detail": {
        "EventCategories": ["availability"],
        "SourceIdentifier": "analysis-test-instance-1"
    }
}
PostgreSQL Stats after ANALYZE: [(...)]

 

참고 사항

1. Lambda 코드에 DB 정보를 직접 포함하지 말고 AWS Secrets Manager를 활용 or 환경 변수SNS 활용

2. EventBridge 대신 AWS SNS를 통한 간단한 구성 가능

3. RDS 이벤트 유형: 재부팅 이벤트는 RDS-EVENT-0006을 통해 감지 가능

728x90
SMALL
profile

개발로 자기계발

@김잠봉

틀린부분이나 조언이 있다면 언제든 환영입니다:-)