Amazon Web Services 한국 블로그
AWS Lambda SnapStart – 함수 실행 속도 및 성능 가속화 기능
AWS의 고객은 AWS Lambda를 다양한 이유로 좋아해 주십니다. 개발 측면에서는 프로그래밍 모델이 간단하고 그 모델을 다른 AWS 서비스와 함께 쉽게 사용할 수 있다는 점을 높이 평가해주십니다. 운영 측면에서는 변화하는 사용 패턴에 신속하게 대응할 수 있는 강력한 애플리케이션을 구축할 수 있다는 이점이 있습니다.
이미 Lambda를 사용하고 있다면 아시겠지만, 함수는 안전하고 격리된 실행 환경에서 실행됩니다. 각 환경의 수명 주기는 Init
, Invoke
및 Shutdown
이라는 세 가지 주요 단계로 구성됩니다. Init
단계에서는 함수의 런타임을 부트스트랩하고 함수의 정적 코드를 실행합니다. 대부분의 경우 이러한 작업은 몇 밀리초 내에 완료되며 눈에 띌 정도로 단계가 길어지지는 않습니다. 나머지 경우에는 여러 가지 이유로 상당한 시간이 걸릴 수 있습니다. 첫째, 일부 언어의 런타임을 초기화하는 데 비용이 많이 들 수 있습니다. 예를 들어 Spring Boot, Quarkus 또는 Micronaut와 같은 프레임워크와 함께 Java 런타임 중 하나를 사용하는 Lambda 함수의 Init
단계는 때때로 10초까지 걸릴 수 있습니다(종속성 삽입, 함수 코드 컴파일 및 클래스 패스 구성 요소 스캔 포함). 둘째, 정적 코드는 일부 기계 학습 모델을 다운로드하거나, 일부 참조 데이터를 미리 계산하거나, 다른 AWS 서비스에 대한 네트워크 연결을 설정할 수 있습니다.
Lambda SnapStart 소개
Lambda를 더 다양하게 사용하실 수 있도록 오늘 Lambda SnapStart를 소개해 드리겠습니다.
특정 Lambda 함수에 대해 Lambda SnapStart를 활성화한 후 새 버전의 함수를 게시하면 최적화 프로세스가 트리거됩니다. 프로세스에 의해 함수가 시작되고 Init
단계 전체에 걸쳐 프로세스가 실행됩니다. 그런 다음 메모리 및 디스크 상태의 변경 불가능한 암호화된 스냅샷을 가져와서 다시 사용할 수 있도록 캐시합니다. 이후에 함수가 호출되면 필요에 따라 상태가 캐시에서 청크 단위로 검색되어 실행 환경을 채우는 데 사용됩니다. 새로운 실행 환경을 만드는 데 더 이상 전용 Init
단계가 필요하지 않으므로 이 최적화를 통해 호출 시간이 단축되고 더 잘 예측할 수 있게 됩니다.
이번 출시와 함께 Corretto(java11
) 런타임을 사용하는 Java 함수를 지원하며 Spring Boot, Quarkus, Micronaut, 및 기타 Java 프레임워크를 사용하는 애플리케이션에 Lambda SnapStart를 즉시 사용할 수 있을 것으로 예상됩니다. Java 함수용 Lambda SnapStart를 활성화하면 추가 비용 없이 최대 10배 더 빠르게 시작할 수 있습니다.
Lambda SnapStart 사용
저는 지난 세기에 마지막으로 Java를 실제로 접해봤기 때문에 AWS Labs 리포지토리의 서버리스 Spring Boot 2 예제를 출발점으로 사용했습니다. AWS SAM CLI를 설치하고 테스트 구축 및 배포를 수행하여 기준을 설정했습니다. 함수를 호출했더니 Init 지속 시간이 6초를 약간 넘는 것을 확인했습니다.
그런 다음 template.yml
에 두 줄을 추가하여 SnapStart
속성을 구성했습니다.
다시 빌드하고 다시 배포하고 SnapStart를 설정하는 새 버전의 함수를 게시하고 다른 테스트를 실행했습니다.
SnapStart를 사용하면 함수의 새 버전을 게시할 때 초기화 단계(앞서보여드린 Init 기간으로 표시됨)가 발생합니다. SnapStart가 활성화된 함수를 호출하면 Lambda는 함수 핸들러를 호출하기 전에 스냅샷(복원 기간으로 표시됨)을 복원합니다. 따라서 SnapStart를 사용한 전체 콜드 호출은 이제 복구 기간+기간으로 구성됩니다. SnapStart는 콜드 스타트 지속 시간을 6초 이상에서 200ms 미만으로 단축했습니다.
스냅 복원력 강화
Lambda SnapStart는 초기화된 단일 스냅샷을 재사용하여 여러 실행 환경을 재개함으로써 애플리케이션 속도를 높입니다. 이는 코드에 몇 가지 흥미로운 영향을 미칩니다.
고유성 — SnapStart를 사용하는 경우 고유성을 유지하려면 초기화 중에 생성되었던 모든 고유 컨텐츠를 초기화 후에 생성해야 합니다. 사용자(또는 사용자가 참조하는 라이브러리)가 유사 난수 생성기를 사용하는 경우 Init 단계에서 얻은 시드를 기반으로 해서는 안됩니다. SnapStart와 함께 사용할 때 임의성을 보장하기 위해 OpenSSL의 Rand_bytes
를 업데이트했고java.security.SecureRandom
이 이미 스냅 복원력이 있음을 확인했습니다. Amazon Linux의 /dev/random
및 /dev/urandom
도 스냅 복원력이 뛰어납니다.
네트워크 연결 – 코드가 Init
단계에서 네트워크 서비스에 대한 장기 연결을 만들어 Invoke
단계에서 사용하는 경우 필요 시 연결을 다시 설정할 수 있는지 확인하세요. 이를 위해 AWS SDK가 이미 업데이트되었습니다.
임시 데이터 — 이는 사실상 위 항목의 보다 일반적인 형태입니다. Init
단계에서 코드가 참조 정보를 다운로드하거나 계산하는 경우 캐싱 기간 동안 참조 정보가 오래되지 않았는지 빠르게 확인하는 것이 좋습니다.
Lambda는 고유성을 유지하는 데 도움이 되는 한 쌍의 런타임 후크와 발생 가능한 문제를 탐지하는 데 도움이 되는 스캔 도구를 제공합니다.
주요 사항
다음은 Lambda SnapStart에 대해 명심해야 할 몇 가지 사항입니다.
캐싱 — 캐싱된 스냅샷은 14일 동안 사용하지 않으면 제거됩니다. 업데이트되거나 패치된 런타임에 따라 스냅샷이 달라지는 경우 Lambda는 자동으로 캐시를 새로 고칩니다.
요금 — Lambda SnapStart를 사용하는 데는 추가 요금이 부과되지 않습니다.
기능 호환성 — 더 큰 임시 스토리지, Elastic File Systems, Provisioned Concurrency 또는 Graviton2에서는 Lambda SnapStart를 사용할 수 없습니다. 일반적으로 범용 Lambda 함수에는 SnapStart를 사용하고 지연 시간에 매우 민감한 함수의 하위 집합에는 Provisioned Concurrency를 사용하는 것이 좋습니다.
Firecracker — 이 기능은 Firecracker 스냅샷 생성을 사용합니다.
리전 — Lambda SnapStart는 미국 동부(오하이오, 버지니아 북부), 미국 서부(오레곤), 아시아 태평양(싱가포르, 시드니, 도쿄) 및 유럽(프랑크푸르트, 아일랜드, 스톡홀름) 리전에서 사용할 수 있습니다.
— Jeff;