AWS Lambda 컨테이너 재사용을위한 모범 사례

AWS Lambda를 다른 서비스에 연결할 때 웜 스타트 최적화

AWS Lambda는 서버리스 및 상태 비 저장으로 인해 높은 확장 성을 제공하므로 여기에 설명 된대로 많은 람다 함수 복사본을 즉시 생성 할 수 있습니다. 그러나 애플리케이션 코드를 작성할 때 일부 상태 저장 데이터에 액세스하려고 할 수 있습니다. 이는 RDS 인스턴스 또는 S3와 같은 데이터 스토어에 연결하는 것을 의미합니다. 그러나 AWS Lambda에서 다른 서비스에 연결하면 함수 코드에 시간이 추가됩니다. RDS 인스턴스에 허용되는 최대 연결 수에 도달하는 것과 같이 높은 확장 성으로 인한 부작용이있을 수도 있습니다. 이에 대응하는 한 가지 옵션은 AWS Lambda에서 컨테이너 재사용을 사용하여 연결을 유지하고 람다 실행 시간을 줄이는 것입니다.

여기에 람다 요청의 수명주기를 설명하는 유용한 다이어그램이 있습니다.

콜드 스타트 ​​(cold start) 중에 함수가 처음 또는 불 활동 기간 후에 호출되면 다음이 발생합니다.

  • 코드와 종속성이 다운로드됩니다.
  • 새로운 컨테이너가 시작됩니다.
  • 런타임이 부트 스트랩됩니다.

마지막 조치는 람다 함수가 호출 될 때마다 발생하는 코드를 시작하는 것입니다. 람다 함수의 후속 호출을 위해 컨테이너를 재사용하는 경우 코드 시작으로 건너 뛸 수 있습니다. 이를 웜 스타트라고하며 이는 핸들러 메소드의 범위 밖에서 연결을 정의하여 다른 서비스에 연결할 때 최적화 할 수있는 단계입니다.

Lambda에서 다른 AWS 서비스에 연결

예 : 여기에서 제공되는 AWS 아이콘 인 RDS 인스턴스에 연결

기본 및 일반적인 예제가 있습니다. 컨테이너 데이터에 연결하여 농축 데이터를 가져 오려고합니다. 이 예제에서 JSON 페이로드는 ID와 함께 제공되며 Lambda 함수는 PostgreSQL을 실행하는 RDS 인스턴스에 연결하여 ID의 해당 이름을 찾아 풍부한 페이로드를 반환 할 수 있습니다. 람다 기능이 VPC에있는 RDS에 연결되어 있으므로 람다 기능은 이제 프라이빗 서브넷에도 있어야합니다. 이렇게하면 콜드 스타트에 몇 단계가 추가됩니다. VPC ENI (Elastic Network Interface)를 연결해야합니다 (Jeremy Daly의 블로그에서 언급했듯이 콜드 스타트에 시간이 추가됩니다).

참고 : RDS 대신 DynamoDB와 함께 키 / 값 스토리지를 사용하는 경우 VPC를 사용하지 않아도됩니다.

이 작업에 대한 두 가지 솔루션을 살펴 보겠습니다. 첫 번째는 '순진한'솔루션이고 두 번째 솔루션은 후속 호출에 연결을 재사용하여 시작 시간을 최적화합니다. 그런 다음 각 솔루션의 성능을 비교합니다.

옵션 1 — 처리기 내의 RDS에 연결

이 코드 예제는이 작업에 순진하게 접근하는 방법을 보여줍니다. 데이터베이스 연결은 핸들러 메서드 내에 있습니다. 페이로드를 반환하기 전에 ID의 이름을 가져 오는 간단한 선택 쿼리가 있으며 여기에는 이름이 포함됩니다.

동시성 20의 버스트 2000 호출로 소규모 테스트 중에이 옵션이 어떻게 수행되는지 살펴 보겠습니다. 최소 지속 시간은 18ms이며 평균 51ms이고 최대 1 초 (콜드 스타트 ​​지속 시간)입니다.

람다 지속 시간

아래 그래프는 데이터베이스에 최대 8 개의 연결이 있음을 보여줍니다.

5 분 동안 RDS 데이터베이스에 대한 연결 수

옵션 2 — 전역 연결 사용

두 번째 옵션은 연결을 핸들러 메소드 외부의 전역으로 정의하는 것입니다. 그런 다음 핸들러 내부에 연결이 있는지 확인하고 연결되어 있지 않은 경우에만 연결합니다. 즉, 컨테이너 당 한 번만 연결됩니다. 조건부로이 방법으로 연결을 설정하면 코드 논리에 필요하지 않은 경우 연결할 필요가 없습니다.

더 이상 데이터베이스에 대한 연결을 닫지 않으므로 이후에 함수를 호출하기 위해 연결이 유지됩니다. 연결을 재사용하면 웜 스타트 지속 시간이 크게 줄어 듭니다. 평균 지속 시간은 약 3 배 빠르며 최소값은 18ms가 아닌 1ms입니다.

람다 지속 시간

RDS 인스턴스에 연결하는 것은 시간이 많이 걸리는 작업이므로 모든 호출에 대해 연결하지 않아도 성능에 도움이됩니다. 간단한 데이터베이스 쿼리를 위해 데이터베이스에 연결할 때 동시성 수준과 일치하는 최대 데이터베이스 연결 수는 20입니다 (20 개의 동시 호출 x 100 회 수행). 호출 버스트가 중지되면 연결이 점차 닫힙니다.

AWS가 람다 지속 시간을 15 분으로 늘렸으므로 데이터베이스 연결이 더 오래 지속될 수 있으며 RDS 최대 연결 수에 도달 할 위험이 있습니다. 최대 연결 수를 늘리면 메모리 할당에 문제가 발생할 수 있지만 RDS 매개 변수 그룹 설정에서 기본 최대 연결을 덮어 쓸 수 있습니다. 더 작은 인스턴스의 기본 max_connections 값은 100보다 작을 수 있습니다. 이러한 제한을 염두에두고 필요한 경우 데이터베이스에 연결할 응용 프로그램 논리 만 추가하십시오.

다른 작업에 글로벌 연결 사용

S3에 연결하는 Lambda

Lambda로 수행해야 할 일반적인 작업은 S3에서 상태 저장 데이터에 액세스하는 것입니다. 아래 코드 스 니펫은 AWS에서 제공 한 Python Lambda 함수 청사진입니다. AWS 콘솔에 로그인 한 후 여기를 클릭하면 탐색 할 수 있습니다. 코드에서 컨테이너가 초기화 될 때 S3 클라이언트가 처리기 외부에 완전히 정의되어 있음을 알 수 있지만 RDS 예제의 경우 전역 연결이 처리기 내부에 설정되어 있습니다. 두 가지 방법 모두 전역 변수를 설정하여 이후 호출에 사용할 수있게합니다.

s3-get-object 람다 청사진 코드 스 니펫 https://console.aws.amazon.com/lambda/home?region=us-east-1#/create/new?bp=s3-get-object-python

환경 변수 해독

람다 콘솔은 추가 보안을 위해 환경 변수를 암호화하는 옵션을 제공합니다. 다음 코드 스 니펫은 Lambda 함수에서 환경 변수를 해독하기위한 도우미 스크립트의 AWS 제공 Java 예제입니다. 이 학습서 (특히 6 단계)에 따라 코드 스 니펫을 탐색 할 수 있습니다. DECRYPTED_KEY는 클래스 전역으로 정의되므로 decryptKey () 함수와 논리는 람다 컨테이너 당 한 번만 호출됩니다. 따라서 웜 스타트 시간이 크게 향상됩니다.

https://console.aws.amazon.com/lambda/home?region=us-east-1#/functions 및 https://docs.aws.amazon.com/lambda/latest/dg/tutorial-env_console.html

다른 FaaS 솔루션에서 글로벌 변수 사용

이 방법은 AWS Lambda와 분리되어 있지 않습니다. 글로벌 연결 사용 방법은 다른 클라우드 제공 업체의 서버리스 기능에도 적용 할 수 있습니다. Google Cloud Functions 팁 및 요령 페이지에는 지연 시간이없는 변수 (변수가 항상 핸들러 메소드 외부에서 초기화되는 경우)와 지연 변수 (전역 변수는 필요한 경우에만 설정 됨) 전역 변수에 대한 자세한 설명이 있습니다.

다른 모범 사례

명심해야 할 다른 모범 사례는 다음과 같습니다.

테스팅

FaaS를 사용하면 마이크로 서비스 아키텍처를 갖출 수 있습니다. 작고 별개의 기능을 갖는 것은 효과적인 단위 테스트와 함께 진행됩니다. 단위 테스트를 돕기 위해 :

  • 람다 패키지에서 테스트 종속성을 제외해야합니다.
  • 프로그램의 기본 메소드와 마찬가지로 처리기 메소드에서 로직을 분리하십시오.

종속성 및 패키지 크기

배포 패키지의 크기를 줄이면 초기화시 코드 다운로드 속도가 빨라져 초기 시작 시간이 향상됩니다. 배치 ZIP 파일 크기를 줄이려면 사용하지 않는 라이브러리와 데드 코드를 제거하십시오. AWS SDK는 Python 및 JavaScript 런타임 용으로 제공되므로 배포 패키지에 포함 할 필요가 없습니다.

Node.js가 선호하는 Lambda 런타임 인 ​​경우 축소 및 축소를 적용하여 함수 코드의 크기를 줄이고 배포 패키지의 크기를 최소화 할 수 있습니다. 축소 및 축소의 모든 측면이 아닌 일부는 다른 런타임에 적용될 수 있습니다. 파이썬 코드에서 공백을 제거 할 수는 없지만 주석을 제거하고 변수 이름을 줄일 수 있습니다.

메모리 설정

Lambda 함수에 대한 최적의 메모리 양을 찾기 위해 실험하십시오. 메모리 할당 비용을 지불하므로 메모리를 두 배로 늘리면 밀리 초당 두 배를 지불해야합니다. 그러나 할당 된 메모리에 따라 컴퓨팅 용량이 증가하므로 실행 시간을 원래보다 절반 미만으로 줄일 수 있습니다. 이와 같은 최적의 메모리 설정을 선택하는 유용한 도구가 이미 있습니다.

결론적으로…

고려해야 할 한 가지는 연결 재사용 방법을 적용해야하는지 여부입니다. 람다 함수가 하루에 한 번과 같이 가끔씩 만 호출되는 경우에는 웜 스타트를 최적화하지 않아도됩니다. 성능 최적화와 코드의 가독성 간의 균형을 맞추는 경우가 종종 있습니다. 또한 코드에 전역 변수를 추가하여 다른 서비스에 대한 연결을 재사용하면 코드 추적이 더 어려워 질 수 있습니다. 두 가지 질문이 떠 오릅니다.

  • 새로운 팀원이 귀하의 코드를 이해합니까?
  • 앞으로 귀하와 귀하의 팀이 코드를 디버깅 할 수 있습니까?

그러나 규모에 따라 Lambda를 선택하고 높은 성능과 저렴한 비용을 원한다면 팀의 요구에 맞는 균형을 찾으십시오.

이러한 의견은 저자의 의견입니다. 이 게시물에서 달리 언급되지 않는 한 Capital One은 언급 된 회사와 제휴하거나 보증하지 않습니다. 사용되거나 표시된 모든 상표 및 기타 지적 재산은 해당 소유자의 소유권입니다. 이 기사는 © 2019 Capital One입니다.