다른 많은 기업과 마찬가지로, 데이터 스타트업 세그먼트(Segment) 역시 오래된 인프라스트럭처로 인한 문제 때문에 마이크로서비스(microservice)로 눈을 돌렸다. 하지만 곧 단일 구조(monolithic) 아키텍처로 돌아오지 않으면 해결할 수 없는 복잡한 문제가 있다는 것을 깨달았다.
세그먼트의 주 고객은 타임(Time), IBM, 리바이스(Levi’s) 등이다. 이들 기업의 모든 고객 데이터를 세일즈, 애널리틱스, 헬프데스크 등에 피딩하기 전에 한 지점에 모아 볼 수 있는 서비스를 제공한다.
세그먼트의 CTO이자 공동창립자인 캘빈 프렌치-오웬은 “처음에는 단일 API와 라이브러리를 제공하고 그들이 데이터를 보내오는 식의 개발자 우선 방식을 택했다. 우리가 데이터를 모아 구성한 후 이를 적절한 스키마로 정렬하고, 고객사가 사용하는 200여 가지 이상의 툴에 이 데이터를 보냈다. 여기서 툴이란 세일즈포스 같은 세일즈 툴 일수도 있고, 젠데스크(Zendesk) 같은 고객 관련 툴, 혹은 레드시프트(Redshift)나 빅쿼리(BigQuery)같은 데이터 웨어하우스 일수도 있다”라고 말했다.
세그먼트사는 전적으로 AWS에 의존하고 있으며, ECS(Elastic Container Service)가 관리하는 1만 6000개 컨테이너가 250여 가지 마이크로서비스를 제공한다.
세그먼트는 원래 단일 구조 아키텍처를 사용했다. API가 데이터를 처리해 싱글 큐(queue)에 포워딩하면 직원이 데이터를 읽고 이벤트를 모든 서버측 ‘목적지’, 그러니까 파트너 API에 선형 체인을 통해 전송했다. 그러나 이런 방식은 이내 문제를 발생시켰다. 툴에서 서버 에러를 반송할 때의 재시도가 큐와 만나 다른 이벤트와 뒤섞이는 것이다. 이로 인해 파이프가 막히고 성능 장애로 이어졌다.
세그먼트의 소프트웨어 엔지니어 알렉스 누난은 “단일 구조에서 탈피해 마이크로서비스로 전환한 것도 이 때문이었다. 우리에게는 데이터를 수집하는 API와 라우터가 있고, 라우터는 이벤트를 목적지별 큐와 서비스로 라우팅했다. 이벤트가 발생하면 라우터가 ‘좋아, 이 이벤트는 구글 애널리틱스와 맥스 패널로 보내야겠어’라고 판단을 내리고 해당 이벤트의 카피를 2개 생성해 각각의 큐로 이를 보내는 식이었다”라고 말했다.
바람 잘 날 없었던 “마이크로서비스”의 세계
마이크로서비스 방식은 한동안 잘 돌아 가는 것처럼 보였다. 그러나 역시 문제가 발생했다. 누난의 표현을 빌리면 '마이크로서비스 세계의 더 깊숙한 곳에서 개별 파트너의 API 목적지와 서비스에 대한 새로운 타입의 큐가 형성됨'에 따라 발생했다. 결국 개발자는 모든 업데이트를 수동으로 처리해야 했고 어떤 업데이트 버전이 어디의 어느 리포(repo)에 있는지를 일일이 기억하는 것이 한계에 다다랐다.
누난은 “시간이 갈수록 개발자의 생산성이 급격히 저하됐다. 모든 것이 각기 다른 별개의 큐와 별개의 서비스, 그리고 자체적인 리포에 있었기 때문이다. 우리는 통합을 유지, 생성하기 위해 공유 라이브러리를 만들었지만 이것을 전개할 좋은 방법도, 또 제대로 테스팅할 여건도 안됐다. 공유 라이브러리를 업데이트하기에는 시간도 자원도 부족했다. 결국 구글 애널리틱스 버전만 업데이트하는 식이 됐다. 모든 라이브러리가 서로 다른 업데이트 버전을 갖게 됐다"라고 말했다.
세그먼트 팀은 파트너 API가 각각 어느 라이브러리 버전에서 구동되는지 추적하고, 그 버전 간의 차이도 기억해야 했다. 누난은 “라이브러리 관리 업무 만으로도 개발자에게 너무 큰 부담이 됐다. 꾹 참고 서비스마다 하나하나 변경할 수도 있지만 그러려면 수 일이 걸렸고, 특히 서비스 하나 하나를 테스트하고 전개하는데 여러 명의 개발자가 필요하게 됐다. 이것이 너무 큰 부담으로 작용한 끝에 결국 꼭 필요한 변경사항조차도 적용하지 않게 되는 일까지 발생했다. 모든 서비스에 아주 작은 변경사항만 적용하기 위해서도 팀 전체가 달려 들어 일주일 이상 소모해야만 했다”라고 말했다.
세그먼트의 직원은 이러한 큐를 처리하기 위해 수면 부족에 시달리는 것도 모자라, 성능 이슈에도 직면했다. 예를 들어 구글 애널리틱스와 같은 대규모 목적지의 경우 초당 수천 건에 달하는 이벤트를 처리하는 반면 하루에 수 건 이내의 이벤트만을 처리하는 곳도 있었다. 세그먼트 팀은 오토-스케일링 룰을 적용해 이러한 서비스의 수동 커스터마이징을 최소화 했지만 서비스마다 고유의 CPU 및 메모리 로드 패턴이 있었기 때문에 모든 통합에 같은 룰을 적용할 수는 없었다.
누난은 “하루에도 수십 번씩 쉴 새 없이 호출이 왔고, 직원이 일일이 개입해 이러한 서비스를 처리해야 했다. 이런 식으로 2년 넘게 마이크로서비스 방식을 이용한 결과 큐와 리포에 140여 가지 서비스를 갖게 됐지만 시스템 장애를 막는 데에만 모든 에너지를 쏟아도 역부족이었기에 그보다 더 건설적이거나 선제적인 어떤 노력도 할 수 없는 상황이었다. 이쯤 되자 한걸음 물러나 생각해 보지 않을 수 없었다. ‘대체 이 상황을 해결하려면 어떻게 해야 하지?’ 결국 인력을 추가해야 한다는 결론이 나왔지만, 그런 식으로 문제를 해결하고 싶지는 않았다”라고 말했다.
그러나 결국 세그먼트는 마이크로서비스 아키텍처가 지속 불가능하다는 결론에 다다랐다. 목적지를 추가할수록 성능 저하가 눈에 띄게 증가했고 이것은 ‘상당히 뚜렷한 경고 신호’였다. 누난은 “한창 마이크로서비스로 인한 광기가 극에 달했을 때 내가 세그먼트에 합류했다. 당시 이미 어떻게 하면 이 문제를 해결할 것인가에 대한 논의가 이루어지고 있었다”라고 말했다.
---------------------------------------------------------------
프로그래밍 인기기사
-> 개발자를 미치게 하는 10가지 프로그래밍 언어
-> 프로그래밍의 미래는? 9가지 예측
-> 21세기 개발자들을 괴롭히는 12가지 윤리적 딜레마
-> 상승가도 달리는 프로그래밍 언어 10선
-> '커피, 보석, 달 등에서 유래한' 프로그래밍 언어 이름 13
-> 개발자 경력에 '가산점' 될 6가지 새로운 언어
-> 프로그래머 생산성을 떨어뜨리는 15가지
-> 개발자들의 8가지 직업병, 혹시 당신도?
---------------------------------------------------------------
단일 구조로 돌아가다프로그래밍 인기기사
-> 개발자를 미치게 하는 10가지 프로그래밍 언어
-> 프로그래밍의 미래는? 9가지 예측
-> 21세기 개발자들을 괴롭히는 12가지 윤리적 딜레마
-> 상승가도 달리는 프로그래밍 언어 10선
-> '커피, 보석, 달 등에서 유래한' 프로그래밍 언어 이름 13
-> 개발자 경력에 '가산점' 될 6가지 새로운 언어
-> 프로그래머 생산성을 떨어뜨리는 15가지
-> 개발자들의 8가지 직업병, 혹시 당신도?
---------------------------------------------------------------
세그먼트 팀은 마이크로서비스를 어떻게 다시 하나의 거대한 시스템으로 재설계할 것인지 방법을 찾아야 했다. 이른바 ‘신(新) 단일구조’로의 이행이었다. 결국 당시 세그먼트가 진행 중이던 ‘센트리퓨즈(Centrifuge)’ 인프라스트럭처 프로젝트를 통해 새로운 단일 구조로 이행하기로 결정됐다. 센트리퓨즈는 세그먼트 비즈니스의 핵심이라 할 수 있는 단일 이벤트 딜리버리 시스템이다.
프렌치-오웬은 “센트리퓨즈는 큐를 생성하고 실패가 발생했을 때 트래픽을 흡수하기 위한 시스템이다. 이 시스템 덕분에 우리는 여러 코드를 한 장소에 통합하고, 이를 통해 두 마리 토끼를 잡는 전략을 취하기로 했다"라고 말했다.
이를 위해 먼저 모든 목적지 코드를 하나의 리포로 통합했다. 하나의 리포에 모든 종속 항목과 테스트를 합병하는 것이었다. 서비스가 하나뿐이므로 논리적으로 당연했다. 그러나 이 과정이 대단히 복잡하고 머리 아픈 과정이었다. 누난은 "120개가 넘는 고유의 종속 항목들 각각에 대해 우리는 모든 목적지에 대한 하나의 버전을 만드는 데 집중했다. 또한 목적지를 이동하면서 사용 중인 종속 항목을 확인하고 이들을 최신 버전으로 업데이트했다. 또 목적지의 새로운 버전에서 생긴 부분을 바로 바로 수정했다"라고 말했다.
이렇게 일관성을 확보한 결과 코드베이스를 어지럽히던 혼란이 상당 부분 해소되었다. 세그먼트 팀은 또한 빠르고 쉽게 모든 목적지 테스트를 한 번에 진행할 수 있는 테스트 스위트는 개발했다. 지나치게 길고 복잡한 테스트 과정 역시 업데이트를 방해하던 주요 요소 중 하나였기 때문이다.
이처럼 목적지 코드를 단일 리포로 이동시켜 단일 서비스로 통합하자 곧바로 개발자 생산성 증대라는 성과로 이어졌다. 서비스 전개 시간도 수 분 이내로 단축됐다. 누난은 “인프라스트럭처의 가장 큰 부분을 재설계해야 했기 때문에 단일 구조로의 전환에는 상당한 시간이 걸렸다. 당연한 일이었다. 하지만 적어도 예전처럼 계속해서 고객 지원 요청이 들어오거나 하는 일은 없다. 모두가 수면 부족에 시달리지 않을 수 있게 됐다. 모든 것을 하나의 리포로 통합하고 나니 관리도 쉬워졌다”라고 말했다.
이어 "이제 공유 라이브러리에 업데이트를 생성하고 싶을 때, 엔지니어 1명이 한 시간만 투자해 테스트하고 전개할 수 있다. 우리에게는 정말 획기적인 변화였다. 처음 마이크로서비스를 채택했을 때 당시 그런 선택을 할 만한 사정이 있었다고 생각한다. 당시 팀이 처한 상황이나 겪고 있던 성능 이슈를 고려하면 최고의 선택이었다. 그러나 시간이 지날수록 마이크로서비스의 장점은 사라지고 생산성과 성능만 잡아먹게 됐다. 그래서 다시 단일 구조로 돌아온 것이다"라고 말했다.
세그먼트 사가 다른 기업에 비해 처리하는 데이터 양에서 압도적으로 많긴 하지만 비슷한 불편을 겪는 다른 기업 역시 단일 구조로 돌아오는 것이 하나의 대안이 될 수 있다. 누난도 "그런 선택을 한다고 해도 전혀 놀라운 일이 아니다"라고 말했다.
단일 구조로 돌아온 후 나아진 건 세그먼트 사 직원의 워크-라이프 밸런스 뿐 만이 아니다. 고객 역시 훨씬 일관되고 안정적인 서비스를 누릴 수 있게 됐다. 프렌치-오웬은 “모든 서비스가 한 장소에, 단일 리포에 통합됨에 따라 추가된 변경 사항이 다음 번에도 모든 서비스에 똑같이 전개될 것이라는 확신을 가질 수 있게 됐다. 덕분에 고객 역시 서비스 별로 각기 다른 버전으로 인해 발생하는 혼란이나 비일관성을 더 이상 겪지 않아도 됐다"라고 말했다. ciokr@idg.co.kr
원문보기