Lambda 함수 확장(스케일링) 이해하기
Lambda 함수 확장(스케일링) 이해하기
동시성(concurrency)은 AWS Lambda 함수가 동시에 처리하는 진행 중(in-flight) 요청 수를 말해요. 각 동시 요청에 대해 Lambda는 실행 환경의 인스턴스를 별도로 하나 프로비저닝합니다. 함수가 더 많은 요청을 받으면 계정의 동시성 한도에 도달할 때까지 Lambda가 실행 환경 수의 확장을 자동으로 처리합니다. 기본적으로 Lambda는 AWS 리전의 모든 함수에 걸쳐 총 1,000개의 동시 실행 한도를 계정에 제공합니다. 계정의 특정 요구를 지원하기 위해 쿼터 증가를 요청하고 함수 수준 동시성 제어를 구성해 중요한 함수가 스로틀링을 겪지 않도록 할 수 있어요.
본문
이 주제는 Lambda의 동시성 개념과 함수 확장을 설명합니다. 이 주제를 마치면 동시성을 계산하고, 예약(reserved) 동시성과 프로비저닝(provisioned) 동시성이라는 두 가지 주요 동시성 제어 옵션을 시각화하고, 적절한 동시성 제어 설정을 추정하며, 추가 최적화를 위한 지표를 확인할 수 있게 됩니다.
Sections
- 동시성 이해 및 시각화
- 함수의 동시성 계산하기
- 예약 동시성과 프로비저닝 동시성 이해하기
- 동시성과 초당 요청 수 이해하기
- 동시성 쿼터
- 함수의 예약 동시성 구성하기
- 함수의 프로비저닝 동시성 구성하기
- Lambda 확장 동작
- 동시성 모니터링
동시성 이해 및 시각화
Lambda는 안전하고 격리된 실행 환경에서 함수를 호출합니다. 요청을 처리하려면 Lambda는 먼저 실행 환경을 초기화해야 합니다(Init 단계), 그런 다음 이를 사용해 함수를 호출합니다(Invoke 단계):
참고
실제 Init 및 Invoke 지속 시간은 선택한 런타임과 Lambda 함수 코드 같은 여러 요인에 따라 달라질 수 있어요. 이전 다이어그램은 Init와 Invoke 단계 지속 시간의 정확한 비율을 나타내려는 것이 아닙니다.
이전 다이어그램은 사각형으로 단일 실행 환경을 나타냅니다. 함수가 첫 번째 요청(1로 표시된 노란색 원)을 받으면 Lambda는 새 실행 환경을 만들고 Init 단계 동안 기본 핸들러 밖의 코드를 실행합니다. 그런 다음 Lambda는 Invoke 단계 동안 함수의 기본 핸들러 코드를 실행합니다. 이 전체 과정 동안 이 실행 환경은 바쁘며 다른 요청을 처리할 수 없습니다.
Lambda가 첫 번째 요청 처리를 마치면 이 실행 환경은 같은 함수의 추가 요청을 처리할 수 있습니다. 이후 요청에서는 Lambda가 환경을 다시 초기화할 필요가 없습니다.
이전 다이어그램에서 Lambda는 실행 환경을 재사용해 두 번째 요청(2로 표시된 노란색 원)을 처리합니다.
지금까지 실행 환경의 단일 인스턴스(즉, 동시성 1)에만 집중했어요. 실제로 Lambda는 들어오는 모든 요청을 처리하기 위해 여러 실행 환경 인스턴스를 병렬로 프로비저닝해야 할 수 있습니다. 함수가 새 요청을 받으면 두 가지 중 하나가 발생합니다:
- 사전 초기화된 실행 환경 인스턴스가 사용 가능하면 Lambda가 그 인스턴스를 사용해 요청을 처리합니다.
- 그렇지 않으면 Lambda가 새 실행 환경 인스턴스를 만들어 요청을 처리합니다.
예를 들어 함수가 10개의 요청을 받을 때 어떤 일이 발생하는지 살펴보겠습니다:
이전 다이어그램에서 각 가로 평면은 단일 실행 환경 인스턴스(A부터 F까지 라벨)를 나타냅니다. Lambda가 각 요청을 처리하는 방식은 다음과 같습니다:
| 요청 | Lambda의 결정 | 설명 |
|---|---|---|
| 1 | 새 환경 A 프로비저닝 | 첫 번째 요청이며, 사용 가능한 실행 환경 인스턴스가 없습니다. |
| 2 | 새 환경 B 프로비저닝 | 기존 실행 환경 인스턴스 A가 바쁩니다. |
| 3 | 새 환경 C 프로비저닝 | 기존 실행 환경 인스턴스 A와 B가 모두 바쁩니다. |
| 4 | 새 환경 D 프로비저닝 | 기존 실행 환경 인스턴스 A, B, C가 모두 바쁩니다. |
| 5 | 새 환경 E 프로비저닝 | 기존 실행 환경 인스턴스 A, B, C, D가 모두 바쁩니다. |
| 6 | 환경 A 재사용 | 실행 환경 인스턴스 A가 요청 1 처리를 마치고 이제 사용 가능합니다. |
| 7 | 환경 B 재사용 | 실행 환경 인스턴스 B가 요청 2 처리를 마치고 이제 사용 가능합니다. |
| 8 | 환경 C 재사용 | 실행 환경 인스턴스 C가 요청 3 처리를 마치고 이제 사용 가능합니다. |
| 9 | 새 환경 F 프로비저닝 | 기존 실행 환경 인스턴스 A, B, C, D, E가 모두 바쁩니다. |
| 10 | 환경 D 재사용 | 실행 환경 인스턴스 D가 요청 4 처리를 마치고 이제 사용 가능합니다. |
함수가 더 많은 동시 요청을 받으면 Lambda는 그에 응답해 실행 환경 인스턴스 수를 확장합니다. 다음 애니메이션은 시간에 따른 동시 요청 수를 추적합니다.
이전 애니메이션을 시간의 여섯 지점에서 멈추면 다음과 같은 다이어그램을 얻습니다:
이전 다이어그램에서 임의의 시점에 수직선을 그려 이 선과 교차하는 환경 수를 셀 수 있어요. 이것이 그 시점의 동시 요청 수입니다. 예를 들어 시간 t1에는 세 개의 활성 환경이 세 개의 동시 요청을 처리하고 있습니다. 이 시뮬레이션에서 동시 요청의 최대 수는 시간 t4에 발생하며, 여섯 개의 활성 환경이 여섯 개의 동시 요청을 처리합니다.
요약하면 함수의 동시성은 같은 시간에 처리 중인 동시 요청 수입니다. 함수 동시성의 증가에 응답해 Lambda는 요청 수요를 충족하도록 더 많은 실행 환경 인스턴스를 프로비저닝합니다.
함수의 동시성 계산하기
일반적으로 시스템의 동시성은 둘 이상의 작업을 동시에 처리하는 능력입니다. Lambda에서 동시성은 함수가 같은 시간에 처리하는 진행 중인 요청 수입니다. Lambda 함수의 동시성을 측정하는 빠르고 실용적인 방법은 다음 공식을 사용하는 것입니다:
Concurrency = (평균 초당 요청 수) * (평균 요청 지속 시간(초))
동시성은 초당 요청 수와 다릅니다. 예를 들어 함수가 평균적으로 초당 100개의 요청을 받는다고 가정해 보세요. 평균 요청 지속 시간이 1초라면 동시성도 100입니다:
Concurrency = (100 requests/second) * (1 second/request) = 100
그러나 평균 요청 지속 시간이 500ms라면 동시성은 50입니다:
Concurrency = (100 requests/second) * (0.5 second/request) = 50
동시성 50이 실제로 무엇을 의미할까요? 평균 요청 지속 시간이 500ms라면 함수의 인스턴스 하나가 초당 두 개의 요청을 처리할 수 있다고 생각할 수 있어요. 그러면 초당 100개의 요청 부하를 처리하려면 함수 인스턴스가 50개 필요합니다. 동시성 50은 Lambda가 스로틀링 없이 이 워크로드를 효율적으로 처리하려면 실행 환경 인스턴스를 50개 프로비저닝해야 한다는 뜻입니다. 이는 다음과 같이 방정식으로 표현할 수 있어요:
Concurrency = (100 requests/second) / (2 requests/second) = 50
함수가 요청 수의 두 배를 받지만(초당 200개 요청), 각 요청을 처리하는 데 절반의 시간만 필요하다면(250ms), 동시성은 여전히 50입니다:
Concurrency = (200 requests/second) * (0.25 second/request) = 50
예약 동시성과 프로비저닝 동시성 이해하기
기본적으로 계정은 리전의 모든 함수에 걸쳐 1,000개의 동시 실행 한도를 가집니다. 함수는 이 1,000의 동시성 풀을 주문형(on-demand)으로 공유합니다. 사용 가능한 동시성이 바닥나면 함수는 스로틀링(즉, 요청을 버리기 시작함)을 겪습니다.
일부 함수는 다른 함수보다 더 중요할 수 있어요. 결과적으로 중요 함수가 필요한 동시성을 얻도록 동시성 설정을 구성하고 싶을 것입니다. 사용 가능한 동시성 제어에는 예약 동시성과 프로비저닝 동시성 두 가지 유형이 있습니다.
- 예약 동시성(reserved concurrency) 은 함수에 계정 동시성의 일부를 예약하기 위해 동시 인스턴스의 최대 및 최소 수를 설정하는 데 사용합니다. 다른 함수가 사용 가능한 모든 비예약 동시성을 차지하지 않도록 하려면 이 기능이 유용해요. 함수에 예약 동시성이 있으면 다른 함수는 그 동시성을 사용할 수 없습니다.
- 프로비저닝 동시성(provisioned concurrency) 은 함수에 대해 사전 초기화된 환경 인스턴스 수를 설정하는 데 사용합니다. 이는 콜드 스타트 지연 시간을 줄이는 데 유용합니다.
예약 동시성
특정 양의 동시성이 항상 함수에 사용 가능하다는 것을 보장하고 싶다면 예약 동시성을 사용하세요.
예약 동시성은 함수에 할당하려는 동시 인스턴스의 최대 및 최소 수를 설정합니다. 함수에 예약 동시성을 전용하면 다른 함수는 그 동시성을 사용할 수 없습니다. 즉, 예약 동시성을 설정하면 다른 함수에 사용 가능한 동시성 풀에 영향을 줄 수 있어요. 예약 동시성이 없는 함수는 남은 비예약 동시성 풀을 공유합니다.
예약 동시성을 구성하는 것은 계정의 전체 동시성 한도에 포함됩니다. 함수에 예약 동시성을 구성하는 데는 요금이 부과되지 않습니다.
예약 동시성을 더 잘 이해하려면 다음 다이어그램을 고려하세요:
이 다이어그램에서 이 리전의 모든 함수에 대한 계정 동시성 한도는 기본 한도인 1,000입니다. 일반적으로 높은 호출 볼륨을 기대하는 두 개의 중요 함수 function-blue와 function-orange가 있다고 가정해 보세요. function-blue에 400유닛, function-orange에 400유닛의 예약 동시성을 주기로 결정합니다. 이 예시에서 계정의 다른 모든 함수는 나머지 200유닛의 비예약 동시성을 공유해야 합니다.
다이어그램에는 다섯 개의 관심 지점이 있습니다:
t1에서function-orange와function-blue모두 요청을 받기 시작합니다. 각 함수는 할당된 예약 동시성 유닛의 일부를 사용하기 시작합니다.t2에서function-orange와function-blue가 꾸준히 더 많은 요청을 받습니다. 동시에 다른 Lambda 함수를 배포해 요청을 받기 시작합니다. 이 다른 함수에는 예약 동시성을 할당하지 않았습니다. 이들은 나머지 200유닛의 비예약 동시성을 사용하기 시작합니다.t3에서function-orange가 최대 동시성 400에 도달합니다. 계정의 다른 곳에 미사용 동시성이 있지만function-orange는 그것에 접근할 수 없습니다. 빨간 선은function-orange가 스로틀링을 겪고 있으며 Lambda가 요청을 버릴 수 있음을 나타냅니다.t4에서function-orange가 더 적은 요청을 받기 시작해 더 이상 스로틀링하지 않습니다. 그러나 다른 함수들은 트래픽 급증을 겪으며 스로틀링하기 시작합니다. 계정의 다른 곳에 미사용 동시성이 있지만 이 다른 함수들은 그것에 접근할 수 없습니다. 빨간 선은 다른 함수들이 스로틀링을 겪고 있음을 나타냅니다.t5에서 다른 함수들이 더 적은 요청을 받기 시작해 더 이상 스로틀링하지 않습니다.
이 예시에서 동시성을 예약하면 다음과 같은 효과가 있다는 점을 주목하세요:
- 함수가 계정의 다른 함수와 독립적으로 확장할 수 있습니다. 같은 리전에서 예약 동시성이 없는 계정의 모든 함수는 비예약 동시성 풀을 공유합니다. 예약 동시성이 없으면 다른 함수가 사용 가능한 모든 동시성을 잠재적으로 사용할 수 있습니다. 이는 필요할 때 중요 함수가 확장되는 것을 방지합니다.
- 함수가 통제를 벗어나 확장할 수 없습니다. 예약 동시성은 함수의 최대 및 최소 동시성을 제한합니다. 이는 함수가 다른 함수를 위해 예약된 동시성이나 비예약 풀의 동시성을 사용할 수 없다는 뜻입니다. 또한 예약 동시성은 하한과 상한 모두로 작동합니다 — 지정된 용량을 함수에 전용으로 예약하면서 그 한도를 넘어 확장되는 것도 방지합니다. 함수가 계정의 사용 가능한 모든 동시성을 사용하거나 다운스트림 리소스를 과부하시키는 것을 방지하기 위해 동시성을 예약할 수 있어요.
- 계정의 사용 가능한 동시성을 모두 사용하지 못할 수도 있습니다. 동시성 예약은 계정 동시성 한도에 포함되지만, 이는 다른 함수가 그 예약된 동시성 덩어리를 사용할 수 없다는 뜻이기도 합니다. 함수가 예약한 동시성을 모두 사용하지 않으면 그 동시성을 사실상 낭비하는 것입니다. 낭비된 동시성이 계정의 다른 함수에 도움이 될 수 없다면 문제가 되지 않습니다.
함수의 예약 동시성 설정을 관리하는 방법은 함수의 예약 동시성 구성하기를 참고하세요.
프로비저닝 동시성
예약 동시성은 Lambda 함수를 위해 예약된 실행 환경의 최대 수를 정의하는 데 사용합니다. 그러나 이러한 환경 중 어느 것도 사전 초기화되어 있지 않습니다. 결과적으로 Lambda가 새 환경을 초기화한 다음 함수를 호출하는 데 사용해야 하기 때문에 함수 호출이 더 오래 걸릴 수 있어요. Lambda가 호출을 수행하기 위해 새 환경을 초기화해야 할 때 이를 콜드 스타트라고 합니다. 콜드 스타트를 완화하려면 프로비저닝 동시성을 사용할 수 있습니다.
프로비저닝 동시성은 함수에 할당하려는 사전 초기화된 실행 환경 수입니다. 함수에 프로비저닝 동시성을 설정하면 Lambda가 그 수만큼 실행 환경을 초기화해 함수 요청에 즉시 응답할 준비를 합니다.
참고
프로비저닝 동시성을 사용하면 계정에 추가 요금이 부과됩니다. Java 11 또는 Java 17 런타임으로 작업 중이라면 Lambda SnapStart를 사용해 추가 비용 없이 콜드 스타트 문제를 완화할 수도 있어요. SnapStart는 실행 환경의 캐시된 스냅샷을 사용해 시작 성능을 크게 개선합니다. 같은 함수 버전에서 SnapStart와 프로비저닝 동시성을 동시에 사용할 수는 없습니다. SnapStart 기능, 제한, 지원 리전에 대한 자세한 내용은 Lambda SnapStart로 시작 성능 개선하기를 참고하세요.
프로비저닝 동시성을 사용할 때도 Lambda는 백그라운드에서 실행 환경을 재활용합니다. 예를 들어 호출 실패 후 이렇게 될 수 있어요. 그러나 언제라도 Lambda는 항상 사전 초기화된 환경 수가 함수의 프로비저닝 동시성 설정 값과 같도록 보장합니다. 중요하게도 프로비저닝 동시성을 사용해도 Lambda가 실행 환경을 재설정해야 하면 여전히 콜드 스타트 지연을 겪을 수 있습니다.
대조적으로 예약 동시성을 사용할 때 Lambda는 비활성 기간 후에 환경을 완전히 종료할 수 있습니다. 다음 다이어그램은 예약 동시성과 프로비저닝 동시성으로 함수를 구성할 때 단일 실행 환경의 수명 주기를 비교해 이를 보여줍니다.
다이어그램에는 네 개의 관심 지점이 있습니다:
| 시점 | 예약 동시성 | 프로비저닝 동시성 |
|---|---|---|
| t1 | 아무 일도 일어나지 않습니다. | Lambda가 실행 환경 인스턴스를 사전 초기화합니다. |
| t2 | 요청 1이 들어옵니다. Lambda가 새 실행 환경 인스턴스를 초기화해야 합니다. | 요청 1이 들어옵니다. Lambda가 사전 초기화된 환경 인스턴스를 사용합니다. |
| t3 | 일정 비활성 후 Lambda가 활성 환경 인스턴스를 종료합니다. | 아무 일도 일어나지 않습니다. |
| t4 | 요청 2가 들어옵니다. Lambda가 새 실행 환경 인스턴스를 초기화해야 합니다. | 요청 2가 들어옵니다. Lambda가 사전 초기화된 환경 인스턴스를 사용합니다. |
프로비저닝 동시성을 더 잘 이해하려면 다음 다이어그램을 고려하세요:
이 다이어그램에서 계정 동시성 한도는 1,000입니다. function-orange에 400유닛의 프로비저닝 동시성을 주기로 결정합니다. function-orange를 포함한 계정의 모든 함수는 나머지 600유닛의 비예약 동시성을 사용할 수 있습니다.
다이어그램에는 다섯 개의 관심 지점이 있습니다:
t1에서function-orange가 요청을 받기 시작합니다. Lambda가 400개의 실행 환경 인스턴스를 사전 초기화했으므로function-orange는 즉시 호출할 준비가 됩니다.t2에서function-orange가 400개의 동시 요청에 도달합니다. 결과적으로function-orange는 프로비저닝 동시성을 소진합니다. 그러나 아직 비예약 동시성이 사용 가능하므로 Lambda는 이를 사용해function-orange에 대한 추가 요청을 처리할 수 있습니다(스로틀링 없음). Lambda는 이 요청들을 처리하기 위해 새 인스턴스를 만들어야 하며, 함수는 콜드 스타트 지연을 겪을 수 있습니다.t3에서function-orange는 짧은 트래픽 급증 후 400개의 동시 요청으로 돌아옵니다. Lambda는 콜드 스타트 지연 없이 모든 요청을 다시 처리할 수 있습니다.t4에서 계정의 함수들이 트래픽 버스트를 겪습니다. 이 버스트는function-orange또는 계정의 다른 함수에서 올 수 있습니다. Lambda는 비예약 동시성을 사용해 이 요청들을 처리합니다.t5에서 계정의 함수들이 최대 동시성 한도 1,000에 도달해 스로틀링을 겪습니다.
이전 예시는 프로비저닝 동시성만 고려했습니다. 실제로 함수에 프로비저닝 동시성과 예약 동시성을 모두 설정할 수 있어요. 주중에는 일관된 호출 부하를 처리하지만 주말에는 트래픽 급증을 정기적으로 보는 함수가 있다면 이렇게 할 수 있습니다. 이 경우 프로비저닝 동시성으로 주중 요청을 처리할 기준 환경 수를 설정하고, 예약 동시성으로 주말 급증을 처리할 수 있어요. 다음 다이어그램을 고려하세요:
이 다이어그램에서 function-orange에 200유닛의 프로비저닝 동시성과 400유닛의 예약 동시성을 구성한다고 가정해 보세요. 예약 동시성을 구성했으므로 function-orange는 600유닛의 비예약 동시성을 전혀 사용할 수 없습니다.
이 다이어그램에는 다섯 개의 관심 지점이 있습니다:
t1에서function-orange가 요청을 받기 시작합니다. Lambda가 200개의 실행 환경 인스턴스를 사전 초기화했으므로function-orange는 즉시 호출할 준비가 됩니다.t2에서function-orange가 모든 프로비저닝 동시성을 사용합니다.function-orange는 예약 동시성을 사용해 계속 요청을 처리할 수 있지만, 이 요청들은 콜드 스타트 지연을 겪을 수 있습니다.t3에서function-orange가 400개의 동시 요청에 도달합니다. 결과적으로function-orange는 모든 예약 동시성을 사용합니다.function-orange가 비예약 동시성을 사용할 수 없으므로 요청이 스로틀링되기 시작합니다.t4에서function-orange가 더 적은 요청을 받기 시작해 더 이상 스로틀링하지 않습니다.t5에서function-orange가 200개의 동시 요청으로 내려가므로 모든 요청이 다시 프로비저닝 동시성을 사용할 수 있게 됩니다(즉, 콜드 스타트 지연 없음).
예약 동시성과 프로비저닝 동시성 모두 계정 동시성 한도와 리전별 쿼터에 포함됩니다. 즉, 예약 및 프로비저닝 동시성을 할당하면 다른 함수에 사용 가능한 동시성 풀에 영향을 줄 수 있습니다. 프로비저닝 동시성을 구성하면 AWS 계정에 요금이 부과됩니다.
참고
함수 버전과 별칭의 프로비저닝 동시성 합계가 함수의 예약 동시성과 같다면, 모든 호출이 프로비저닝 동시성에서 실행됩니다. 이 구성은 또한 함수의 미게시 버전($LATEST)을 스로틀링하는 효과가 있어, 해당 버전이 실행되는 것을 방지합니다. 함수에 예약 동시성보다 많은 프로비저닝 동시성을 할당할 수 없습니다.
함수의 프로비저닝 동시성 설정을 관리하려면 함수의 프로비저닝 동시성 구성하기를 참고하세요. 일정이나 애플리케이션 사용률을 기반으로 프로비저닝 동시성 확장을 자동화하려면 Application Auto Scaling으로 프로비저닝 동시성 관리를 자동화하기를 참고하세요.
Lambda가 프로비저닝 동시성을 할당하는 방법
프로비저닝 동시성은 구성 직후에 바로 온라인 상태가 되지 않습니다. Lambda는 준비를 마친 후 1~2분 뒤에 프로비저닝 동시성 할당을 시작합니다. 각 함수에 대해 Lambda는 AWS 리전과 관계없이 매분 최대 6,000개의 실행 환경을 프로비저닝할 수 있습니다. 이는 함수의 동시성 확장률과 정확히 동일합니다.
프로비저닝 동시성 할당을 요청할 때 Lambda가 해당 환경 할당을 완전히 마칠 때까지는 그 환경 중 어느 것에도 접근할 수 없습니다. 예를 들어 프로비저닝 동시성 5,000을 요청하면 Lambda가 5,000개의 실행 환경 할당을 완전히 마칠 때까지 어떤 요청도 프로비저닝 동시성을 사용할 수 없습니다.
예약 동시성과 프로비저닝 동시성 비교
다음 표는 예약 동시성과 프로비저닝 동시성을 요약하고 비교합니다.
| 기준 | 예약 동시성 | 프로비저닝 동시성 |
|---|---|---|
| 정의 | 함수의 실행 환경 인스턴스 최대 수 | 함수의 사전 프로비저닝된 실행 환경 인스턴스 일정 수 |
| 프로비저닝 동작 | Lambda가 주문형으로 새 인스턴스를 프로비저닝 | Lambda가 인스턴스를 사전 프로비저닝(즉, 함수가 요청을 받기 전에) |
| 콜드 스타트 동작 | Lambda가 주문형으로 새 인스턴스를 만들어야 하므로 콜드 스타트 지연 가능 | Lambda가 주문형으로 인스턴스를 만들 필요가 없으므로 콜드 스타트 지연 불가능 |
| 스로틀링 동작 | 예약 동시성 한도에 도달하면 함수가 스로틀링 | 예약 동시성이 없으면: 프로비저닝 동시성 한도 도달 시 함수가 비예약 동시성 사용 / 예약 동시성이 있으면: 예약 동시성 한도 도달 시 함수가 스로틀링 |
| 설정하지 않을 때의 기본 동작 | 함수가 계정의 사용 가능한 비예약 동시성 사용 | Lambda가 인스턴스를 사전 프로비저닝하지 않음. 대신 예약 동시성이 없으면: 함수가 계정의 사용 가능한 비예약 동시성 사용 / 예약 동시성이 있으면: 함수가 예약 동시성 사용 |
| 요금 | 추가 요금 없음 | 추가 요금 부과 |
동시성과 초당 요청 수 이해하기
앞 섹션에서 언급했듯이 동시성은 초당 요청 수와 다릅니다. 이는 평균 요청 지속 시간이 100ms 미만인 함수에서 작업할 때 특히 중요한 구분입니다.
계정의 모든 함수에 걸쳐 Lambda는 계정 동시성의 10배와 같은 초당 요청 수 한도를 적용합니다. 예를 들어 기본 계정 동시성 한도가 1,000이므로 계정의 함수는 초당 최대 10,000개의 요청을 처리할 수 있습니다.
예를 들어 평균 요청 지속 시간이 50ms인 함수를 고려해 보세요. 초당 20,000개의 요청에서 이 함수의 동시성은 다음과 같습니다:
Concurrency = (20,000 requests/second) * (0.05 second/request) = 1,000
이 결과에 기반해 계정 동시성 한도 1,000이 이 부하를 처리하기에 충분할 것이라고 기대할 수도 있어요. 그러나 초당 10,000개의 요청 한도 때문에 함수는 총 20,000개 요청 중 초당 10,000개의 요청만 처리할 수 있습니다. 이 함수는 스로틀링을 겪습니다.
여기서 배울 점은 함수의 동시성 설정을 구성할 때 동시성과 초당 요청 수를 모두 고려해야 한다는 것입니다. 이 경우 계정 동시성 한도 증가를 요청해 2,000으로 높여야 합니다. 그러면 총 초당 요청 수 한도가 20,000으로 올라가기 때문입니다.
참고
이 초당 요청 수 한도에 기반해 각 Lambda 실행 환경이 초당 최대 10개의 요청만 처리할 수 있다고 말하는 것은 올바르지 않습니다. Lambda는 개별 실행 환경의 부하를 관찰하는 대신 쿼터를 계산할 때 전체 동시성과 전체 초당 요청 수만 고려합니다.
초당 요청 수 한도는 동시성과 관련된 Lambda의 모든 쿼터에 적용됩니다. 즉, 동기식 주문형 함수, 프로비저닝 동시성을 사용하는 함수, 동시성 확장 동작에 적용됩니다. 예를 들어 동시성과 초당 요청 수 한도를 모두 신중하게 고려해야 하는 몇 가지 시나리오는 다음과 같습니다:
- 주문형 동시성을 사용하는 함수는 10초마다 500의 동시성 버스트 증가를 겪거나, 10초마다 초당 5,000개의 요청 증가를 겪을 수 있습니다. 먼저 도달하는 쪽이 적용됩니다.
- 프로비저닝 동시성 할당이 10인 함수가 있다고 가정해 보세요. 이 함수는 동시성 10 또는 초당 100개의 요청 중 먼저 도달하는 순간 주문형 동시성으로 넘어갑니다.
동시성 쿼터
Lambda는 리전의 모든 함수에 걸쳐 사용할 수 있는 총 동시성에 대한 쿼터를 설정합니다. 이 쿼터는 두 수준으로 존재합니다:
- 계정 수준에서 함수는 기본적으로 최대 1,000유닛의 동시성을 가질 수 있습니다. 이 한도를 늘리려면 Service Quotas 사용자 안내서의 쿼터 증가 요청을 참고하세요.
- 함수 수준에서 기본적으로 모든 함수에 걸쳐 최대 900유닛의 동시성을 예약할 수 있습니다. 총 계정 동시성 한도와 관계없이 Lambda는 항상 예약 동시성을 명시하지 않는 함수를 위해 100유닛의 동시성을 예약합니다. 예를 들어 계정 동시성 한도를 2,000으로 늘렸다면 함수 수준에서 최대 1,900유닛의 동시성을 예약할 수 있습니다.
- 계정 수준과 함수 수준 모두에서 Lambda는 해당 동시성 쿼터의 10배와 같은 초당 요청 수 한도도 적용합니다. 예를 들어 이는 계정 수준 동시성, 주문형 동시성을 사용하는 함수, 프로비저닝 동시성을 사용하는 함수, 동시성 확장 동작에 적용됩니다. 자세한 내용은 동시성과 초당 요청 수 이해하기를 참고하세요.
현재 계정 수준 동시성 쿼터를 확인하려면 AWS Command Line Interface(AWS CLI)로 다음 명령을 실행하세요:
aws lambda get-account-settings
다음과 같은 출력이 보일 거예요:
{
"AccountLimit": {
"TotalCodeSize": 80530636800,
"CodeSizeUnzipped": 262144000,
"CodeSizeZipped": 52428800,
"ConcurrentExecutions": 1000,
"UnreservedConcurrentExecutions": 900
},
"AccountUsage": {
"TotalCodeSize": 410759889,
"FunctionCount": 8
}
}
ConcurrentExecutions는 총 계정 수준 동시성 쿼터입니다. UnreservedConcurrentExecutions는 함수에 아직 할당할 수 있는 예약 동시성의 양입니다.
함수가 더 많은 요청을 받으면 계정이 동시성 쿼터에 도달할 때까지 Lambda는 이 요청을 처리하기 위해 실행 환경 수를 자동으로 확장합니다. 그러나 갑작스러운 트래픽 버스트에 대응한 과도한 확장을 방지하기 위해 Lambda는 함수가 확장할 수 있는 속도를 제한합니다. 이 동시성 확장률은 계정의 함수가 요청 증가에 대응해 확장할 수 있는 최대 속도입니다(즉, Lambda가 새 실행 환경을 만들 수 있는 속도). 동시성 확장률은 함수에 사용 가능한 총 동시성인 계정 수준 동시성 한도와 다릅니다.
각 AWS 리전에서, 그리고 각 함수에 대해 동시성 확장률은 10초마다 1,000개의 실행 환경 인스턴스(또는 10초마다 초당 10,000개의 요청)입니다. 즉, 10초마다 Lambda는 각 함수에 최대 1,000개의 추가 실행 환경 인스턴스를 할당하거나 초당 10,000개의 추가 요청을 수용할 수 있습니다.
보통은 이 제한에 대해 걱정할 필요가 없습니다. Lambda의 확장률은 대부분의 사용 사례에 충분합니다.
중요하게도 동시성 확장률은 함수 수준 한도입니다. 즉, 계정의 각 함수는 다른 함수와 독립적으로 확장할 수 있습니다.
확장 동작에 대한 자세한 내용은 Lambda 확장 동작을 참고하세요.