Serverless와 기술도입, Backend Application의 미래

빙글의 Backend Application을 Monolithic EC2 + Ruby On Rails에서 Microservice Architecture 기반의 AWS Lambda + Node.JS 로 옮겼다는 이야기를 몇 번인가 발표하고 난 뒤로, 외부 사람들을 만나서 System Migration에 대한 이야기를 하다보면 언제나 비슷한 질문을 듣게됩니다.

  1. AWS Lambda 비싸지 않아요?
  2. AWS Lambda 에서 EC2에서 하는걸 다 할수 있긴 해요?
  3. 대표님이 migration 해도 된다고 하시던 가요?

(그 외에 Microservice Architecture 라는게 도대체 뭐냐? 같은 단순 개념 질문이야 한국에서는 사례가 드물기에 당연한 것 같고요. 구글 검색 해보시면 더 정확한 걸 왜 굳이 저에게 물어보시는 지는 모르겠지만..)

사실 개인적으로, 이런 질문을 들을때마다 좀 당황스럽습니다. 사실 새로운 기술을 선택하고, 팀원들을 설득하고, 그 기술에 맞는 도구를 (없다면) 직접 만들고 하는 긴 과정을 할지 말지 선택할 때, 당연히 저것보다 훨씬 중요한 질문들이 많았기 때문입니다.

오늘은 저희가 Serverless에 베팅을 걸었을때 제가 고민했던게 뭐였는지, 그리고 지나고 나서 돌아봤을때 놓친게 뭐였는지, 그리고 이런 기술선택을 할때 저희가 답을 고민해야하는 질문이 도대체 뭔지 (답이야 상황에 따라 다르겠지만) 에 대해 Serverless로의 migration 경험을 토대로 이야기해보려고 합니다.

(질문들은 굳이 답변하자면 “더 싸요” / “아니요" / “원래 이런건 허락 안 받아요” 긴 합니다)


여러분의 기술 선택은 안녕하십니까?

우선, 많은 팀들이 “기술 선택” / “기술 도입” 이라는걸 매우 추상적으로, 그리고 거대 트렌드 차원에서만 생각하고 실행한다는 생각이 듭니다.

Michael Burry 라는 투자가가 있습니다. 이사람은 2008년 금융위기에서 주택시장의 붕괴 (정확히는 주택담보부증권의 붕괴) 를 몇년 앞서 예측하고, 이를 기반으로 주택담보부증권을 공매도하여 +489% 라는 기록적 수익률을 남긴걸로 유명한데요. 
이 사람은 이 공매도를 유지하는 기간 내내, 자신이 관리하는 기금의 투자자 들로부터 줄소송 (“이렇게 잘나가는 주택시장을 공매도라니 미쳤냐” / “내 돈 돌려내라”) 을 당했습니다.
그렇다고 이사람이 묻지마 투자를 한건 당연히 아니였습니다. 영화에도 나오지만, 이 사람은 아주 단순하게도, 주택담보부증권의 raw level data 몇만건을 직접 하나씩 읽고 확인하여 믿기 어렵지만 아주 논리적인 결론, “주택담보부증권은 전부 지나치게 높게 평가되어 있으며, 곧 default에 빠질 것이다” 에 다다랐죠. (그외에도 주택 대출 사기가 급증했다 등의 시장 data도 있었고요)

(주택담보부증권은 집을 담보로 돈을 빌린 대출 몇천-몇만건을 묶어서 하나의 증권으로 만드는거라, 그 증권을 만든 변호사나 그 대출들을 전부 확인하지, 투자자들은 무디스나 S&P같은 증권평가회사들에서 정한 증권의 평가등급만 봤던 겁니다. 증권 안에 있는 몇천건의 대출 하나하나의 상환 상태나 default 가능성을 확인 해보지는 않았던거죠)

당시는 미국 정부, 은행, 금융평가원, 연방준비위원회 모두 주택시장은 안정적이며 리스크는 낮다고 하던 시절 이였으니, 투자자들이 이랬던걸 이해 못할건 아닙니다.

이 사람은 결국에는 공매도 포지션을 팔아 자신에게 소송을 건 투자자들에게도 기록적인 수익률을 남겨준뒤, 자신이 운영하던 펀드를 닫아버립니다.

“사람들은 권위있는 전문가들이 자산의 가치를 어떻게 평가할지 알려주기를 기대합니다. 다만, 사람들은 이 “권위”를 “사실” 이나 “실적”을 보고 판단하기 보다 “더 권위있어 보이니까” “더 익숙하니까 / 친밀해보이니까(familiar)” 에 기반해 판단합니다”
“저는 한번도 익숙하거나 친밀해보이는 사람인 적이 없었고, 앞으로도 그러지 못할 것 같습니다. 그렇기에 펀드를 닫아야만 한다는 결론에 도달했습니다”

(참고로 이사람은 몇년뒤 다시 펀드를 열었고, 요즘은 비트코인에 투자한다고 하더군요)

제가 이 이야기를 감명깊게 봤던건, 여기서 “자산"“Framework” / “Library” “Architecture” 로 바꾸면 많은 개발자들에게 그대로 적용되는 내용이기 때문입니다.

예를들어 Docker.

물론 Docker가 근본적으로 나쁘다 이런게 아니라, (빙글에서도 여전히 Docker 사용하고 있어요;;) “Cloud에 올릴꺼면 당연히 instance가 한대여도 Container 써야지!!!!!!!!!” 가 아니면 설명될수 없는 도입이 너무 많다는 겁니다.

개인적으로는 ELK를 이 예시로 참 자주 느끼는데요. ELK 그 자체가 악하다거나 나쁘다거나 이런게 아니라, 도대체 왜 Log 분석이나 search는 무조건 ELK 로 하는걸까요?
제가 실제로 겪었던 사례 하나는,

(게임회사 다니시는 상대방): HTTP Log 분석좀 하려고 하는데, EC2랑 연결해서 AWS에서 ELK운영 해보셨나요?
(저): 저희는 Kiniesis / Athena / S3로 처리하고 있는데요. 스케일링도 그게 더 편하고, ELK에서 꼭 필요한 기능이 있거나 그런게 아니라서요.
(상대방): 그래도 ELK가 일반적이지 않나요?
(저): “일반적" 이긴 하지만, 특히 게임이면 스케일링이 클텐데, web server 늘어나는거 맞춰서 ELK Cluster 안터지도록 늘리는건 어떻게 하시려고요? 그리고 그냥 Error rate나 접속 위치 같은거 보시는 정도라면 굳이 ELK 에서만 되는 기능도 아닌데…

물론, ELK가 압도적인 우위를 가지는 기능도 분명히 있고, 그런것들을 고려해서 선택하는건 당연히 이상할게 없죠. 다만 다른 대안이 없는것도 아닌데, “Log 분석은 다들 ELK로 하니까” ELK를 선택하는건 뭔가 뒤틀려 있다는 겁니다;

기술은 언제나 상황과 맥락에 따라 그 가치가 달라지고, 회사나 팀마다 상황이 분명히 다 다를텐데 말이죠. “100% 나쁜 기술” “100% 좋은 기술" 이런건 단언코 없습니다. 
하다못해 공인인증서도, 한때는 정말 진보된 보안 기술로 취급되던 시절과 상황이 있었고, Web application의 standard model이 Apache / PHP / Mysql 이던 시절도 있었듯이요.

물론 빙글에서도 이런 실수, 참 많이도 했습니다;

기술 선택은 팀과 비즈니스를 위해서

그럼 도대체 기술을 선택할때, 어떤 질문을 던져야 하는걸까요?
당연한 것들이긴 한데, 제가 생각하는 질문은 이런것들입니다.

  • 개발자들이 더 편하고 즐겁게 일할수 있게 되는가?
  • 개발자들의 생산성이 더 좋아지는가?
  • 팀원들이 충분히 납득할수 있는 선택인가? (혹은 내가 설득할수 있는 선택인가?)
  • 긴 미래가 보장된 기술인가?
  • 비즈니스에도 도움이 되는가?
  • 서비스 사용자들에게도 도움이 되는가?

기술적으로 아무리 우월하고 (일단 그게 “우리 상황에서도” 우월한건지도 체크하는게 먼저지만) 아무리 멋있고 아무리 문서가 이쁘고 폰트가 이쁘고 스크린샷이 예뻐도, 
그것들은 우리가 새로운 기술을 배우고 도입해야 하는 결정적인 이유는 당연히 아닌 겁니다.

사실 그래서 저는 언제나 세미나 같은데서 저희 경험을 이야기 하고나서, 이런 질문을 기대합니다. “팀원들은 어떻게 설득했나요?” / “그게 비즈니스적으로도 도움이 되나요?” / “생산성이 정말 더 좋아지나요?” 같은거요
정말 고맙게도 가끔은 듣긴 하지만, 앞에도 언급했듯이, serverless도 이런 측면에서 고려되기 보다는 기술 그 자체의 물적 특성 (infra 관리가 줄어든다, 돈을 아낀다.. 등등) 으로만 접근되는 경우가 많은것 같습니다. 이 부분을 좀더 파보죠.

Serverless와 Microservice 도입의 실제 효과

AWS와 Serverless를 적극적으로 도입하면서 생긴 재밌는 변화중 하나는, 저희가 기존에도 “쉽지만 귀찮다” 는 이유로 유저에게 도움이 되는데도 안하고 있던 일들을 하게 됬다는 겁니다.

예를들어, 빙글은 아주 초창기 부터 vin.gl 이라는 도메인을 가지고 있었습니다. 개발자중 한명이 저거 goo.gl 처럼 쇼트너로 쓸수 있겠는데? 라고 했거든요.

하지만 실제로 vin.gl을 지원하는 일은 아주 오랫동안 미뤄져 왔습니다. 사실 만드는건 엄청 쉬운 일처럼 보였음에도 불구하고 말이죠. (vin.gl/p/1 -> vingle.net/posts/1 redirect. 너무 간단하잖아요?)

가장 큰 이유는 그걸 “유지보수” 해야한다는 점 이였습니다. 만드는건 좋은데, 저게 만약 트래픽이 몰려서 스케일링을 해야하는 상황이 생기면?
참고로, 당시에 나와있던 가장 Fully Managed 된 PaaS는 Heroku였고, Heroku는 트래픽이 몰리면 스케일링이 최소 10~15분정도 걸렸습니다. 그 동안은 서버 다운 인거죠

즉, 개발자로서 우리가 스스로에게 뭉뚱그려서 “쉽지만 귀찮다" 라는 기표를 사용하는 메시지가, 사실 그 기의를 좀더 자세히 들여다보면

“Application Logic은 간단한데 이걸 어디다 배포해야할지도 애매하고, 배포한뒤에 모니터링도 구축해야하고, 그런게 다 갖춰진 기존 시스템에 붙이자니 너무 독립적인 기능이고, 이걸 잘못 배포하면 기존 시스템도 죽는 리스크를 감수할순 없다. 스케일링 하는것도 답이 없다. 안그래도 “공유"를 위한 기능인데, 갑자기 바이럴 타서 트래픽 터지면 그때는 어떻게 하냐? 그나마 managed 인게 heroku 인데 엄청 비싼데다가, 이것도 스케일링은 최소 10분 이상 걸린다. 모니터링도 별도로 구축해야하는데, url 별로 요청량을 보고싶다 거나 하면 또 별도로 Fluentd나 Kafaka 같은걸 붙여야해서 그것만 해도 별도로 Cluster를 또 만들어야한다. 그럼 그건 또 어떻게 관리하냐

였던거죠. 물론 아무도 이걸 이렇게 명확하게 설명하진 않았습니다. 그냥 직관적으로 “귀찮다 / “손이 많이간다” 고 표현한거죠. 
그러니, 사실 “쉽지만” 이라는 말 자체가 기만적 이였던 겁니다. Application Logic만 간단한거지, 유저에게 실제로 가치를 제공할수 있는 단위 (Scaling / Monitoring / continuous deployment 되는 Service) 로서는 여전히 엄청 어려운 일이였던거죠.

돌이켜보면 제 스스로도 이랬던 것 같은데, 개발자들은 이런경우 “어렵다” 고 표현하기 보다, “귀찮다" 고 표현하곤 합니다; 그러니까 시스템을 유지보수하는것도 개발자의 일임에도, 그걸 인정하기는 정말 싫으니 (사실, 만드는게 재밌지 하루종일 그래프보면서 모니터링하고 스케일링 하는게 뭐가 재밌습니까),

“내가 재밌어 하는 부분은 쉬운데 내가 싫어하는 부분은 어려워”“쉬운데 귀찮아” 정도로 번역했던것 같네요. 
비트겐슈타인 말마따나, “언어는 규칙적이지만 맥락을 포함한 언어의 사용은 언어가 아니라 언어게임이며 이것은 불규칙적 입니다”

3년뒤, AWS와 Serverless / Microservice 로 옮기고 난 시점에서 vin.gl shortener를 만들어보자는 이야기가 나왔을때는 답변이 많이 달라져 있었습니다.

그리고 결과적으로, vin.gl shortener는 사용자들에게 나갈수 있는 수준으로 완벽하게 만드는데까지, 채 24시간이 걸리지 않았습니다.

이유는 간단했는데, 실제로 제가 해야하는 일 자체가 줄었기 때문입니다.
vin.gl을 위해, 저는 Cloudfront / Lambda@Edge / S3 / Athena를 사용했습니다.

Scaling
- 시스템 구성요소 전부 auto scaling 됩니다.

Monitoring
- CloudFront / Lambda는 Cloudwatch로 error rate등이 제공되고, raw level log는 CloudFront S3 Log를 Athena로 쿼리해서 봅니다.

Deployment
- 코드를 zip으로 압축하여 s3에 올리기만 하면, 거의 즉시 배포됩니다.

이러고 나니, 개발자로서 해야하는 일은 정말 Business Logic을 작성하는게 끝이였습니다.

개발자들이 일을 안해야 서비스가 죽지 않는다 (?)

또, 개발자들이 이런 업무를 무의식적으로 “귀찮다" 라고 표현하는데는 나름의 귀납적이며 경험적인 근거가 있습니다.

https://www.youtube.com/watch?v=CZ3wIuvmHeM 정말 명강의 입니다.

Netflix 사례인데, 주말일수록 outage가 적게 나고, 아침 9시에 outage가 가장 많이 납니다. 
이유는 알만하죠? 퇴근할때 배포하긴 싫으니까, 작업은 다 해놓고 다음날 아침에 와서 Deploy => Service Down 
주말엔 일을 안하니까 (이 데이터로 봐서는 Netflix는 “안한" 다기 보다는 평일보다 “적게" 하는 듯 하는군요..) 당연히 배포가 적고, 그러니 Outage가 안나고.

정리해보면, 내가 새로운 기능을 만들고 배포할때

  1. Application 자체가 너무 커서 기능간의 dependency가 많아 배포할때 다른 기능까지 터지는 경우가 잦고
  2. 실제 business logic 작성 이외에 Monitoring / Scaling / Deployment 등이 너무 귀찮다

이 두가지가 문제 였던 겁니다.

그리고 우리의 사고 방식

과학적인 근거는 찾아봐야겠지만, 저는 기본적으로 인간의 뇌는 새롭거나 낯선 사고를 피하도록 설계 되어있다고 생각합니다. 그리고 나중에는 내가 사고를 피하는 부분이 있다는 사실 자체를 잊어버리도록 만드는것 같아요.

다들 그런게 하나씩은 있잖아요? 이불킥 기억 이라던가, 인정하기 싫은 내 자신의 결점 이라던가. 물리적인 예시로는, 지름길이 있다는걸 아는데도 생각없이 걷다보면 무의식적으로 익숙하지만 먼 길로 간다거나

진화적으로 생각해봐도 어떤 사고회로가 계속 작동할수 있다는 사실 자체가, 그 사고를 하는 뇌가 죽지 않고 살아있는데 도움이 된다는 의미가 되니, 이미 잘작동하는 회로일수록 계속해서 살아남아 강화되어 작동하도록 진화하지 않았을까요? 물론 과학적 근거는 없습니다;

개발자들을 예로 들자면, “운영" 업무가 있다는걸 초기에는 무척 낯설게 받아들입니다. 혼자서 Toy project 만 하던 사람이 회사에 처음 입사해서 서비스 개발을 하기 시작하면, 그때는 “아 Bussiness Logic 만드는거 말고 이런 운영 업무도 있구나. 흠.. 내 본업은 개발을 하는거 아닌가” 라고 생각하죠. 그런데, 그게 엄청 익숙해지면 그게 존재한다는 사실 자체를 까먹게 됩니다. “쉬운데 손이 많이간다” / “쉬운데 귀찮다" 같이요. 
그리고 나중에야, 자신의 사고를 Loop를 돌면서 계속해서 파보다보면 문득 제 사고가 의식적으로 피하는 부분이 있었다는걸 깨닫게 됩니다.

어떤 기술을 선택하는지가 정말 막중한 작업으로 느껴지는건 바로 이것 때문입니다.

저희는 기존에 Opsworks / ECS등을 사용해서 서비스 운영을 했었는데, (그 전에는 Heroku를 사용했고요) 이러다보니 당연히 독립적인 서비스를 만들자 (Microservice)로 가자는 말이 쉽게 안나옵니다. 설정할게 너무 많고, 그 서비스의 특성에 맞게 scaling / monitoring 다 구축해야하고..

그러다보니 자연스럽게 잘 돌아가고 있는 Ruby On Rails 에 기능을 붙이는걸로 해결하게 되고, 그러다보니 시스템이 무거워지고, 그러다보니 배포 주기를 길게 가져가게 되고, 그러니 기능 변경사항이 있을때 몰아서 배포하게 되고, 그러니 배포마다 리스크가 커지고, 그러니 배포 자체를 꺼리게 되고..

Lambda / Cloudwatch / Kinesis / API Gateway 같은 fully-managed serverless 서비스들이 팀 차원에서 우리에게 준 가장 큰 영향은, 개발을 시작하기도 전에 운영때문에 사고를 차단하는 일을 줄여 줬다는 겁니다.

즉 아무도 “이제는 운영업무가 줄었으니까 좀더 다양한 Application을 만들어보자” 라고 하지 않았음에도, 팀원들 각자가 Serverless나 Microservice 같은 환경변화에 적응하면서, 자연스럽게 다양한 Application을 만들고 더 빠르게 배포하고 유연하게 대처하게 된 겁니다. 사고의 흐름 자체가 지속적으로 바뀐거죠.

Backend Application 개발의 미래

마지막으로, Serverless가 과연 긴 미래가 보장된 기술인지를 짚어보려고 합니다.

기술 선택에 있어, “미래” 가 있는 기술 인가는 두말할것 없이 중요합니다. 저는 Apple이 Flash를 지원하지 않았던게 좋은 예시라고 생각하는데요,

모든 기술은 일정한 생애를 지닙니다. 봄 여름 가을 겨울을 거쳐, 결국은 무덤으로 가죠. 애플에서는 언제나 “봄”에 있는 기술을 선택하려고 노력합니다. 그리고 우리가 이걸 아주 지혜롭게 잘 해내면, 정말 엄청난 시간과 노력을 아끼게 되죠.
우리는 Flash가 전성기를 이미 누렸고, 지금은 쇠퇴기에 들어간 기술이라고 생각했습니다. 그리고 HTML5 / Javascript 야 말로 “봄” 에 있는 기술이라고 생각했죠.

(참고로 저는 고등학교를 300MB짜리 Flash파일 하나로 만든 web page를 만들어서 특별전형으로 들어갔습니다… 아이폰이 한국에 들어오기 전이라서 다행 이였어요;)

통시적으로 생각해보면, Backend Application을 만드는 방법은 몇가지 단계를 거치며 변화해 왔습니다.

  1. IDC에 있는 거대한 서버 컴퓨터에 Application을 올린다.
  2. Cloud에 있는 가상화 된 서버 컴퓨터에 Application을 올린다
  3. Cloud에 있는 가상화 된 서버 컴퓨터에 Container를 올리고 (Docker+ ECS / Kubernetes 같은) Application을 Container Image로 만들어 올린다.

여기서 읽어낼수 있는 트렌드는 물론, “개발자들이 좀더 편하게 Business Logic 작성에 집중할수 있도록” 일겁니다. 최대한 Scailing, Failover, monitoring 같은 infra 관리와 관련된 것들을 자동화 하는 트렌드인거죠.

AWS reinvent 2017 — Werner Vogels

자연스럽게도, 저는 Serverless가 그런 트렌드의 미래라고 생각합니다. 그게 AWS같은 Cloud Vendor들이 막대한 투자를 하고 있는 이유겠고, 
제가 외부에서 Serverless의 현재 한계를 지적하시는 분들을 만날때마다 (AWS Lambda에서 5분이 넘어가는 작업은 어떻게 돌리죠? / 메모리를 많이 쓰는 작업은 어떻게 돌리죠?) 자신있게 “시간이 지나면 다 해결 될 겁니다” 라고 말할수 있는 이유기도 합니다.
(실제로, Lambda는 최근 몇년간 최대 실행시간은 5배, 최대 메모리 크기도 5배 늘어났습니다;)

물론 모든 Application이 다 무조건 Serverless에서 돌아가게 되는 미래를 상상하는건 아닙니다. 아직도 3G폰을 쓰는 사람이 있듯이 분명 특정 상황에서는 기존의 Container나 bare metal이 더 우위를 가지는 상황이 있겠지만, 대부분의 범용적인 Application들은 Serverless에서 돌아가는게 너무 당연한 미래. 저희 팀이 시스템을 Serverless로 옮기자고 했을때 거기에 베팅한거겠죠.

끝으로

원칙만 지키면 간단한것처럼 쓰긴 했지만, 기술 선택과 도입, 당연히 어렵습니다; 
공식 외운다고 선형대수 문제 다 풀수 있는게 아니듯이, 각자의 상황과 문맥에 맞춰 각자의 답을 찾는 노력을 들이는게 중요한 것 같습니다. 그렇게 노력을 들이고 나면 심지어 잘못된 선택을 하더라도, 우리가 뭘 놓쳤었는지 나중에 돌이켜 볼 수는 있잖아요?

사실 제가 정말 아쉬운건, 그 “노력” 을 들이는걸 귀찮아 하는 사람들이 많다는 겁니다.

인간은 생각보다 환경에 매우 취약합니다. 시간이 지나서 환경에 동화되면, 자연스럽게 그 환경을 비판할수 있는 사고 자체를 피하게 됩니다. 환경에 동화되는 과정은 곧 우리의 뇌가 엄청난 가소성(plasticity) 을 발휘해 우리의 사고 방식 자체를 바꾸는 과정이기 때문입니다.
잘못된 기술을 대충 선택하는건, 마치 “앞으로 우리는 미래도 없고 생산성도 프로젝트가 커지면 커질수록 낮아지는 방식으로 일할꺼야” 라고 우리 팀원들의 뇌의 작동방식을 바꾸는것과 마찬가지인거죠. (물론 그렇게 말하려는게 목적이라면 얼마든지 대충해도 됩니다^^)

여튼, 기술 선택하고 도입하는거, 팀이나 회사에서는 정말 중요한 문제입니다. 좀더 많은 사람들이 이걸 이해하고 고민하는 분위기가 됐으면 좋겠네요.

빙글에서는 이런 문제를 함께 풀어갈 사람을 언제나 기다립니다.

— revise,

  1. https://twitter.com/jeffbarr/status/1050164028188721153?s=21 글을 쓴뒤 3달 뒤에 AWS Lambda의 timeout이 5분에서 15분으로 3배 늘어났습니다.