Lambda Managed Instances용 Python 런타임

Lambda Managed Instances용 Python 런타임

Lambda 런타임은 동시 요청을 처리하기 위해 여러 Python 프로세스를 사용해요. 각 동시 요청은 자체 메모리 공간과 초기화를 가진 별도 프로세스에서 실행돼요. 각 프로세스는 동시에 하나의 요청을 동기적으로 처리해요. 프로세스는 메모리를 직접 공유하지 않으므로 전역 변수, 모듈 수준 캐시, 싱글턴 객체는 동시 요청 간에 격리돼요.

출처: AWS Lambda 개발자 안내서

본문

동시성 구성

Lambda가 각 실행 환경으로 보내는 최대 동시 요청 수는 함수 구성의 PerExecutionEnvironmentMaxConcurrency 설정으로 제어돼요. 이는 선택적 설정이며 기본값은 런타임에 따라 달라져요. Python 런타임의 기본값은 vCPU당 16개의 동시 요청이며, 자체 값을 구성할 수도 있어요. 이 값은 Python 런타임이 사용하는 프로세스 수도 결정해요. Lambda는 각 실행 환경이 요청을 흡수할 수 있는 용량을 기준으로 구성된 최대값까지 동시 요청 수를 자동으로 조정해요.

중요(Important) 프로세스 기반 동시성을 사용하면 각 런타임 워커 프로세스가 자체 초기화를 수행해요. 총 메모리 사용량은 프로세스당 메모리에 동시 프로세스 수를 곱한 값과 같아요. 큰 라이브러리나 데이터 세트를 로드하고 동시성이 높다면 메모리 사용량이 커져요. 워크로드에 따라 CPU-메모리 비율을 조정하거나 더 낮은 동시성 설정을 사용해서 사용 가능한 메모리를 초과하지 않도록 해야 할 수 있어요. CloudWatch의 MemoryUtilization 지표를 사용해서 메모리 소비를 추적할 수 있어요.

다중 동시성을 위한 함수 구축

프로세스 기반 다중 동시성 모델 때문에 Python 런타임을 사용하는 Lambda Managed Instances 함수는 여러 호출에서 인메모리 리소스에 동시에 접근하지 않아요. 인메모리 동시성 안전을 위한 코딩 방식을 적용할 필요가 없어요.

공유 /tmp 디렉토리

/tmp 디렉토리는 실행 환경의 모든 동시 요청 간에 공유돼요. 같은 파일에 대한 동시 쓰기는 예를 들어 다른 프로세스가 파일을 덮어쓰는 경우 데이터 손상을 일으킬 수 있어요. 이를 해결하려면 공유 파일에 대한 파일 잠금을 구현하거나 프로세스별·요청별로 고유한 파일 이름을 사용해서 충돌을 피하세요. 사용 가능한 공간이 고갈되지 않도록 불필요한 파일도 정리하세요.

로깅

로그 인터리빙(interleaving, 서로 다른 요청의 로그 항목이 로그에 섞이는 것)은 다중 동시성 시스템에서 정상이에요.

Lambda Managed Instances를 사용하는 함수는 항상 고급 로깅 제어와 함께 도입된 구조화된 JSON 로그 형식을 사용해요. 이 형식에는 requestId가 포함되어 로그 항목을 단일 요청과 연관 지을 수 있어요. Lambda에서 Python 표준 라이브러리의 logging 모듈을 사용하면 requestId가 각 로그 항목에 자동으로 포함돼요. 자세한 내용은 Python과 함께 Lambda 고급 로깅 제어 사용을 참고하세요.

요청 컨텍스트

context.aws_request_id를 사용해서 현재 요청의 요청 ID에 접근해요.

Python 런타임에서는 _X_AMZN_TRACE_ID 환경 변수를 사용해서 Lambda Managed Instances의 X-Ray 트레이스 ID에 접근할 수 있어요. AWS SDK를 사용할 때 X-Ray 트레이스 ID는 자동으로 전파돼요.

타임아웃을 감지하려면 context.get_remaining_time_in_millis()를 사용해요. 자세한 내용은 오류 처리 및 복구를 참고하세요.

예시: 타임아웃 처리

각 작업 단위 전에 남은 시간을 확인하고 타임아웃이 발생하기 전에 처리를 중지하세요. 다음 작업 청크의 예상 기간에 따라 BUFFER_MS를 구성하세요.

BUFFER_MS = 2000  # Configure based on your next chunk of work

def handler(event, context):
    for item in event["items"]:
        if context.get_remaining_time_in_millis() < BUFFER_MS:
            return {"statusCode": 206, "body": "Timeout approaching, stopping early"}
        process_item(item)
    return {"statusCode": 200, "body": "Done"}

예시: 다운스트림 호출에 데드라인 전파

다운스트림 서비스에 호출할 때 남은 시간을 타임아웃으로 전파해서 호출 수명을 넘어서는 네트워크 호출에 매달리지 않도록 하세요. boto3 SDK는 기존 클라이언트에서 요청별 타임아웃을 지원하지 않으므로 원하는 타임아웃으로 클라이언트를 만들어야 해요. 높은 처리량 함수의 경우 초기화 시 구성된 고정 타임아웃이 요청별 클라이언트 생성보다 더 적절한지 평가하세요.

import boto3
from botocore.config import Config

def handler(event, context):
    remaining = context.get_remaining_time_in_millis() / 1000
    timeout = max(1, remaining - 0.5)
    s3 = boto3.client("s3", config=Config(read_timeout=timeout, connect_timeout=timeout))
    response = s3.get_object(Bucket="my-bucket", Key="my-key")
    return {"statusCode": 200, "body": "Done"}

초기화 및 종료

함수 초기화는 프로세스당 한 번 발생해요. 함수가 초기화 중에 로그를 생성하면 반복되는 로그 항목이 보일 수 있어요.

확장이 있는 Lambda 함수의 경우 종료 중에 실행 환경이 SIGTERM 신호를 생성해요. 이 신호는 확장이 버퍼 플러시 같은 정리 작업을 트리거하는 데 사용돼요. SIGTERM 이벤트를 구독해서 데이터베이스 연결 닫기 같은 함수 정리 작업을 트리거할 수 있어요. 실행 환경 라이프사이클에 대해 자세히 알아보려면 Lambda 실행 환경 라이프사이클 이해를 참고하세요.

종속성 버전

Lambda Managed Instances에는 다음 최소 패키지 버전이 필요해요.

  • Powertools for AWS Lambda(Python): 버전 3.23.0 이상

Powertools for AWS Lambda(Python)

Powertools for AWS Lambda(Python)는 Lambda Managed Instances와 호환되며 로깅, 트레이싱, 메트릭 등의 유틸리티를 제공해요. 자세한 내용은 Powertools for AWS Lambda(Python)를 참고하세요.

다음 단계

더 알아보기 (Learn more)

Lambda Managed Instances에 대한 자세한 내용은 Lambda Managed Instances를 참고하세요.