brunch

You can make anything
by writing

C.S.Lewis

by 손주식 Jun 16. 2019

Uber의 머신러닝을 통한 용량 안전성 보장

Tech Review of Uber #1

Uber는 세계 최대의 승차 공유 서비스로, 2009년 창립되어 만 10년이 지난 현재 세계에서 가장 높은 가치를 지닌 스타트업 중 하나가 되었습니다. 우버는 교통과 관련된 유료 서비스를 제공하기 때문에 작은 시스템 장애만 일어나더라도 사용자 입장에서는 매우 큰 혼란이나 사고가 발생할 수 있을 텐데요. 전 세계 500개 이상의 도시에서 서비스를 제공하면서도 어떻게 이렇게 안정적으로 성장해올 수 있었을까요? 이런 Uber의 안정적인 서비스의 밑바탕이 되는 신뢰성 시스템의 일부가 지난 3월 Uber Engineering Blog에 공개되었습니다. 이 글은 해당 블로그 아티클을 리뷰한 것으로, 간단히 의역 및 번역을 한 뒤 중간중간 제 의견을 첨부해보았습니다. (검은색 글이 번역이고 파란색 글이 의견입니다.)

https://eng.uber.com/machine-learning-capacity-safety/




Uber의 신뢰성 공학 팀은 Uber의 다른 엔지니어들이 수천 개의 마이크로 서비스들을 대용량 환경에서도 안정적으로 운영할 수 있도록 도와주는 도구와 라이브러리, 인프라스트럭쳐를 만든다. 신뢰성 공학은 본질적으로 '평균 무고장 시간 (Mean Time Between Failures, MTBF)'에 영향을 주는 장애들을 능동적으로 예방하는 활동을 의미한다. 


Uber의 글로벌 모빌리티 플랫폼이 성장함에 따라, 마이크로 서비스들이 서로 호출하는 패턴도 글로벌 스케일로 커지고 또한 복잡해졌고, 각 개별 서비스들의 용량 요구사항을 예측하기도 어려워졌다. 서비스 단위의 용량 요구사항을 예측하지 못하면, 용량 부족으로 인한 장애가 발생할 수 있게 된다. 서비스를 실시간으로 운영해야 하는 상황인데, (직접적으로 사용자 경험에 영향을 주지는 않더라도 마이크로 서비스들의 기능 수준에서 발생하는) 용량 관련 장애들이 Uber의 전체 장애에서 꽤 큰 비중을 차지하게 되었다.


이런 장애들을 예방하기 위하여, Uber의 신뢰성 엔지니어들을 "용량 안전성"이라는 개념을 준수하게 되었다. 용량 안전성이란, 쉽게 말해 하나의 데이터센터에서 CPU나 메모리 등 자원 부족을 겪지 않고 동시에 운행 중인 라이더들을 과거 최대치 또는 90일 예측치만큼 버틸 수 있는 능력을 말한다. "지도 신뢰성 공학 팀"에서는 한 주나 한 달 동안 초당 요청 수, 응답 속도, CPU 사용률 등 핵심 서비스 지표들이 어떻게 변화할지 예측하는 자체 머신러닝 도구를 만들었다. 이 예측 도구를 활용하면, 개별 팀에서는 각 마이크로 서비스들의 특성을 고려한 정확한 용량 안전성 테스트를 수행할 수 있다. 


본 아티클에서는, Uber의 용량 안전성 개념을 정의하고 우리가 용량 안전성 예측 도구를 개발하기 위해 어떻게 머신러닝을 활용하였는지 소개할 것이다. 특히 부하 테스트 도구에서 이 예측을 믿을지 말지 판단하는데 활용하는 "신뢰성 점수"의 품질을 계산하는 부분을 주목하길 바란다.


Uber는 SRE를 담당하는 조직의 규모도 큰 편이고 역량도 뛰어난 기업 중 하나입니다. 단순히 고객 서비스의 개발에만 회사의 인재들을 투입하는 것이 아니라, 그 서비스들을 안정적으로 운영하고, 효율화하고, 더 발전시키기 위한 별도의 조직을 만들어 많은 비용을 투자하고 있다는 뜻인데요, 스타트업에서는 하기 힘든 결정이지만 Uber에는 이 문화가 잘 정착한 것으로 보입니다. 보통은 시스템의 주요 Metric 수집이나 저장까지는 플랫폼화 하더라도 그 데이터를 머신러닝으로 분석하여 미래 예측에 활용할 생각까지는 잘 못 하는 편이죠. 서비스 개발이 급하니까요. Uber의 경우, 워낙 장애가 크리티컬 한 분야이기도 하고, 또 기술인력들이 워낙 유능하고 노련해서 이런 좋은 문화가 만들어질 수 있었던 것 같습니다.


Uber의 용량 안전성


용량 안전성 측정을 위해, 일단 각 마이크로 서비스들은 모든 데이터센터에서 한꺼번에 장애가 발생하지는 않도록 올바르게 배치되어야 한다. 너무 적게 배치되는 경우 용량 부족을 겪을 수 있고, 너무 많이 배치하는 경우 해당 서비스의 상단이나 하단에 네트워크 관련 문제(connection 과다 등)를 일으킬 수 있다.


과거에, 우리 신뢰성 공학 팀에서는 핵심 운행 흐름 서비스의 용량 안전성을 보장하기 위한 플랫폼 단위 훈련을 진행했었다. 엔지니어들은 정해진 규모의 가상 운행 트래픽을 발생시키고 핵심 지표들을 모니터링했다. 플랫폼의 입구에 가까운 마이크로 서비스들을 모니터링하는 것뿐만 아니라, 최초의 부하와 연속된 호출 패턴이 어떻게 하단의 마이크로 서비스들의 성능에 영향을 미치는지도 흥미롭게 지켜보았다.


이런 플랫폼 단위의 접근 방식은 상당히 넓은 범위의 용량 안전성 이슈들을 해결해 주었지만, 다른 수많은 도전 대상들 또한 발굴해주었다. 예를 들어, "Fidelity"와 "매끄러운 개발자 경험"을 동시에 지원해야 했다. "Fidelity"란 모든 중요한 서비스들이 실제 트래픽과 같은 방식으로 테스트되어야 한다는 것을 뜻하는 말이다. 이 방법으로는 최상단의 마이크로 서비스들은 제대로 테스트되지만, mapping 시스템이나 결제 시스템과 같은 깊은 하단의 백엔드 마이크로 서비스들은 동일한 테스트 커버리지를 가질 수는 없게 된다. 게다가, 테스트 환경의 제어를 위하여, 플랫폼 단위의 테스트를 할 때는 전체 배포 시스템에 lock을 걸게 된다. 예상하겠지만, 이것은 수행 중이던 빌드와 배포를 멈추기 때문에 개발자 경험에 나쁜 영향을 주게 된다. 


이 문제를 해결하기 위하여, 신뢰성 엔지니어들은 기존 도구 위에서 동작하는 지역화되고 자동화되어 독립적으로 실행될 수 있는 서비스 단위의 용량 안전성 테스트를 만들게 되었다. 이 접근은 여러 복잡한 사항들과 패턴들, 그리고 각 서비스의 사용량 등을 반드시 고려해야 하기 때문에 훨씬 더 어려운 방식이다. 게다가, 이 테스틀 통과하기 위해서 우리는 핵심 서비스 지표를 예측하는 자체 도구를 만들었다. 이 덕분에 우리는 각 서비스가 용량 안전성 요구사항을 충족시킬 수 있을지 없을지에 대해 더 잘 알 수 있게 되었다. 


규모가 작을 때는 간단한 모니터링과 테스트도 유용할 수 있지만, 점점 서비스가 성장하고 사업이 커질수록 기존 방식으로는 한 번에 전체 시스템의 상태를 파악하기가 어려워집니다. 시스템이라는 것은 갈수록 점점 더 복잡해질 수밖에 없기 때문에 모니터링과 테스트의 규모와 범위를 확장하는 것만으로도 엄청난 어려운 난관에 많이 부딪히게 되는데요, 여기서 Uber는 용량 안전성이라는 개념을 도입하여 문제를 단순화한 것으로 보입니다. 여러 가지 문제들이 발생하고 여러 가지 원인들이 존재하겠지만 그중에 큰 비중을 차지하는 하나의 원인, "용량"에만 집중해보자는 결정을 한 것이지요. 이렇게 일단 집중할 수 있는 대상을 선택하고 나면 좀 깊게 파고들 수 있게 됩니다. 그래서 이 업무가 단순히 모니터링과 테스트가 아니라 예측까지 업무가 확장될 수 있었던 것이 아닐까요?


머신러닝을 활용 가능한 시스템 구조 설계


그림 1 : 마이크로 서비스의 신뢰성을 향상하기 위해 데이터 수집과 저장 및 예측을 통합 제공하는 지도 신뢰성 공학 예측 시스템의 구조 설계


간단히 말해서, Uber의 각 실제 서비스들은 지표들을 뱉어냄으로써 관측이 되고 있고, 그 지표들 중 일부는 자원 사용과 용량과 관련되어 있다. 이 지표들은 M3에 저장되고 API를 통해 질의할 수 있다. 우리의 예측 시스템은 어떤 서비스에서 예측이 필요한지 판단하기 위해 하나의 서비스 질의 설정 파일을 사용한다. 이 시스템을 사용하고 싶은 내부 개발자들은 그들의 서비스 이름과 핵심 지표(예를 들어, 초당 요청 수)들을 설정함으로써 그들의 서비스를 입주시킬 수 있고, 시간 단위/일 단위의 예측이 가능해진다.


다른 머신러닝 과제와 마찬가지로, 예측이 정확해지기 위해서는 굉장히 많은 양의 학습 데이터가 필요하다. 그래서 시계열의 추세와 계절성 패턴이 드러나는 충분한 양의 데이터가 있어야 한다. 우리의 서비스는 M3에 범위 질의를 수행하는 수집기를 사용하여 가상의 저장 계층에 이 데이터를 저장한다.


한 서비스가 예측을 위한 준비가 되면, 저장 계층에서 학습 데이터를 수집한다. 이 데이터는 불필요한 내용을 제거하기 위해 여러 전처리 계층을 거치게 된다. 예측 단계에서는, 정확한 예측을 위해 다양한 통계 기법들이 사용된다. 마지막으로, 이 예측은 모델이 얼마나 학습 데이터에서 잘 학습되었는지 확인하기 위해 검증 단계를 거치게 된다. 


예측 시스템은 주어진 시간 동안 정해진 주기로 반복 실행되도록 설정하는 기능을 제공한다. 이를 통해 서비스와 이벤트에 변화가 생겨도 그에 맞춰 수정될 수 있다. 예를 들어, 어떤 서비스가 평소와 다르게 높은 요청을 받기 시작하는 경우, 시스템은 이 새로운 패턴을 계산에 포함하게 되고 따라서 예측도 변화하게 된다.


각 수집과 예측 주기가 지나고 나면, 그 결과가 저장 계층에 저장된다. 만약 앞서 말한 이벤트로 인해 예측에 변화가 생기는 경우 우선순위 큐 방식으로 기존 예측이 새로운 예측에 의해 덮어 쓰여진다. 결과적으로, 이 예측을 테스트 용도로 사용하기 원하는 담당자들은 API를 통해 데이터를 요청할 수 있게 된다. 


시스템 구조가 아주 상세하게 소개되지는 않았지만, 수집 - 저장 - 학습 - 서빙으로 일반적인 머신러닝 시스템과 과 크게 다르지 않은 것 같습니다. 굳이 차이를 찾자면 서빙 계층이 따로 없고 그냥 예측 결과를 저장만 하고 있는데, 이 시스템이 사용자를 대상으로 하는 것이 아닌 회사 내부의 서비스 담당자들을 대상으로 하는 시스템이기 때문입니다. M3라는 지표 수집 플랫폼이 튼튼하고 편리하게 잘 구축되어 있어서 그런지 본 아티클에서는 데이터 파이프라인이나 지표 처리 방법에 대해 굳이 자세히 설명하지 않는 것도 특이한 점입니다. 


데이터 수집


CPU나 메모리 사용량 정보 등 우리가 사용하는 데이터는 서버 로그, 이벤트 로그, 데이터센터 리포트와 같은 믿을 만한 출처로부터 나오기 때문에 안정적인 학습 데이터셋을 제공해준다. 예측의 시간 범위는 정확히 학습 데이터셋의 크기와 비례하기 때문에, 우리는 수집 데이터 양에 제한을 두지 않기로 결정했다. 그러나 M3의 기본 데이터 보관 정책 때문에 예측을 위해 충분한 데이터를 수집할 수 없었다. 대부분의 경우 시계열 데이터는 오래될수록 가치가 떨어지기 때문에, 오래된 데이터는 삭제하는 것이 경제적이다. 하지만, 이 "낡은" 데이터가 예측 시스템에서는 더 먼 미래를 예측하는 모델을 생성할 때 매우 중요한 역할을 한다. 어찌 되었든, 장기 추세와 계절적 패턴을 찾아내기 위해서는 과거 데이터에서 그만한 범위를 커버할 수 있어야 하기 때문이다. 


그림 2 : 예측의 시간 범위는 대략 학습 데이터 크기의 25% 정도이다. 따라서 만약 더 많은 양의 학습 데이터셋이 있으면 더 많은 지점을 예측할 수 있다. 


M3의 범위 질의는 오직 제한된 양의 시계열 데이터만 제공하기 때문에, 위 그림 2에 표시된 것과 같이 거대 서버 집단의 전체 데이터를 얻기 위해서는 연속된 질의를 만들어내야 했다. 그러나, 시계열 데이터는 주기적으로 수집되므로, 우리는 종종 데이터의 시작과 끝에 잘못된 데이터가 들어가 있는 것을 발견하였다. 이것은 시계열 데이터가 유입될 때 미리 선집계를 한 뒤 미래의 질의를 위해 나중에 저장하도록 한 M3의 설계 결정 때문이었다. 우리의 수집 주기에 집계 주기가 잘 맞지 않으면 데이터 경계에는 적합한 데이터가 존재하지 않게 된다. 이 문제를 해결하기 위해, 우리는 수집 주기의 시작과 끝에 버퍼 구간을 두어 모든 연속 데이터가 제대로 구성된 다음에 삭제되도록 하였다. 이 기능은 M3의 집계 정책과 호환되게 해 주었지만, 우리가 잘못된 데이터를 덮어쓸 수도 있게 만들어 버렸다.


다음 단계는 수집 데이터에서 시간에 따라 학습 데이터셋을 계속 만들어내는 것이었다. Uber의 M3 팀은 더 넓은 보유 기간에 대한 수요가 증가하고 있다는 것을 깨달았고, 개별 시계열 데이터에 따라 보유 기간과 집계 정책을 설정할 수 있는 기능을 제공하기 시작했다.


초창기에 우리는 프로토타입을 빨리 만들기 위해 시계열 데이터를 로컬에 저장하였다. 이때 우리는 오픈소스 내장형 key-value 저장소인 BoltDB를 사용하였다. BoltDB는 프로토타입을 만들기 위해서는 좋은 선택이었지만, 시계열 데이터를 예측 시스템의 여러 인스턴스에 분산시키는 기능이 없어서 실제로 활용하기에는 충분하지 않았다. 게다가, 데이터가 내장되기 때문에 새로운 배포가 발생할 때마다 데이터가 제거되는 문제도 있었다. 그래서 우리는 Apache Cassandra 위에서 동작하는 오픈소스 저장소 솔루션인 DOSA로 옮기게 되었다. DOSA는 우리의 용도에 잘 맞았는데, 우리는 대부분 timestamp 기반의 범위 질의를 수행했지, 복잡한 관계형 질의는 수행하지 않았기 때문이다. DOSA는 또한 여러 배포와 인스턴스에 걸쳐서 일관된 뷰를 보여주기 때문에 BoltDB에서 발생했던 이슈들을 많이 해결해주었다.


데이터의 지속성과 마찬가지로, 우리의 예측 시스템은 데이터를 수집할 때 여러 가지 이유로 문제가 생길 수 있었기 때문에 가용성에 많은 신경을 써야 했다. 장애에 대한 내성을 보장하기 위해, 우리는 예측 시스템을 여러 데이터센터에 인스턴스를 구축하여 운영하였고, 어느 시간에도 최소한 하나의 인스턴스는 정상 동작하도록 보장하였다. 이 시나리오에서, 동시 수집에서 발생하는 데이터의 일관성은 또 다른 이슈이다. M3에서 시계열 데이터를 선집계하기 때문에, 각 인스턴스들은 항상 같은 데이터에 질의를 하고, 덕분에 데이터 일관성을 보장하기 위한 추가 작업은 필요가 없었다. 


M3에서 처리할 수 없는 or 정책적으로 지원하지 않는 일부 영역에 대한 커버를 위해 별도 DB를 구축한 내용입니다. 사실 시스템을 개발하다 보면 이런 일이 꽤 자주 발생하게 되는 편인데, 모든 도구를 직접 다 만들 수는 없으니 있는 것들을 최대한 활용을 하긴 해야 하는데, 그렇다고 모든 도구들이 내 입맛이 맞게 딱딱 준비되어 있지는 않기 때문입니다. 이럴 때 도구들의 장단점을 빠르게 잘 파악하여 내가 가진 문제들 중 어떤 문제를 도구로 해결하고, 어떤 문제를 직접 구현으로 해결해야 할지 빠르게 판단하는 것이 회사에서 가장 중요한 능력 중 하나가 아닐까 싶습니다. Uber의 신뢰성 엔지니어링 팀은 "운영 문제를 소프트웨어로 해결하는" SRE 조직답게 이런 어려움을 슬기롭게 잘 극복한 것으로 보입니다. 


데이터 전처리


시계열 데이터를 예측하기 전에, 우리는 과거 데이터셋에서 예측에 영향을 줄 만한 예외 케이스와 필요 없는 부분들을 제거하는 작업을 한다. 특히, 임의의 서비스에서 가져온 시계열 데이터들은 데이터센터 Failover가 발생한 시점의 데이터를 가지고 있을 수도 있다. 현재의 플랫폼 단위의 용량 안전성 프로세스상 데이터센터 Failover가 일어나는 것은 당연하다. 하지만, 이 구간에서 문제가 생겨 비정상적인 행동을 보여주는 데이터센터의 데이터는 데이터셋에서 제외되어야 한다. 


시계열 데이터의 전처리를 위한 첫 단계는 데이터센터 Failover에 해당하는 구간을 식별하고 제거하는 것이다. 이 구간은 한 데이터센터의 트래픽이 0으로 가고 다른 데이터센터의 트래픽이 기존의 두 배가 되기 때문에 시각적으로는 발견하기 쉽다. 그러나, 자동으로 이 데이터센터 Failover를 감지하는 것은 단순한 작업이 아니다.


그림 3 : 이 가상 시나리오에 의하면, Failover 기간 동안 DC2에의 트래픽이 DC1으로 유입되면서 점점 0에 가까워진다. 몇 시간 뒤, 둘 다 정상화된다.


Failover는 아주 구체적인 특성을 보여주기 때문에, 머신러닝이 이 특성을 Feature로 잡아낼 수 있도록 만들 수 있다. 전통적인 분류 작업과는 달리, 용량 학습과 관련된 우리의 목표는 시계열 데이터 안에서 문제 구간을 분류해내는 것이기 때문에, 학습과 예측 단계가 학습 조건에 따라 달라졌다.


학습 단계는 다음과 같이 구성된다.

데이터셋에서 k개의 데이터로 구성된 Rolling Window를 만든다.

뽑힌 데이터 기반으로 각 Rolling Window에 "Failover" 또는 "No Failover" 태그를 달아준다.

각 Failover Window로부터 다양한 시계열 Feature들을 추출한다.


예측 단계는 다음과 같이 구성된다.

데이터셋에서 k개의 데이터로 구성된 Rolling Window를 만든다.

학습된 모델을 사용하여 각 Rolling Window를 "Failover" 또는 "No Failover"로 분류한다.

"Failover"로 태그 된 각 구간들의 겹치는 부분들을 합친다. 


그림 4 : SVM 모델은 데이터센터 Failover 구간을 구분해낼 수 있다.


Failover 구간이 데이터셋에서 지워지고 나면, 시계열 데이터를 다시 연속적으로 만들기 위해 채워야 할 값들이 생겨난다. 선형 보간법과 같은 단순한 복구 방법은 사용하기는 쉽지만 현실적이지 않은 값만 만들어낸다. 그래서 데이터를 복구할 때는 시계열 데이터 분해 알고리즘을 통해 얻어낼 수 있는 추세와 계절성 요소들이 반드시 고려되어야 한다. Uber에서는 선형 보간법과 STL 방식을 혼합한 하이브리드 복구 방식으로 빈 값들을 채우고 있다. 


그림 5 : 선형 보간법과 계절성 기반 보간법을 비교해보면 계절성 기반 보간법이 시계열 데이터의 빈 부분을 좀 더 현실적으로 채워준다.


여기서 좀 특이한 대목은, 이 시스템이 "이상 탐지"가 아니라 "용량 예측"의 용도로만 사용되고 있다는 점입니다. 데이터센터 Failover와 같은 패턴을 자동으로 감지할 수 있다면, 시스템에서 발생하는 각종 이상 현상에 대한 탐지도 자동화하여 장애를 예방하거나 대응을 자동화하는 것이 가능할 텐데, 그런 언급은 전혀 없습니다. 실제로는 존재하지만 본 아티클의 주제에서 벗어나서 언급하지 않은 것인지, 아니면 진짜 이 글에서 말하는 내용이 전부인지 알 수 없네요. 저런 특이한 지표 패턴을 탐지하는 일은 생각보다 꽤 어려운 작업이기 때문에 그냥 학습 데이터셋에서 제거하는 용도로만 사용하기에는 좀 아깝지 않나 싶습니다. 



데이터 예측과 백테스팅


시계열 데이터 예측을 위해, 우리는 내부적으로 ARIMA, Holt-Winters, 그리고 Theta 모델을 혼합한 앙상블 방식의 예측 API를 만들었다. 각 모델의 예측은 똑같은 비중으로 계산에 포함되고 있는데, 미래 예측의 경우 좀 더 나은 성능을 보여주는 모델에 가중치가 조금 더 추가될 수도 있다. 게다가, 이 예측 API에는 수동으로 인자를 넣어주지 않아도 hyperparamter가 조절되는 자동 예측이 구현되어있다. 


앙상블 방식의 성능을 평가하기 위해, 우리는 예측과 실제 값의 오차를 수치화하였다. 전통적인 머신러닝 테스트 방법과 달리, 시계열 데이터는 연속적이기 때문에 순서를 무작위로 섞을 수 없다. 시계열 데이터는 연속적인 테스트나 백테스트가 필요하고, 따라서 Rolling Window에 대한 모델 성능을 가지고 Cross-validation을 수행하게 된다.


백테스팅 과정에서는 예측된 값과 실제 값의 오차를 수치화하여 다음과 같은 다양한 오차 지표를 제공해준다. 

Mean Error (ME)

Mean Absolute Error (MAE)

Mean Absolute Percentage Error (MAPE)

Weighted Mean Absolute Percentage Error (wMAPE)

우리는 앙상블 방식의 오차를 평가하기 위해 주로 wMAPE를 사용하는데, 가장 bias가 적고, 유익하면서 상수인 지표이기 때문이다.


wMAPE 점수가 낮은 모델의 예측이 정확할 가능성이 높지만, 시계열 데이터는 금방 사라질 수도 있기 때문에 이 값이 더 이상 낮아질 수 없는 한계가 존재한다. 보통 우리 시스템을 사용하는 서비스 담당자들은 이 값이 10-15% 정도가 되면 유용하다고 생각하고, 이게 각 서비스들의 목표치가 된다.

그림 6 : 한 개발 서비스의 RPS 예측 오차 범위를 고민해본 결과 wMAPE 기준 12 %가 적당한 것으로 나타났다.


몇 가지 알고리즘을 혼합하여 시계열 지표 예측에 활용하는 것은 아주 좋은 방법인 것 같습니다. 각 알고리즘마다 장단점이 있을 것이고 또 어떤 데이터가 들어올지 알 수 없는 "플랫폼"의 입장에서는 가능하면 다양한 방법을 준비해두는 것이 제일 안전할 것입니다. 다만, 여기서 각 알고리즘 자체를 조금 더 튜닝하거나, 아니면 Uber 서비스와 여기서 수집된 데이터의 특성을 반영한 자체 알고리즘이나 문제 해결법이 소개되었으면 더 좋았겠다는 아쉬움이 살짝 남습니다.


용량 안전성 확인


주간 예측과 백테스팅 점수는 HTTP API를 통해 확인이 가능하다. 로컬 용량 안전성 테스트에 관심이 있는 서비스 담당자들은 현재 지표 상태만을 가지고 예측치와의 차이점을 계산해볼 수 있다. 그러면 이제 Uber의 부하 테스트 프레임워크인 Hailstorm을 사용하여 이 차이나는 만큼의 추가 부하를 발생시켜보면 된다. 그러면 서비스들이 제대로 배치되었는지에 대한 직관을 얻을 수 있게 된다. 만약 부하 테스트가 실패하면, 나중에 성능이 감소하리라는 것을 암시하는 것이다.

그림 7 : 우리의 예측 시스템을 사용하여, 개발자들은 이번 주의 남은 날들의 시간당 부하를 시뮬레이션해볼 수 있다.


예측 시스템의 목적은 주요 지표에 대한 예측 과정을 간소화하고, 로컬 용량 안전성 훈련을 수행하고, 서비스가 제대로 배치되었는지에 대한 피드백을 받는 것이다. 이 서비스를 개발하면서, 우리는 충분한 운영 데이터를 통해 정확한 시계열 예측이 가능하다는 것을 알게 되었다. 우리는 두 가지 넓은 범위의 통계적 기법이 필요하였는데, 하나는 전처리를 위한 것, 그리고 또 하나는 예측을 위한 것이었다. 또한 앙상블 기반 모델은 다양한 모델들의 관점을 차용하여 아주 강력하였다.


아티클의 앞부분에 비해 내용이 좀 부실하게 느껴지는 뒷부분입니다. 아마 자세한 실험 데이터를 공개하기가 어려웠거나 글 작성 기간이 빡빡해서 그렇지 않을까 예상해봅니다. 어쨌든 각 서비스의 담당자 입장에서는 어느 정도의 부하를 어떻게 테스트해야 할지 막막한 경우가 많을 텐데, 이렇게 용량 안전성을 계산해주고 예측해주는 시스템이 있으면 큰 도움을 받을 수 있을 것 같습니다. 비록 완전히 정확할 순 없겠지만 수작업으로 계산하는 시간을 많이 줄여주고, 그 과정에서 발생할 수 있는 실수에 대한 리스크를 없애준다는 것만으로도 충분히 가치가 있다고 생각합니다. 


앞으로


운영 지표 예측과 API 주도 부하 생성기가 있으면, 각 마이크로 서비스에 대한 적응형의 자동화 용량 안전성 테스트가 가능해진다. SLA 보장 또한 후행적인 방식이 아닌 선제적인 방식으로 검증이 가능해진다.


앞으로 우리는, 이 과정을 완전히 자동화하여 신뢰성 엔지니어들이 버튼 하나 누르지 않고도 trip-flow 서비스의 용량 안전성을 보장할 수 있게 되기를 원한다. 또한 이렇게 되면 조금 덜 중요한 시스템에 대한 빠른 실험과 반복이 가능해지기 때문에, 개발 자유도도 높아지고 서비스도 더 좋아지게 될 것이다. 


글의 마지막 부분에 언급된 완전 자동화에 대해서 후속 글이 공개된다면 꼭 읽어보고 싶습니다. 보통 자동화는 편리하지만, 가끔 돌이킬 수 없는 재앙을 일으키기도 해서 "완전한 자동화"라는 말을 하기가 꺼려질 수밖에 없습니다. 위에서도 언급했지만 아마 이 시스템이 "이상 탐지"가 아닌 "용량 예측"을 주로 수행하기 때문에 서비스에 그렇게 심각한 영향을 주지 않을지도 모르겠습니다. 

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari