1년 반 전쯤에 스튜디오 전체 인원을 대상으로 이메일을 쓴 글이다. 내가 무슨 생각을 하고 어떻게 일을 했는지 기억을 되새기는 차원에서 회사 정보는 지우고 일반적인 내용만 남겨서 기록한다. 여기 나온 기술 스택은 구인공고 등을 통해 외부에 공개되었다.
이 프로젝트는 소수의 인원으로 시작했고 그 기간이 꽤 깁니다. 그런 까닭에 기술 선정 과정에 참여한 사람도 사실상 저와 Jane Doe 뿐입니다. 그 이후에 도입된 일부 기술에서는 다른 사람도 참여했고 가끔 이런저런 이야기를 나누다 보면 과거의 결정 과정을 공유하기도 하지만 전체 그림을 알기에는 역부족일 겁니다. 애초에는 이런 문제를 해소하기 위해 워크샵/세미나를 열기로 했지만 뜻대로 되지 않았습니다. 그래서 지금부터 초기에 어떤 기술을 왜 선택했는지를 이 글을 통해 설명하겠습니다(주요 기술만 다루고 나머지 기술에 대해서는 추후에 알아볼 기회를 갖겠습니다). 이는 비단 개발자를 위한 노력이 아닙니다. 다른 분들도 이 글을 통해 이 팀이 추구하는 바가 무엇인지 이해하는 기회가 될 것입니다.
Spring Framework
여러분이 생각하는 Java 소스코드의 대부분을 이루는 뼈대입니다. 이 회사는 윈도우 위에서 작동하는 C#을 주력으로 사용하던 중이었고 지금도 C#이 차지하는 비중이 큽니다. 그래서 Java를 최신 기술로 생각하기도 하는데 이는 회사 밖의 인식과는 완전히 다릅니다. Java는 C#보다 오래됐고 매우 보수적인 언어입니다. 신기술이라는 측면에서는 C#이 월등히 앞서 있고 여러분이 게임 개발 조직의 프로그래머에게 Java로 넘어오지 않겠냐고 하면 “Java는 너무 불편해서 싫어요”라는 대답을 듣게 될 겁니다(실제 회의 때 들은 발언입니다).
프로젝트 런칭 시점에는 앞서 언급한 요소, 그러니까
- C# 이 사실상 회사의 공통 기술이고
- 프로그래머가 좋아하는 기능이 매우 많은
상황이었습니다. 그럼에도 불구하고 Java 기반의 솔루션을 선택한 데에는 전 직장에서의 경험이 크게 영향을 끼쳤습니다.
- Java 기반의 오픈소스가 매우 많습니다. XXX 같은 대형 회사는 in-house에서 거의 모든 걸 개발할 인력과 자원이 있습니다만 사업 초기인 우리는 그럴 여력이 없고 가급적 외부의 자원을 큰 비용 들이지 않고 끌어다 써서 신속하게 개발해야 했습니다. Java는 그러기에 적절한 환경입니다(실제로는 XXX 조차도 오픈소스 프로젝트를 가져와서 개선해서 쓰곤 합니다). C#의 경우에는 Java에 비해 소위 오픈소스 생태계가 빈약합니다. Microsoft가 사업 정책을 바꿀 때마다 기존 오픈소스 프로젝트가 쓸모없게 되는 일이 여러 번 반복된 탓입니다.
-
Spring Framework는 분업하기 매우 좋은 구조입니다. 이런 강점은 전자정부 프레임워크로 채택 이유 중 하나이기도 합니다. 프로젝트 구성원이 적을 때는 잘 모르지만 규모가 커질수록 하나의 소스코드를 두고 여러 사람이 붙게 되어 혼란이 일어납니다. 백엔드 개발자는 이미 익숙해져서 이 프레임워크가 얼마나 분업과 협업에 좋은지 깨닫기 힘들 수도 있습니다. 그러나 여러분이 다른 솔루션을 선택하면 더 재미있을지는 몰라도 이만큼 일을 쉽게 쪼개 가져가기는 힘들다는 점을 알게 되실 겁니다.
나쁜 표현을 빌리자면 이 프레임워크는 소위 “공장”을 만들기에 최적화됐습니다. SI 등 외주 업무를 맡아본 분은 충분히 이해하실 겁니다. 물론 여러분은 “설계자”이지 공장 직원은 아닙니다. 그 점도 아셨으면 합니다.
-
Spring Framework는 매우 오랜 기간에 걸쳐 철저히 검증된 솔루션입니다. 더 재밌고 흥미로운 프레임워크는 시장에 많습니다만 프로젝트 초기에는 결정해야 할 이슈가 충분히 넘쳤고 주력 프레임워크 선정에서부터 모험을 할 생각은 없었습니다.
CentOS
CentOS는 리눅스의 한 종류입니다. 우선은 Windows가 아닌 Linux를 선택한 이유부터 설명합니다.
- 라이선스 비용이 안 나갑니다. 우리는 항상 미래를 보고 그림을 그립니다. 근 미래에 대규모 서비스로 발전하게 되면 운영체제 비용도 우습게 볼 문제는 아닙니다. 하지만 이것은 기술 선정의 주된 요소는 아닙니다. 그때가 오면 어차피 회사는 이 정도 비용을 부담하는데 아무런 문제도 없을 겁니다.
- 플랫폼이 성장해나갈 때 서비스를 쉽게 확장해나가려면 단일 머신으로 서비스를 지탱하려고 하면 안 됩니다. 어느 정도 규모까지는 더 좋은 머신으로 더 많은 사용자를 받아들이는 구조가 편하고 쉽습니다. 하지만 우리의 목표는 그것보다는 훨씬 크고 그런 목표를 달성하기 위해서는 최소한 수십, 수백 대의 머신으로 사용자를 나눠 받는 구조로 가야 합니다. 이런 걸 보통 수평적 아키텍처라 합니다.
이런 구조로 가기 위해서는 자동화가 필수입니다. 그런데 안타깝게도 윈도우 기반에서는 자동화 솔루션이 생각보다 많지 않습니다. 저는 윈도우 기반의 빌드 자동화 등으로 여러 차례 컨퍼런스에서 발표하고 칼럼도 썼습니다. 그만큼 윈도우를 좋아합니다. 하지만 안타깝게도 윈도우에서 자동화란 꽤나 버거운 과업입니다. 어느 시점이 되면 필요한 도구를 구하거나 살 수 없어서 in-house 개발을 하게 됩니다. 설사 인력과 돈이 있더라도 in-house 개발에는 시간이 소요됩니다. 물론 우리는 이 셋이 모두 부족한 상황입니다.
그에 비해 리눅스는 얼핏 복잡하고 다루기 힘들어 보이지만 최소한 우리가 필요로 하는 도구를 모두 손쉽게 구할 수 있습니다. 우리가 할 일은 솔루션을 찾고 공부하고 적용하는 일 뿐입니다. 공부하는 게 in-house 개발에 시간을 쏟는 것보다는 훨씬 자원이 절약됩니다.
자, 이제 리눅스를 선택한 이유는 설명했습니다. 이번에는 그 중에서도 왜 굳이 CentOS를 설명합니다. 이유는 매우 간단합니다.
- CentOS의 상용 버전인 RedHat이 제공하는 서비스가 필요하지 않은 시점이었습니다.
- 이미 카카오톡 같은 대형 서비스에서 CentOS로 안정적인 서비스를 구축했습니다.
- 보안 측면에서 매우 평판이 좋습니다.
- 이 외의 다른 요소는 검토하지 않았습니다.
MySQL
실은 MySQL의 변종이라 할 MariaDB를 씁니다만 설명을 쉽게 하기 위해 잘 알려진 MySQL이라고 합니다. 운영체제를 Linux로 선택한 시점에 우리가 선택할만한 데이터베이스는 다음과 같이 압축됩니다.
- Oracle
- MySQL
- PostgreSQL
오라클은 매우 비쌉니다. 그만큼 뛰어나기 때문에 쓰고 싶었지만 서비스가 커질수록 비용도 천문학적으로 증가할 게 뻔해서 포기했습니다. PostgreSQL은 후발주자인만큼 아직 성공사례가 많지 않습니다. 근래에는 조금씩 점유율을 높혀가는데 아직은 더 지켜봐야 합니다.
결론적으로 그다지 뭔가를 고를 여지가 없었습니다. 다른 회사도 마찬가지여서 이런 요소 때문에 대규모 웹 서비스를 제공하는 회사는 대부분 MySQL을 주력 데이터베이스로 사용합니다.
Redis
Redis라고 하는 솔루션은 여러 가지 명칭으로 불립니다.
- in-memory 데이터베이스
- Message Queue
- Cache Service
비기술자라면 그냥 임시 저장창고, 물류 센터 정도로 생각하면 편합니다. 이 솔루션을 선택할 당시에는 이 기술이 국내에 보급될 무렵이었고 아직 일부에선 최신 기술로 인식하기도 했습니다. 그리고 Redis를 대체할 수 있는 대안도 여럿 있었습니다. 예를 들면,
- Message Queue: ActiveMQ, RabbitMQ 등
- Cache: memcached
그럼에도 불구하고 Redis를 선택한 이유는
- Message Queue와 Cache 둘 다 필요한데 우리가 다뤄야 하는 기술 범위를 늘리기 싫었습니다. 그만큼 더 공부해야 하고 운영시에도 더 많은 위험 요소를 계산해 넣어야 하는 상황은 피하고 싶습니다.
- Redis를 선정할 무렵에 때맞춰 Line 등 초대형 서비스에서 Redis를 광범위하게 적용해서 효과를 본 사례가 많이 발표됐습니다. 1년이 넘게 사고가 나지 않을 정도로 매우 안정적이고 빠르며 기능이 다양하다는 점에서 Redis가 아닌 다른 솔루션을 굳이 알아볼 필요가 없었습니다.
- Redis는 AWS 등 다양한 상용 서비스에서 지원합니다.
- 기술 문서와 사례가 충분히 많습니다.
참고. 단순 캐시 서비스로는 memcached가 더 나은 점도 있습니다. 먼 미래에는 용도 별로 솔루션을 나누게 될지도 모릅니다.
Puppet
Puppet은 인프라 자동화 솔루션입니다. 말이 거창한데 쉽게 생각하면 각 머신에 어떤 프로그램을 설치하고 어떻게 설정할지 등을 프로그래밍으로 제어합니다. 과거에는 패치 등 일상적인 업무를 할 때마다 개발자나 시스템 관리자가 각 서버에 접속해서 뭔가 설치하고 확인하고 이를 문서로 남기곤 했습니다. 그리고 여전히 그런 회사가 많습니다. 하지만 이는 앞서 언급한 수평적 아키텍처에서는 좋지 않습니다. 값비싼 서버 2대로 할 일을 값싼 서버 6대로 처리하게 되므로 서비스가 커질수록 관리 비용이 증가합니다. 그러므로 어떤 식으로든 자동화는 필수입니다. 자동화는
- 서비스 관리를 중앙집중적으로 바꾸고
- 귀한 내부 인력이 관리 업무에 시간을 가급적 적게 쓰고 주력 업무에 집중하고
- 사람의 실수를 줄이고
- 문서화하지 않은 부분이 공백으로 남아 나중에 업무 인계하기 힘들게 되거나 시스템 장애를 처리하는데 애를 먹는 일을 방지하는데
도움이 됩니다. 실제로 2012년 무렵으로 기억합니다만 그 당시 페이스북은 MySQL 데이터베이스가 2천대가 넘었는데도 DBA는 불과 두 명에 불과했습니다. 이는 인프라 자동화에 투자한 결과입니다.
이런 인프라 자동화를 돕는 솔루션은 최근에 하나 둘 등장했습니다. 대표적으로
- Puppet
- Chef
- Ansible
사내에 인프라 자동화 전문가가 없었기에(사실은 전세계 어디나 사람이 부족합니다) 우리만의 기준으로 골랐습니다. 그 기준은
- 참고할 문서가 많은가?
- 쉬워 보이나?
- 쓰는 곳이 많은가?
이러한 기준에서 Puppet과 Chef가 만족스러워 보였고 처음에 골라서 시도한 Puppet으로 결과물이 빨리 나와서 Chef는 테스트조차 하지 않았습니다. 사실 AWS는 Chef를 곳곳에서 쓰기 때문에 Chef를 선택했으면 공부할 게 줄고 시스템 통합을 좀더 빨리하는데 도움이 됐을지도 모르겠습니다. 이 부분에 대해서는 확신은 하지 못합니다. 다만 현재 수준에서 퍼펫이 원하는 결과를 뽑아내는데 나쁘지 않은 것만은 분명합니다.
아마도 팀의 프로그래머조차도 절반 이상은 이 기술을 깊게 접해본 적이 아직 없을 겁니다. 현재까지는 제가 90% 정도의 업무를 처리하고 일부만 몇몇 분이 참여하는 상황입니다. 가급적 짜증나고 귀찮은 인프라 업무를 제가 가져가려고 했기 때문에 이렇게 됐는데 앞으로는 모든 프로그래머가 이 기술을 전수받게 될 겁니다.