함수에 대한 프로비저닝된 동시성 구성하기
함수에 대한 프로비저닝된 동시성 구성하기
Lambda에서 동시성은 함수가 현재 처리 중인 진행 중 요청의 수예요. 사용 가능한 동시성 컨트롤에는 두 가지 유형이 있어요:
- 예약 동시성(Reserved concurrency) – 함수에 할당된 동시성 인스턴스의 최대 및 최소 수를 모두 설정해요. 함수에 예약 동시성이 있으면 다른 함수가 해당 동시성을 사용할 수 없어요. 예약 동시성은 가장 중요한 함수가 들어오는 요청을 처리할 충분한 동시성을 항상 확보하도록 하는 데 유용해요. 또한 데이터베이스 연결과 같은 다운스트림 리소스를 압도하지 않도록 동시성을 제한하는 데에도 사용할 수 있어요. 예약 동시성은 하한과 상한을 모두 제공해요 — 지정된 용량을 함수에 독점적으로 예약하면서도 그 한도를 넘어 확장하지 못하도록 해요. 함수에 예약 동시성을 구성해도 추가 비용은 발생하지 않아요.
- 프로비저닝된 동시성(Provisioned concurrency) – 함수에 할당된 사전 초기화된 실행 환경의 수예요. 이 실행 환경은 들어오는 함수 요청에 즉시 응답할 준비가 되어 있어요. 프로비저닝된 동시성은 함수의 콜드 스타트 대기 시간을 줄이는 데 유용하며, 함수를 두 자릿수 밀리초의 응답 시간으로 사용할 수 있도록 설계되었어요. 일반적으로 대화형 워크로드가 이 기능의 혜택을 가장 많이 받아요. 웹 및 모바일 애플리케이션처럼 사용자가 요청을 시작하는 애플리케이션이 바로 그것이며, 대기 시간에 가장 민감해요. 데이터 처리 파이프라인 같은 비동기 워크로드는 대기 시간에 덜 민감한 경우가 많아 보통 프로비저닝된 동시성이 필요하지 않아요. 프로비저닝된 동시성을 구성하면 AWS 계정에 추가 비용이 발생해요.
이 주제는 프로비저닝된 동시성을 관리·구성하는 방법을 자세히 설명해요. 이 두 동시성 컨트롤 유형의 개념적 개요는 예약 동시성 및 프로비저닝된 동시성을 참고하세요. 예약 동시성 구성에 대한 자세한 내용은 함수에 대한 예약 동시성 구성을 참고하세요.
참고 Amazon MQ 이벤트 소스 매핑에 연결된 Lambda 함수는 기본 최대 동시성이 있어요. Apache Active MQ의 경우 최대 동시 인스턴스 수는 5이고, Rabbit MQ의 경우 최대 동시 인스턴스 수는 1이에요. 함수에 대해 예약 또는 프로비저닝된 동시성을 설정해도 이러한 제한은 변경되지 않아요. Amazon MQ 사용 시 기본 최대 동시성 증가를 요청하려면 Support에 문의하세요.
주제
- 프로비저닝된 동시성 구성
- 함수에 필요한 프로비저닝된 동시성 정확히 추정
- 프로비저닝된 동시성 사용 시 함수 코드 최적화
- 환경 변수를 사용해 프로비저닝된 동시성 동작 확인·제어
- 프로비저닝된 동시성의 로깅·청구 동작 이해
- Application Auto Scaling으로 프로비저닝된 동시성 관리 자동화
본문
프로비저닝된 동시성 구성
Lambda 콘솔이나 Lambda API를 사용해서 함수에 대한 프로비저닝된 동시성 설정을 구성할 수 있어요.
함수에 대한 프로비저닝된 동시성 할당(콘솔)
-
Lambda 콘솔의 함수 페이지를 엽니다.
-
프로비저닝된 동시성을 할당할 함수를 선택합니다.
-
구성(Configuration)을 선택한 다음 동시성(Concurrency)을 선택합니다.
-
프로비저닝된 동시성 구성(Provisioned concurrency configurations)에서 구성 추가(Add configuration)를 선택합니다.
-
한정자 유형과 별칭 또는 버전을 선택합니다. 참고 어떤 함수의 $LATEST 버전에도 프로비저닝된 동시성을 사용할 수 없어요. 함수에 이벤트 소스가 있다면 해당 이벤트 소스가 올바른 함수 별칭이나 버전을 가리키는지 확인하세요. 그렇지 않으면 함수가 프로비저닝된 동시성 환경을 사용하지 않아요.
-
프로비저닝된 동시성(Provisioned concurrency)에 숫자를 입력합니다.
-
저장(Save)을 선택합니다.
계정의 미예약 계정 동시성(Unreserved account concurrency)에서 100을 뺀 만큼 구성할 수 있어요. 나머지 100개 단위의 동시성은 예약 동시성을 사용하지 않는 함수를 위한 거예요. 예를 들어 계정의 동시성 한도가 1,000이고 다른 함수에 예약 또는 프로비저닝된 동시성을 할당하지 않았다면, 단일 함수에 최대 900개의 프로비저닝된 동시성 단위를 구성할 수 있어요.
함수에 대한 프로비저닝된 동시성 구성은 다른 함수에 사용 가능한 동시성 풀에 영향을 미쳐요. 예를 들어 function-a에 100단위의 프로비저닝된 동시성을 구성하면 계정의 다른 함수는 나머지 900단위의 동시성을 공유해야 해요. function-a가 100단위를 모두 사용하지 않더라도 마찬가지예요.
동일한 함수에 예약 동시성과 프로비저닝된 동시성을 모두 할당하는 것도 가능해요. 이 경우 프로비저닝된 동시성은 예약 동시성을 초과할 수 없어요.
이 제한은 함수 버전에도 적용돼요. 특정 함수 버전에 할당할 수 있는 최대 프로비저닝된 동시성은 함수의 예약 동시성에서 다른 함수 버전의 프로비저닝된 동시성을 뺀 값이에요.
Lambda API로 프로비저닝된 동시성을 구성하려면 다음 API 작업을 사용하세요.
- PutProvisionedConcurrencyConfig
- GetProvisionedConcurrencyConfig
- ListProvisionedConcurrencyConfigs
- DeleteProvisionedConcurrencyConfig
예를 들어 AWS Command Line Interface(CLI)로 프로비저닝된 동시성을 구성하려면 put-provisioned-concurrency-config 명령을 사용하세요. 다음 명령은 my-function 함수의 BLUE 별칭에 100단위의 프로비저닝된 동시성을 할당해요:
aws lambda put-provisioned-concurrency-config --function-name my-function \
--qualifier BLUE \
--provisioned-concurrent-executions 100
다음과 같은 출력이 표시될 거예요:
{
"Requested ProvisionedConcurrentExecutions": 100,
"Allocated ProvisionedConcurrentExecutions": 0,
"Status": "IN_PROGRESS",
"LastModified": "2023-01-21T11:30:00+0000"
}
함수에 필요한 프로비저닝된 동시성 정확히 추정
CloudWatch 지표를 사용해서 활성 함수의 동시성 지표를 볼 수 있어요. 특히 ConcurrentExecutions 지표는 계정의 함수에 대한 동시 호출 수를 보여줘요.
앞의 그래프는 이 함수가 주어진 시점에 평균 5~10개의 동시 요청을 제공하고 최대 20개 요청에서 정점을 찍는 것을 시사해요. 계정에 다른 함수가 많다고 가정해 보세요. 이 함수가 애플리케이션에 중요하고 모든 호출에서 낮은 대기 시간 응답이 필요한 경우 최소 20단위의 프로비저닝된 동시성을 구성하세요.
다음 공식을 사용해서 동시성을 계산할 수도 있다는 것을 기억하세요:
Concurrency = (average requests per second) * (average request duration in seconds)
필요한 동시성을 추정하려면 평균 초당 요청 수와 평균 요청 기간(초)을 곱하세요. 평균 초당 요청 수는 Invocation 지표로, 평균 요청 기간(초)은 Duration 지표로 추정할 수 있어요.
프로비저닝된 동시성을 구성할 때 Lambda는 함수가 일반적으로 필요로 하는 동시성 양에 10% 버퍼를 추가할 것을 권장해요. 예를 들어 함수가 보통 200개의 동시 요청에서 정점을 찍는다면 프로비저닝된 동시성을 220으로 설정하세요(200개 동시 요청 + 10% = 220 프로비저닝된 동시성).
프로비저닝된 동시성 사용 시 함수 코드 최적화
프로비저닝된 동시성을 사용하고 있다면 낮은 대기 시간에 맞게 함수 코드를 재구성하는 것을 고려해 보세요. 프로비저닝된 동시성을 사용하는 함수의 경우 Lambda는 할당 시간 동안 라이브러리 로드, 클라이언트 인스턴스화 같은 초기화 코드를 실행해요. 따라서 실제 함수 호출 중 대기 시간에 영향을 주지 않도록 가능한 한 많은 초기화를 기본 함수 핸들러 밖으로 옮기는 것이 좋아요. 반대로 기본 핸들러 코드에서 라이브러리를 초기화하거나 클라이언트를 인스턴스화하면 함수가 호출될 때마다 이를 실행해야 해요(프로비저닝된 동시성을 사용하는지 여부와 무관하게 발생해요).
온디맨드 호출의 경우 함수가 콜드 스타트를 겪을 때마다 Lambda가 초기화 코드를 다시 실행해야 할 수 있어요. 이러한 함수의 경우 함수가 필요로 할 때까지 특정 기능의 초기화를 지연시키는 것을 선택할 수 있어요. 예를 들어 Lambda 핸들러의 다음 제어 흐름을 고려해 보세요:
def handler(event, context):
...
if ( some_condition ):
// Initialize CLIENT_A to perform a task
else:
// Do nothing
앞의 예시에서 개발자는 CLIENT_A를 기본 핸들러 밖에서 초기화하는 대신 if 문 안에서 초기화했어요. 이렇게 하면 Lambda가 some_condition이 충족될 때만 이 코드를 실행해요. 기본 핸들러 밖에서 CLIENT_A를 초기화하면 Lambda가 매 콜드 스타트마다 그 코드를 실행해요. 이로 인해 전체 대기 시간이 늘어날 수 있어요.
함수에 X-Ray 모니터링을 추가해서 Lambda가 확장되는 동안 콜드 스타트를 측정할 수 있어요. 프로비저닝된 동시성을 사용하는 함수는 실행 환경이 호출 전에 준비되므로 콜드 스타트 동작을 보이지 않아요. 하지만 프로비저닝된 동시성은 $LATEST 버전이 아닌 함수의 특정 버전 또는 별칭에 적용해야 해요. 콜드 스타트 동작이 계속 보인다면 프로비저닝된 동시성이 구성된 버전이나 별칭을 호출하고 있는지 확인하세요.
환경 변수를 사용해 프로비저닝된 동시성 동작 확인·제어
함수가 프로비저닝된 동시성을 모두 사용할 수 있어요. Lambda는 초과 트래픽을 처리하기 위해 온디맨드 인스턴스를 사용해요. 특정 환경에 대해 Lambda가 사용한 초기화 유형을 확인하려면 AWS_LAMBDA_INITIALIZATION_TYPE 환경 변수의 값을 확인하세요.
이 변수에는 provisioned-concurrency 또는 on-demand의 두 가지 가능한 값이 있어요. AWS_LAMBDA_INITIALIZATION_TYPE의 값은 변경할 수 없으며 환경의 수명 동안 일정하게 유지돼요. 함수 코드에서 환경 변수의 값을 확인하는 방법은 Lambda 환경 변수 검색을 참고하세요.
.NET 8 런타임을 사용한다면 함수가 프로비저닝된 동시성을 사용하지 않더라도 대기 시간을 개선하도록 AWS_LAMBDA_DOTNET_PREJIT 환경 변수를 구성할 수 있어요. .NET 런타임은 코드가 처음 호출하는 각 라이브러리에 대해 지연 컴파일·초기화를 사용해요. 그 결과 Lambda 함수의 첫 번째 호출이 후속 호출보다 더 오래 걸릴 수 있어요. 이를 완화하려면 AWS_LAMBDA_DOTNET_PREJIT에 대해 다음 세 값 중 하나를 선택할 수 있어요:
ProvisionedConcurrency: Lambda는 프로비저닝된 동시성을 사용하는 모든 환경에 대해 사전 JIT 컴파일을 수행해요. 이것이 기본값이에요.Always: Lambda는 함수가 프로비저닝된 동시성을 사용하지 않더라도 모든 환경에 대해 사전 JIT 컴파일을 수행해요.Never: Lambda는 모든 환경에 대해 사전 JIT 컴파일을 비활성화해요.
프로비저닝된 동시성의 로깅·청구 동작 이해
프로비저닝된 동시성 환경의 경우 함수의 초기화 코드는 할당 중에, 그리고 Lambda가 환경 인스턴스를 재활용함에 따라 주기적으로 실행돼요. Lambda는 환경 인스턴스가 요청을 처리하지 않더라도 초기화에 대해 청구해요. 프로비저닝된 동시성은 지속적으로 실행되며 초기화 및 호출 비용과는 별도로 청구돼요. 자세한 내용은 AWS Lambda Pricing을 참고하세요.
프로비저닝된 동시성으로 Lambda 함수를 구성하면 Lambda는 호출 요청보다 앞서 사용할 수 있도록 해당 실행 환경을 사전 초기화해요. Lambda는 환경이 초기화될 때마다 JSON 로깅 형식의 platform-initReport 로그 이벤트에 함수의 Init Duration 필드를 기록해요. 이 로그 이벤트를 보려면 JSON 로그 수준을 최소 INFO로 구성하세요. Init Duration 필드가 보고되는 플랫폼 이벤트를 소비하려면 Telemetry API를 사용할 수도 있어요.
Application Auto Scaling으로 프로비저닝된 동시성 관리 자동화
Application Auto Scaling을 사용해서 일정에 따라 또는 사용률에 따라 프로비저닝된 동시성을 관리할 수 있어요. 함수가 예측 가능한 트래픽 패턴을 받는다면 예약 확장(scheduled scaling)을 사용하세요. 함수가 특정 사용률 비율을 유지하도록 하려면 대상 추적 확장 정책(target tracking scaling policy)을 사용하세요.
참고 Application Auto Scaling을 사용해서 함수의 프로비저닝된 동시성을 관리한다면 먼저 초기 프로비저닝된 동시성 값을 구성해야 해요. 함수에 초기 프로비저닝된 동시성 값이 없으면 Application Auto Scaling이 함수 확장을 제대로 처리하지 못할 수 있어요.
예약 확장
Application Auto Scaling을 사용하면 예측 가능한 부하 변화에 따라 자신만의 확장 일정을 설정할 수 있어요. 자세한 내용과 예시는 Application Auto Scaling 사용 설명서의 Application Auto Scaling 예약 확장과 AWS Compute Blog의 반복되는 최대 사용량을 위한 AWS Lambda 프로비저닝된 동시성 예약을 참고하세요.
대상 추적
대상 추적을 사용하면 Application Auto Scaling이 확장 정책을 정의한 방식에 따라 일련의 CloudWatch 경보를 만들고 관리해요. 이러한 경보가 활성화되면 Application Auto Scaling이 프로비저닝된 동시성을 사용해 할당된 환경 수를 자동으로 조정해요. 예측 가능한 트래픽 패턴이 없는 애플리케이션에는 대상 추적을 사용하세요.
대상 추적을 사용해서 프로비저닝된 동시성을 확장하려면 RegisterScalableTarget와 PutScalingPolicy Application Auto Scaling API 작업을 사용하세요. 예를 들어 AWS Command Line Interface(CLI)를 사용한다면 다음 단계를 따르세요:
-
함수의 별칭을 확장 대상으로 등록합니다. 다음 예시는
my-function함수의 BLUE 별칭을 등록해요:aws application-autoscaling register-scalable-target --service-namespace lambda \ --resource-id function:my-function:BLUE --min-capacity 1 --max-capacity 100 \ --scalable-dimension lambda:function:ProvisionedConcurrency -
대상에 확장 정책을 적용합니다. 다음 예시는 별칭의 사용률을 70%에 가깝게 유지하도록 프로비저닝된 동시성 구성을 조정하도록 Application Auto Scaling을 구성해요. 10%~90% 사이의 값은 무엇이든 적용할 수 있어요.
aws application-autoscaling put-scaling-policy \ --service-namespace lambda \ --scalable-dimension lambda:function:ProvisionedConcurrency \ --resource-id function:my-function:BLUE \ --policy-name my-policy \ --policy-type TargetTrackingScaling \ --target-tracking-scaling-policy-configuration '{ "TargetValue": 0.7, "PredefinedMetricSpecification": { "PredefinedMetricType": "LambdaProvisionedConcurrencyUtilization" }}'
다음과 같은 출력이 표시될 거예요:
{
"PolicyARN": "arn:aws:autoscaling:us-east-2:123456789012:scalingPolicy:12266dbb-1524-xmpl-a64e-9a0a34b996fa:resource/lambda/function:my-function:BLUE:policyName/my-policy",
"Alarms": [
{
"AlarmName": "TargetTracking-function:my-function:BLUE-AlarmHigh-aed0e274-xmpl-40fe-8cba-2e78f000c0a7",
"AlarmARN": "arn:aws:cloudwatch:us-east-2:123456789012:alarm:TargetTracking-function:my-function:BLUE-AlarmHigh-aed0e274-xmpl-40fe-8cba-2e78f000c0a7"
},
{
"AlarmName": "TargetTracking-function:my-function:BLUE-AlarmLow-7e1a928e-xmpl-4d2b-8c01-782321bc6f66",
"AlarmARN": "arn:aws:cloudwatch:us-east-2:123456789012:alarm:TargetTracking-function:my-function:BLUE-AlarmLow-7e1a928e-xmpl-4d2b-8c01-782321bc6f66"
}
]
}
Application Auto Scaling은 CloudWatch에 두 개의 경보를 만들어요. 첫 번째 경보는 프로비저닝된 동시성의 사용률이 70%를 계속 초과할 때 트리거돼요. 이때 Application Auto Scaling은 사용률을 낮추기 위해 더 많은 프로비저닝된 동시성을 할당해요. 두 번째 경보는 사용률이 63%(70% 목표의 90%) 미만으로 지속될 때 트리거돼요. 이때 Application Auto Scaling은 별칭의 프로비저닝된 동시성을 줄여요.
참고
Lambda는 함수가 활성 상태이고 요청을 받을 때만 ProvisionedConcurrencyUtilization 지표를 내보내요. 비활성 기간에는 지표가 내보내지지 않으며 자동 확장 경보가 INSUFFICIENT_DATA 상태로 들어가요. 결과적으로 Application Auto Scaling이 함수의 프로비저닝된 동시성을 조정할 수 없게 돼요. 이로 인해 예상치 못한 청구가 발생할 수 있어요.
다음 예시에서 함수는 사용률에 따라 최소 및 최대 프로비저닝된 동시성 사이에서 확장돼요.
범례
- 함수 인스턴스
- 열린 요청
- 프로비저닝된 동시성
- 표준 동시성
열린 요청 수가 증가하면 Application Auto Scaling은 구성된 최대값에 도달할 때까지 큰 단위로 프로비저닝된 동시성을 증가시켜요. 그 후에는 함수가...
대상 추적 확장 정책에 대한 자세한 내용은 Application Auto Scaling 대상 추적 확장 정책을 참고하세요.
더 알아보기 (Learn more)
이 주제는 프로비저닝된 동시성의 구성·관리 방법을 설명해요. 동시성 컨트롤에 대한 개념적 개요와 예약 동시성 구성은 Lambda 개발자 안내서의 관련 주제를 참고하세요.