서버 있는 서버리스?

AWS는 Lambda의 콜드 스타트 문제를 해결해줄 provisioned concurrency 기능을 발표했습니다. 사실 근본적으로 해결된 것은 아니지만요.

2019. 12. 07. #development #aws

서버리스(serverless), 단어의 뜻은 서버가 없다는 뜻이지만 정말로 서버가 없는 것은 아닙니다.

개발자가 코드를 짜서 업로드 해놓으면, 해당 프로그램을 호출하는 순간 AWS나 GCP 같은 클라우드 프로바이더가 서버 어딘가에 자원을 할당하고 실행합니다. 한 명이 호출하면 한 개, 100명이 호출하면 100개의 실행 환경이 생깁니다. 이 과정은 프로바이더가 알아서 하기 때문에, 개발자는 서버나 네트워크 구성 등에 대해서는 전혀 신경 쓸 필요가 없습니다. 이상적으로 동작한다면 많은 시간과 비용을 줄일 수 있는 아주 혁신적인 개념입니다.

배포와 운영은 클라우드에 맡기고 개발에만 집중하세요. — 서버리스 컴퓨팅의 상징과도 같은 문구

주간에 100명, 야간에 1만명이 이용하는 서비스를 생각해보죠. 기존에는 서버 대수를 야간 트래픽을 감당할 수 있도록 맞춰놓거나, 주간에는 서버를 내리고 야간에 다시 띄우는 등의 작업이 필요했습니다. 그럼에도 서비스가 갑자기 입소문을 타서 10만명이 접속하게 된다면 어떻게 될까요? 아무리 설계가 잘 된 서비스라도 물리적인 한계로 터져나가고 말 것입니다.

하지만 서버리스 컴퓨팅은 이러한 것을 신경쓰지 않아도 됩니다. 트래픽에 맞게 필요한 자원을 알아서 할당해주기 때문입니다. 필요한 자원을 예측한다는 것이 꽤나 복잡한 작업인 만큼, 이를 알아서 해준다는 것은 개발자나 운영자에게 꽤나 메리트가 큽니다. 할당된 자원 만큼만 과금이 이루어지니 비용도 꽤 절감할 수 있다는 점은 덤이구요.

현실은 녹록치 않다

그러나 서버리스 컴퓨팅은 몇 가지 현실적인 벽에 부딪히게 됩니다.

  • 표준이 없어 각 프로바이더마다 구현, 배포 방식이 제각각입니다. 따라서 전체적인 개발 프로세스가 특정 프로바이더에 강하게 종속되어버리는 문제가 생깁니다.
  • 상태(state)가 필요한 코드는 배포할 수 없습니다. 이는 각각의 호출이 격리된 환경에서 실행되기 때문입니다.
  • 프로그램을 호출해야 자원 할당(CPU, 메모리, 네트워크, 디스크 등)이 이루어집니다. 이들 자원을 할당하기 위해서는 당연히 물리적인 시간이 필요하고, 그 시간은 생각보다 짧지 않습니다.

특히 마지막 문제는 서버리스 컴퓨팅의 개념을 근본적으로 뒤집지 않는 이상 피할 방법이 없습니다. 좀 더 자세히 이야기해볼까요?

일반적인 프로그램의 호출 과정은 아주 추상적으로 '자원 할당 → 코드 호출 → 실행 결과 반환'의 순서로 나눌 수 있습니다. 간단히 말해 서버를 띄우고, API나 프로세스 콜로 코드를 호출하고, 실행 결과를 반환받는 구조이죠.

하지만 서버리스 컴퓨팅은 프로그램을 호출해야 자원 할당이 이루어집니다. 평상시에는 서버가 안떠있는데, 호출이 들어오면 그제서야 서버를 실행한다는 뜻입니다. 이 때 자원 할당에 걸리는 시간이 대부분의 경우 수 밀리초 이내로 이루어진다고는 하나, 현실은 수 초에서 수십 초에 이르는 경우가 빈번합니다. 이러한 현상을 콜드 스타트(cold start)라고 부릅니다.

여기에 AWS가 내놓은 답은...

AWS Lambda는 사실 매 호출마다 자원을 할당하지 않습니다. Lambda는 일단 한 번 할당한 자원을 수 분에서 수 시간동안 유지하면서 재활용합니다. 이는 어떤 실행 환경에서 /tmp 디렉토리에 파일을 썼을 때, 다른 실행 환경에서 일정 확률로 해당 파일을 읽을 수 있다는 점으로 확인할 수 있습니다.

하지만 이러한 구조도 콜드 스타트 문제를 근본적으로 해결하지는 못합니다. 어떤 서비스의 동시접속자가 100명에서 갑자기 1만명으로 늘어난다면 어떤 일이 생길까요? 그 중 100명은 자원을 재활용에 빠른 응답을 받겠지만, 나머지 9900명은 여전히 콜드 스타트 문제를 겪게 될 것입니다.

그래서 지난 12월 3일, AWS는 Lambda에 provisioned concurrency 라는 기능을 발표했습니다.

When you enable Provisioned Concurrency for a function, the Lambda service will initialize the requested number of execution environments so they can be ready to respond to invocations.

얼핏 보기에는 합리적인 서비스라고 생각될 수도 있습니다. '자원 할당에 시간이 오래 걸려서 반응성에 문제가 생기니까, 미리 자원을 할당해놓자!' 정도의 개념에서 나온 기능이기 때문이죠.

근데 서버리스는 필요한만큼만 할당하는게 핵심이잖아?

사용자의 선택권이 다양해진 것은 당연히 좋은 일입니다. 트래픽이 어느 정도 예측되는 서비스에서는 미리 환경을 확보해서 콜드 스타트 문제를 최소화할 수 있겠지요. Provisioned concurrency는 그런 분들을 위해 생겨난 기능일 것입니다.

하지만 이러한 기능 추가는 서버리스 컴퓨팅의 패배 선언과 다름이 없습니다. 위에서도 계속 말해왔듯이 서버리스 컴퓨팅의 최대 장점은 필요한 순간에 필요한 만큼의 자원으로 프로그램을 실행하고, 사용한 만큼만 비용을 지불한다는 점입니다. 그런데 실행 환경을 미리 구성해놓는다니요, 이러면 기존처럼 서버를 띄워놓는 것과 다를바가 없어집니다.

다시 주간에 100명, 야간에 1만명이 접속하는 서비스의 예시를 생각해봅시다.

  • 주간 인원에 맞춰 100개의 환경을 확보하면 야간에는 9900명이 여전히 콜드 스타트 문제를 겪게 됩니다.
  • 그럼 야간 인원에 맞춰 1만개의 환경을 확보해볼까요? 주간에는 9900개의 환경이 놀게 됩니다. 놀기만 하면 다행인데, 노는데도 요금을 지불해야 한다는 것은 별로 마음에 들지 않군요.

그렇다면 시간대별 트래픽에 맞게 수치를 유동적으로 조정하면 어떨까요? 음, 그러면 기존의 서버 운영 방식과 다른게 뭐죠?

결국 개발자에게 돌아온 자원 관리에 대한 책임

어떻게 보면 사소한 기능이 하나 생겨난 것에 불과할 수도 있지만 그럼에도 안타까운 건 어쩔 수 없습니다. 지금까지 그들은 마치 서버리스가 모든 운영은 알아서 할테니 개발자는 개발에만 집중하면 된다는 만능 해결책으로 소개해왔습니다. 이는 비단 AWS뿐만 아니라 GCP, Azure, CF 등 다른 클라우드 프로바이더 들도 마찬가지입니다.

하지만 AWS의 이번 기능 추가를 통해 자원 관리에 대한 책임이 다시 개발자에게로 돌아왔습니다. 지금까지의 콜드 스타트 문제가 오로지 AWS의 인프라 한계가 문제였다면, 이제는 개발자들이 자원이 충분을 확보하지 않은 책임도 생겼기 때문입니다. 개발자들은 다시 트래픽을 분석하고, 필요한 자원을 예측하고, 필요에 따라 조정해야하는 업무를 떠안게 되었습니다.

AWS가 firecraker 같은 초경량 가상화 기술을 계속 연구하고 있음에도 불구하고, 아직까지 서버리스 컴퓨팅은 이상이 기술에 가깝다는 생각에 못내 아쉽습니다. 하지만 이번 기능이 추가되었다고 서버리스 컴퓨팅이 완전히 무용해진 것은 당연히 아닙니다. 반응성이 크게 중요하지 않거나, 비용 절감이 중요한 중소규모 프로젝트에서는 여전히 유용하게 쓰일 수 있겠죠.

서버리스는 아직은 성숙하지 못한 기술인 만큼 한계도 명확합니다. 그리고 이러한 한계를 우회하기 위해 여러가지 꼼수를 쓰다보면, 어느 순간 기존의 구조보다 복잡해진 결과물을 마주하게 됩니다. 만약 여러분이 서버리스 컴퓨팅 도입을 검토하고 있다면, 이러한 장점과 단점을 충분히 인지하고 고려해보시길 바랍니다.

크리에이티브 커먼즈 라이선스

이 저작물은 크리에이티브 커먼즈 저작자표시-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.

© 2011 - 2020 Do Hoerin, LYnLab