팀 프로젝트를 진행하면서 AWS Lambda 서비스를 활용한 경험이 있는데 Lambda의 장점만 파악하고 실행 방법만 익혀 적용시켰었다.
Lambda는 어떻게 실행되는지도 모른 채 그저 적용만 시킨 경험으로 남기는 것은 나에게 별 도움이 될 것 같지 않아 Lambda는 실제로 어떻게 실행되는지 이해할 수 있는 범위 내에서 공부해 보기로 했다.
Lambda 함수 실행 방식을 혼자 이런 게 아닐까 생각했던 내용은 아래와 같다.
처음에는 위와 같은 생각을 가지고 있었는데 이번 기회에 공부를 해보니 깊이 알지는 못했지만 어느 정도 돌아가는 방식을 알 수 있게 되었다.
위 링크의 AWS Summit 2019 강연을 보면 Lambda 함수는 AWS EC2 베어 메탈 서버 위에 띄워진 firecracker라는 micro-vm 환경에서 실행되는 것을 알 수 있었다.
하나의 서버에서 별도의 실행환경을 가지기 위해서는 Linux 같은 경우 cgroups, namespaces 등 여러 명령어들을 통해 별도의 환경을 구성할 수 있는데 firecracker는 이러한 작업들을 효율적으로 처리할 수 있도록 개발되었다고 한다. 해당 기술 덕분에 Lambda 함수가 빠르게 실행되고, 하나의 Host 위에서 많은 vm들이 돌아갈 수 있게 되었다. (위 영상에서는 100 ~ 1000개의 vm 들이 하나의 Host 위에서 실행될 수 있다고 한다.)
실제 firecracker 홈페이지를 들어가 보면 위와 같은 설명을 볼 수 있는데 내가 처음 생각했던 대로 2014년에는 고객 당 EC2 하나가 할당되어 그 위에서 함수가 실행되었다는 것을 볼 수 있다. (동시 호출의 경우 하나의 인스턴스 위에 여러 함수가 실행되었는지는 모르겠다.)
여러 자료들을 참고하여 내린 결론은 Lambda 함수 설정값에 따라 다르다이다.
- Lambda 함수 코드 명령 세트 아키텍처 (x86_64, arm64)
- memory allocation
https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html
위 참고 자료 memory allocation 부분 Note에 적혀있는 것을 보면 Lambda 함수의 메모리 할당량에 따라 할당받는 vCPU 값이 다른데 1,796MB의 메모리당 하나의 vCPU를 할당받는 것을 알 수 있었다.
그렇다면 vCPU를 하나 할당받는다는 것은 무슨 의미일까?
vCPU가 의미하는 바는 프로세서마다 다를 수 있는데 만약 Intel CPU를 선택한 인스턴스라면 Hyper-Threading 기술을 이용한다고 가정했을 때 vCPU 수를 아래와 같은 수식으로 나타낼 수 있다. (Lambda 옵션에서 x86_64)
vCPU 수 = CPU core 수 X 코어당 스레드 수 (일반적인 경우 2)
따라서 vCPU 하나를 할당받는다는 것은 core의 절반을 할당받았다고 볼 수 있다
AWS Graviton2 Processor라면 vCPU 수가 결국 할당받은 core 수가 된다. (Lambda 옵션에서 arm64)
vCPU 수 = CPU core 수
위 경우를 제외하고 작성한 Lambda 코드가 하나의 vCPU를 할당받는다는 가정하에 동시에 들어온 Lambda 함수는 모두 각기 다른 micro-vm을 할당받고 각각 vCPU를 할당받으며 실행된다고 볼 수 있다.
위 영상에서는 Lambda 함수가 invoke 되면 위와 같은 일들이 일어난다고 알려준다.
Worker 매니저가 적절한 Worker를 찾아서 함수를 실행시키게 되는데 Worker는 또 한번의 작업(firecracker를 통한 micro-vm 생성)을 통해 함수를 실행 시킨다.
https://docs.aws.amazon.com/whitepapers/latest/security-overview-aws-lambda/lambda-executions.html
결국 한 번의 Lambda 함수 호출은 아래와 같은 과정을 거쳐 실행된다고 볼 수 있다.
동시에 들어온 요청을 통해 각각의 함수가 위와 같은 과정을 거친다고 생각하면 말 그대로 "동시에 실행"된다는 것은 불가능할 것이다.
그렇지만 여러 기술들로 인해 매우 빠르고 효율적으로 Lambda 함수 실행을 위한 독립적인 환경을 구성할 수 있고 각각의 함수가 독립된 환경에서 실행되고 있기 때문에 "거의 동시에 실행"된다고도 볼 수 있을 것이다.
실제로 1초가 걸리는 작업을 Lambda 함수로 작성하여 동시에 10번 호출하게 되면 10초가 아닌 1 ~ 2초가 걸리는 것을 보면 알 수 있다.