페이스북은 어떻게 개발하고 배포할까?

전세계에서 재능있는 엔지니어들이 몰려있다는 실리콘밸리 기업들 중에서도 페이스북은 놀라운 개발생산성을 보여줍니다. 개발자 한명이 대응해야 하는 액티브 사용자 수가 구글의 5배, 아마존의 10배가 넘습니다. 페이스북의 개발 프랙티스는 많은 기업들에게 연구의 대상이자 롤 모델이 되기도 합니다. 2013년 2월 IEEE에 “Development and Deployment at Facebook“라는 논문을 통해 페이스북에서의 개발과 배포 방법을 살펴볼 수 있습니다. 3명의 저자가 쓴 글인데 그중 한명은 XP의 창시자로 유명한 Kent Beck입니다. 2013년부터 페이스북에서 근무하고 있습니다.

여담으로 Kent Beck이 2013년 페이스북 채용 인터뷰 과정에서 8 Queens라는 체스전략퍼즐을 풀기 위해 25년 전의 Prolog 자연언어처리 기술까지 끄집어내느냐고 진땀을 흘렸다는군요. 페이스북 내부 채용팀의 능력과 공정성을 칭찬하면서 자기가 채용팀에 이런 얘기를 할 줄은 몰랐다고 합니다.

1
[개발자당 활성 사용자 수, 자료: Facebook-Moving-Fast-at-Scale] 

1. Perpetual Development

페이스북에는 완성이라는 것이 없습니다. 다른 인터넷 기반 기업들처럼 페이스북도 지속적인 개발 모드로 끊임없이 새로운 기능을 개발하여 사용자에게 제공해야 합니다. 지속적 개발을 위해 성장과 빠른 배포는 엔지니어가 반드시 해결해야만 하는 과제라고 할 수 있습니다.

2
 [개발주기의 시간척도]

폭포수 모델은 전체 개발사이클을 통해 최종 제품을 한번에 전달하는 것이 목적이라면, 애자일에서는 주단위로 릴리즈 혹은 점진적 개발을 가져갑니다. 페이스북은 제품을 매일 릴리즈하며 빠르게 개발과 배포를 수행하며, 지속적 배포는 정말 하루에도 수십번씩 프러덕션에 반영하는 것입니다. (delivery는 운영서버에 릴리즈 대기상태로 만들어 놓는 것으로, deployment는 실제 사용자에게 서비스를 사용할 수 있도록 서비스에 반영하는 것으로 구분) 
지속적 개발의 직접적인 결과는 소프트웨어의 성장에 있습니다. 현재 페이스북의 프론트엔드 코드베이스는 천만라인이 넘어가고 (실제코드로 코멘트와 공백 제외) 그중에서 PHP가 8백5십만 라인 정도가 됩니다. 아래 페이스북의 코드베이스증가율을 살펴보면, 코드베이스 규모가 해마다가파르게 성장하는 것을 볼 수 있습니다. 소프트웨어의 크기와 복잡도가 증가하면 성장율이 둔화된다는 Brooks’s Law에 속하지 않는 모습니다. 
3
  [페이스북 개발 성장율] 
지속적 배포(Continuous Deployment)를 통해 페이스북은 어제 밤에 아이디어를 얻고 오늘 아침에 코딩하고 오후에 서비스에 반영하여 데이타를 내일 얻는 것이 가능합니다. 일반 개발 회사에서 일년동안 얻을 경험을 페이스북에서는 몇 주만에 얻을 수 있다는 얘기입니다. 또한 지속적 배포는 A/B 테스팅을 통해서 라이브 실험을 수행합니다. 두 사용자 그룹에서 새로운 기능을 보여주고 사용자 행동의 변화를 비교할 수 있도록 만들어 줍니다. 이를 통해 엔지니어들은 어떤 것이 먹히고 버려야할지를 즉시 확인해 볼 수 있습니다. 
 
4
 
지속적 배포는 제품관점에서도 잦은 배포를 통해 신규 코드의 량이 제한됨으로써 위험을 줄이고 결함수정을 용이하게 만들어 주는 효과가 있습니다. 페이스북에 신규입사자들은 6주간의 부트캠프을 통해 실서비스에 코드를 커밋을 가능한 빨리하도록 독려하는데, 2주차에 가장 많은 코드가 커밋되는 것을 볼 수 있습니다. 
5 
 [페이스북 부트캠프에서의 첫번째 코드커밋 분포]
 
빠른 배포가 코드베이스에 큰 변화를 초래하는 기능 개발과는 어울릴 것 같지 않지만, 큰 기능 개발이라는 것도 작고 안전한 절차로 구분하여 쪼개면 가능합니다. 또한 페이스북은 Gatekeeper를 통해서 사용자가 보게되는 코드의 기능들 통제함으로써 개발자가 신규 기능을 최종 사용자에게 바로 노출시키지 않고 배포를 점진적으로 증가시킬 수 있도록 만들어 줍니다. (dark release로 config flag를 통해 작은 규모의 사용자에게 신규기능을 노출하여 검증하고 릴리즈 확장)
 
모든 페이스북 프론트엔드 개발자는 단일 코드베이스에서 작업을 합니다. 따라서 코드를 따로 브랜치했다가 트렁크(trunk)에 모아 통합하는 수고를 하지 않아 빠른 개발이 가능해집니다. 이에 따른 장단점이 있겠지만 이런 대규모 코드베이스를 하나로 가져간다는 것은 비지니스 특성과 엄격한 엔지니어링 기반이 뒷받침되지 않으면 어렵겠죠. 일반적으로 지속적 배포에서는 통합의 비용과 복잡함을 증가시키므로 코드브랜치 대신에 UI 상에서 기능을 온/오프시키는 feature toggles이나 아키텍처에서의 변경이 필요하면 branch by abstraction을 사용할 것을 권장합니다. 페이스북 개발자는 깃(Git)을 통해 자신의 개발코드를 로컬에서 관리하고, 릴리즈할 안정적 코드는 서브버전(subversion)의 중앙 리파지토리에 커밋하게 됩니다. 
 
페이스북 엔지니어들은 주당 평균 2~3회 정도 커밋을 하는데 커밋 간격은 몇 시간 이내입니다. 커밋 성공율은 횟수가 늘어남에 따라 극격하게 줄어들며 주 10회 이상 커밋을 하는 엔지니어는 거의 없습니다. 최적의 배포 사이클은 배포 비용, 에러 발생 확률과 처리비용, 점진적 효익의 가치, 엔지니어의 기술과 문화 등 고려할 사항들이 많으며 페이스북와 같이 개인사생활을 다루는 경우 침해 우려도 있어 일간, 주간 배포를 섞어서 사용하고 있습니다. 
 
6 
 
[페이스북 코 드커밋 주기]
 
2. Pushing New Features

푸시 프로세스는 혁신 수준을 어느 통제 수준에서 가져갈 것인 균형을 잡아야 합니다. 신규 소프트웨어 배포의 확장은 보다 많은 엔지니어, 보다 많은 코드, 보다 많은 사용자라는 관점에서 고려할 위험들이 많습니다. 위험을 없애는 것은 불가능하기 때문에 감시 기능을 중요한 부문에 보다 집중하게 되고 일간 및 주간 푸시에 따라서도 달라집니다. 주간 푸시는 기본이 되고 수천가지 변경사항을 포함하므로 일요일 오후에 서브버전 중앙 리파지토리에 코드들이 모여 릴리즈 엔지니어가 진행합니다. 수만개의 회귀테스트 (결함과 성능)를 포함하는 자동화 테스트를 거치고나면 최신 빌드의 일부에 포함되고 페이스북 직원들이 먼저 사용하고 이후 푸시는 화요일 오후에 이루어집니다.

릴리즈 엔지니어는 이전 성과에 기반하여 push karma로 엔지니어를 지명하는데 엔지니어가 나쁜 업보(문제를 자주 야기시키는 경향)를 갖고 있으면 푸시에 포함되기 전에 보다 엄격한 감독을 받게 됩니다. 코드 리뷰 과정에서 토론된 내용이나 코드 변화의 규모에 따라서도 얼마나 검토가 이루어질지 고려됩니다.

릴리즈 엔지니어는 작은 주기의 푸시를 하루 2번씩 수행합니다. 주간 혹은 일간 푸시에 포함되는 코드들은 개별 단위테스트와 코드리뷰를 반드시 거져야 합니다. 페이스북에서 코드리뷰는 중심적 위치를 차지하고 있는데, 모든 라인은 다른 엔지니어들에 의해 반드시 검토되어야 합니다.

Phabricator 코드 리뷰 도구 (http://phabricator.org)와 코드 테스트 자동화 도구 (사용자 인터페이스 포함) Watir (http://watir.com/)와 Selenium (https://code.google.com/p/selenium/)을 활용합니다. 아울러 페이스북을 사내에서 활발하게 사용하면서 모든 직원들이 발견하는 모든 버그들을 바로 리포트하고 있고 있습니다.

 
7 
[Phabricator 코드 리뷰 도구]
8 
[ Watir UI  테스팅 자동화 도구 ]
 
9
[ Selenium 테스팅 프레임워크: Unit, UI , 통합 테스팅 지원 ]
 
아울러  Perflab와 같은 성능테스팅 솔루션을 활용하여 엔지니어가 단시간에 해결할 수 없는 경우 변경된 코드를 서비스에서 제거하거나 다음번 푸시로 연기시켜 엔지니어가 문제를 해결할 수 있도록 활용합니다. 엔지니어들은 작은 성능 상의 이슈라도 지속적으로 관찰하고 문제가 축적되지 않도록 해결해야 합니다. 이런 이슈들이 방치되면 급격하게 용량과 성능 문제를 야기시키기 때문입니다. 
 
10 
[ Perflab 솔루션 홈페이지 ]
 
페이스북에서는 스테이지별 푸시가 이루어지는데, 1차는 H1의 내부 엔지니어가 사용하는 서버에서 테스트를 거친다음 
2차는 H2로 작은 사용자 그룹을 대상으로 배포하고 문제가 없으면 전체 사용자가 사용하는 H3서버로 배포가 이루어집니다. 보통 배포되는 실행 파일 사이즈가 1.5 GB에 달하기 때문에 (웹서버와 컴파일된 페이스북 어플리케이션 포함) 전세계 4군데 장소에 서버 클러스터를 두고 배포가 이루어집니다. 모든 코드와 데이타는 BitTorrent를 통해 모든 서버들에 전파되는데 대략 20분 정도가 소요됩니다. 
 
릴리즈 시점에 반드시 배포할 기능을 만든 개발자가 대기해야 하는데 담당 개발자가 자리를 비우면 해당 푸시에서 그사람의 코드는 제외됩니다. 아울러 Claspin과 같은 내부 모니터링 도구를 통해 배포 후 사용자들이 기능상에 문제점이 없는지를 모니터링합니다. 
 
 
3. Personal Responsibility
 
페이스북에는 대략 1,000명의 개발자와 3명의 릴리즈 엔지니어가 일일 주간 푸시를 관리하며 QA팀 혹은 테스트팀이 별도로 존재하지 않습니다. 일반적으로 개발, QA, 운영을 구분함으로써 서로에게 책임을 떠넘기는 개발회사와 달리 페이스북 엔지니어는 자신의 코드에 테스트 코드를 짜고 자동화된 회귀테스트를 통과시켜야 합니다. 개발자들이 QA와 운영까지 지원해야하는Devops의 문화를 갖고 있습니다. 개발자는 자신의 코드가 결함없이 운영되도록 책임을 집니다. 즉, 개인이 책임을 지는 문화가 깔려 있습니다. 
11
[페이스북 엔지니어 조직: DevOps]
 
페이스북에서는 소수의 개발자들이 대부분의 파일을 처리하다보니 헤비 테일 분포도를 볼 수 있습니다. 3분의 1의 소스파일을 한명의 엔지니어가 수정하고, 4분의 1정도를 2명의 개발자가 처리합니다. 7명 이상의 엔지니어가 수정하는 파일은 10% 정도에 불과하군요. 
12
[개발자당 파일처리 분포]
 
페이스북에서는 사내협업과 아울러 경쟁도 유도합니다. PHP 성능이 인프라 비용의 가장 큰 요소로 떠오르자, 엔지니어들이 3가지의 다른 솔루션을 제시했고, 각 팀마다 병행으로 개발된 솔루션 중에서 최종적으로 가장 나은 대안 (HipHop compiler: https://github.com/facebook/hhvm, 오픈소스로 php 성능 개선을 위해서 JIT 컴파일 접근방법을 사용합니다)만 선택되고 나머지는 바로 폐기되었습니다. 페이스북은 엔지니어가 스스로 주도하는 문화라서 부트캠프에서 코드베이스, 사내문화, 프로세스 등을 배우고 나면 신입직원은 자기가 일할 팀을 본인이 선택합니다.

혁신을 위해서 구글이 개발자의 20%시간을 자신의 프로젝트에 쏟게하는 반면 페이스북은 해카톤(hackathons)을 자주 개최합니다. 하루종일 진행되는 해카톤에는 엔지니어뿐만 아니라 사내 직원들이 모두 참여할 수 있습니다. 페이스북의 Tlimeline, Chat, Video, HipHop 등이 모두 해카톤을 통해 나온 결과물들입니다.

13
[페이스북 주중 커밋 분포]  
 
페이스북 커밋분포를 보면 주중에는 화요일, 일과중에서는 3시때가 가장 높습니다. 점심 시간에도 여전히 많은 커밋이 이루어지고, 저녁 8시 이후로는 거의 커밋이 이루어지지 않습니다. 
 
 
4. 정리
 
페이스북의 개발과 배포 프랙티스에 대하여 몇가지로 정리해보면 다음과 같습니다. 
  • 최종적으로 잘 정의된 제품을 달성하기 위한 구체적 계획은 만들지 않는다. 
  • 모든 엔지니어는 브랜치나 머지없이 하나의 공통된 코드기반에서 작업한다. 
  • 테스팅을 책임지는 별도의 QA 조직은 없다.
  • 매일 하루 2회 신규 코드를 릴리즈한다. 
  • 엔지니어가 무엇을 할지 스스로 결정한다. 
  • 실패에 대한 잘못을 묻지 않는다. 
 
아래 페이스북의 개발과 배포 프로세스에서 알 수 있듯이 자신의 환경에 적합한 개발 프로세스를 최적화하고 자동화하여 사용합니다. 
  • 제품이 미리 정의되지는 않지만 빠른 속도로 반드시 지속적으로 진화하여야 한다. 
  • 엔지니어는 도메인에서 직접 경험해야하고 사용자들이 어떤 것을 좋아하는지 파악하기 위해 테스트 과정을 주도합니다. 
  • 개인적 책임에 따라 엔지니어는 자신이 개발된 코드의 품질을 책임져야 합니다. 
  • 사용자에 대한 테스팅은 범위를 정해 수행하고 가장 정확하고 빠른 피드백을 제공해야 합니다. 
  • 누구의 잘못인지 책임을 따지는 것보다 경험을 통해 배우는 것이 가장 중요하고 이롭습니다. 

14

 [페이스북의 개발과 배포 프로세스]
페이스북 개발문화에서 매우  흥미로운 점은 개인적 책임감이 전문화 (QA, 테스트, 운영팀 구분 및 특화), 방법론, 엄격한 절차 등을 대치했다는 점입니다. 전체 시스템을 대한 책임감을 기꺼이 지려고 하는 엔지니어 조직에서 비난이나 자기보호같은 행동들이 보이지 않는다는 점입니다.
 
글 : 황순삼
원문 : http://swprocess.egloos.com/3009704
 
 
%d bloggers like this: