본문 바로가기

개발/SRE - 사이트 신뢰성 엔지니어링

SRE 4장 - 서비스 수준 목표

  서비스를 운영하는 데 있어 가장 중요한 지표들과 이 지표들을 측정하고 평가하는 방법에 대한 올바른 이해 없이는 서비스를 올바르게, 알아서 잘 돌아가도록 관리한다는 것은 불가능하다. 그래서 여기서는 사용자에게 필요한 서비스의 적정 수준을 정의하고 제공하는 방법에 대해 이야기하고자 한다.

 

  이 내용은 우리 저자들의 직감과 경험(오... 직감과 경험...), 그리고 사용자가 서비스 수준 척도(SLI), 서비스 수준 목표(SLO), 서비스 수준 협약(SLA) 등을 어떻게 정의하고 있는지에 대한 이해를 바탕으로 하고 있다. 이 세 가지를 살펴보면 주요 지표들의 기본 속성과 각 지표들의 적정 값, 그리고 기대했던 수준의 서비스를 제공하지 못했을 때의 대처 방안 등을 알 수 있다.

결국 어딘가에 문제가 발생했을 때 올바른 지표를 참고하여 적절한 행동을 취할 수 있다. SRE팀은 이런 지표들을 확인함으로써 서비스가 문제 없이 동작 중이라는 확신을 가질 수 있다.

 

  이 장에서는 지표의 모델링과, 선택, 그리고 분석 과정에서 발생하는 문제들을 해결하는 데 사용했던 프레임워크를 소개한다. 

 


서비스 수준 관련 용어

  이 책에서는 많은 독자가 이미 SLA의 개념에 대해 알고 있을 것이라고 가정한다. 하지만 상대적으로 SLI와 SLO 역시 주의 깊게 정의해야 한다고 말한다. 그 이유는 SLA는 보통 문맥에 따라 의미가 변하거나 여러 가지 의미를 갖는 경우가 있기 때문이다.

 

척도

  SLI는 서비스 수준 척도를 의미하며, 서비스 수준을 판단할 수 있는 몇 가지를 정량적으로 측정한 값이다. 

 

  1.  대부분의 서비스들은 핵심 SLI로서 요청에 대한 응답 속도를 꼽는다.
  2. 그 외에도 시스템이 수신한 전체 요청 수 대비 에러율,
  3. 그리고 초당 처리할 수 있는 요청 수를 의미하는 시스템 처리량(System throughput) 등이 있다.

측정된 값들은 합산되기도 한다. 즉, 측정한 값들을 모아 비율이나 평균 혹은 백분율 등을 계산한다. 

 

알고자 하는 서비스 수준의 SLI를 직접 측정하는 것이 이상적이기는 하지만, 경우에 따라서는 필요한 값을 얻어내거나 해석하기가 어려워 그에 준하는 대체 값을 사용하는 경우도 있다. 

클라이언트 측의 응답 속도를 측정하는 것이 사용자와 관련해서 조금 더 의미가 있겠지만 우리 입장에서는 서버의 응답 속도만을 측정할 수 있다.

 

SRE가 중요하게 생각하는 SLI 중 하나는 가용성, 즉 서비스가 사용 가능한 상태로 존재하는 시간의 비율이다. 이 값은 주로 올바른 형태의 요청이 성공적으로 처리된 비율을 의미한다. 수율이라고도 한다. 비록 100% 가용성은 실현이 불가능하지만, 100%에 가까운 가용성은 얼마든지 달성한 수 있다. 현재 구글 컴퓨트 엔진(GCE)은 '9 세개 반', 즉 99.95%의 가용성을 목표로 하고 있다.

 

목표

SLO는 서비스 수준 목표를 의미하며, SLI에 의해 측정된 서비스 수준의 목표 값 혹은 일정 범위의 값을 의미한다. 그래서 SLO는 SLI <= 목표치 또는 최솟값 <= SLI <= 최댓값으로 표현할 수 있다.

  • 예를 들어 우리가 셰익스피어의 검색 결과를 '빠르게' 리턴하기로 결정했다면, 평균 검색 요청의 응답 시간에 대한 SLO는 100밀리초 이하로 설정할 수 있다. 

적절한 SLO 값을 설정하는 것은 생각보다 복잡하다. 무엇보다 필요한 값을 항상 얻어낼 수가 없다. 예를 들어 외부에서 서비스로 유입되는 HTTP 요청의 경우, 기본적으로 초당 쿼리 수(QPS)라는 지표는 사용자가 서비스를 얼마나 사용하느냐에 따라 결정되므로 이 지표에 대한 SLO를 설정하는 것은 말이 되지 않는다. 

 

반면, 요청당 평균 응답 시간을 100ms 이내로 설정하겠다는 목표는 설정할 수 있다. 100ms는 보통 빠른 응답 속도로 설정하기에는 적절한 값이다.

 

SLO를 설정하고 고객에게 이를 공개하는 것은 서비스의 동작에 대한 예측을 가능하게 한다. 이런 전략을 통해 서비스 소유자들의 서비스가 느려지고 있다는 등의 근거 없는 불평을 줄일 수 있다. 

SLO를, 즉 목표 수치를 고객에게 공개한다는 생각을 해본 적이 없었다. 약간 나 100점 맞을거야! 라고 말하는 것은 너무 자만심 같은 느낌이라고 생각해서 일까? 그치만, 100%가 아닌, 99.5%라고 말하는 것은 어찌보면 조금의 실수(?), 모자람을 인정한다는 느낌으로 좋은 걸까? 투명성?

명확한 SLO가 설정되어 있지 않다면 서비스를 디자인하고 운영하는 사람들의 생각과는 전혀 다른, 자신들이 희망하는 성능을 기대하곤 한다.(결국 아예 우리는 이 정도를 제공한다! 라고 알려주는 것이 더 사용자들에게 불만을 주지 않는 다는 것이다) 

이렇게 생겨난 다양한 기대치 때문에 사용자가 실제 서비스가 제공할 수 있는 것 이상의 가용성을 기대해서 지나치게 서비스에 의존하는 현상과 잠재 고객들이 서비스를 실제보다 저평가하는 현상 모두를 유발하게 된다.

너무 큰 기대감을 주지 말자, 기대감은 지나친 서비스 의존성을 만들고, 기대가 너무 크면 실망도 크다.

 

 

협약

  마지막으로 SLA는 서비스 수준 협약의 약자로, SLO를 만족했을 경우(혹은 그렇지 못한 경우)의 댓가에 대한 사용자와의 명시적 혹은 암묵적인 계약을 의미한다. 그 댓가란 대부분 경제적인 것(환불이나 벌금 등)으로 대변되지만, 다른 형태로 나타나기도 한다.

 

SLO와 SLA의 차이점은, 'SLO를 달성하지 못하면 어떻게 될 것인가?'를 생각해보면 된다고 한다. 이 질문에 대한 명확한 결론이 없는 경우라면 십중팔구 SLO라고 생각해도 무방하다. ( 이 부분이 조금 헷갈린다 - 하지만 위반 사항이 없는 경우에는 SLO라는 뜻이다. GOOGLE 검색이 잘 안된다고 해서 일반 사용자들에게 보상을 하지 않는다. SLA가 아닌, SLO. SLA 위반은 계약 위반이므로 법정으로 가야 한다.  )

 

SRE는 SLA의 체결에는 관여하지 않는다. 사업부 및 제품에 대한 의사 결정과 관련이 있다. SLO를 달성하지 못하는 경우를 피하기 위해서는 SRE의 도움이 필요하다. SLI를 정의할 때도 마찬가지다. SLO는 객관적인 방법으로 측정되어야 하며, 그렇지 않다면 누구도 그 협약에 동의하지 않을 것이기 때문이다. 

 

구글 검색과 같은 서비스는 중요하지만 SLA가 없다.  전 세계의 모든 사용자와 계약을 맺기를 원하지는 않는다. 댓가를 치르기는 한다. 평판도 좋지 않을 것이고 광고 수입도 줄어들 것이다. 반면, 기업용 구글 앱스 등 구글의 다른 서비스들은 명확한 SLA를 체결하고 있다. 하지만, SLA 체결 여부와는 무관하게 서비스마다 SLI, SLO를 설정하고 이를 토대로 서비스를 관리해야 한다. 

 


지표 설정

서비스나 시스템에 있어 중요한 지표가 무엇인지를 어떻게 판단할 수 있을까?

 

정말 중요한 것은 무엇인가?

모니터링 시스템을 통해 추적할 수 있는 모든 지표를 SLI로 취급할 필요는 없다. 사용자가 무엇을 원하는지를 이해하고 적절한 척도들을 현명하게 선택해야 한다. 너무 많은 지표를 선택하면 중요한 것에 집중하기가 어렵고, 너무 적은 수의 척도를 선택한다면 중요한 부분을 놓칠 수 있다. 부족함이 없는 적절한 수의 척도들을 선택한다. 

 

이 책에서는 적절한 SLI 선정과 관련해 시스템들을 다음 몇 가지로 분류하고 있다.

  • 셰익스피어 검색 프런트엔드 - 사용자가 직접 대면하는 시스템들
    • 가용성, 응답시간, 그리고 처리량이 중요하다 ( 올바르게 응답할 수 있는지, 응답 시간, 얼마나 많은 요청을 처리할 수 있는지 )
  • 저장소 시스템
    • 응답 시간, 가용성, 그리고 내구성 ( 읽고 쓰는 데 걸리는 시간, 필요할 때 데이터에 액세스 할 수 있는지, 데이터는 안전하게 저장되어 있는지 )
  • 빅데이터 시스템 ( 데이터 처리 파이프라인 등 )
    • 종단 간 응답 시간 ( 얼마나 많은 데이터를 처리할 수 있는지, 데이터가 유입된 이후로 작업을 완료하기까지의 시간 )

하지만, 모든 시스템은 정확성(correctness) 역시 중요하게 생각해야 한다. 올바른 응답, 올바른 데이터를 조회했는지, 분석은 정확히 이루어졌는지. 하지만 인프라스트럭처보다는 시스템의 데이터에 대한 것이므로 SRE가 관여하지는 않는 경우가 대부분이다.

 

척도 수집하기

많은 척도들은 기본적으로 보그몬이나 프로메테우스 등의 방법을 통하여 주로 서버 측에서 수집된다. 그러나 일부 시스템들은 클라이언트 측의 수집이 이루어져야 하기도 한다. 예를 들어 셰익스피어 검색 백엔드의 응답 속도만으로는 페이지의 자바스크립트 때문에 발생하는 지연응답을 판단할 수 없다. 브라우저에서 측정해야 사용자의 실제 경험을 판단할 수 있다.

 

합산하기

단순함과 유용함을 위해 측정된 원본 데이터를 합산하는 경우도 있다. 다만 이 경우 상당한 주의를 기울여야 한다. 

 

초당 요청 수 같은 일부 지표들은 보기에는 직관적이다. 하지만 측정 방식에 따라 직관적으로 보이는 지표들도 일정 시간을 놓고 보면 은연중에 합산되어 있다.

  • 측정 자체가 일초에 한 번 수행 되는가 아니면 일분에 걸쳐 발생한 요청들의 평균 값인가? 후자의 경우라면 단 몇 초 동안에 폭발적으로 증가한 요청 비율을 제대로 분석해낼 수 없다. 
  • 어떤 시스템은 짝수 초마다 200개의 요청을 처리하고, 나머지는 0개의 요청을 처리했다고 가정해보자. 이때 그 시스템은 평균적으로 초당 100개의 요청을 처리한 셈이지만 순간적인 부하는 평균 값의 두 배에 달할 수 있다. 평균에는 문제가 없어 보일지 몰라도, 중요한 세부 내용이 모호하다. ( 연구에서도 중요하게 생각했던 부분이다. 개인적으로는 최대한 scale은 최대한 작게 측정하는 것을 선호했다. 데이터의 Quantization이 Normalization보다는 쉽다고 생각한다. )

 

대부분의 지표들의 경우 평균보다는 분포가 중요하다.

  예를 들어 응답 시간 SLI의 경우, 일부 요청은 빠르게 처리되었을 수 있지만 나머지는 균일하게 더 느리게 - 어쩌면 그보다 더 느리게 처리되었을 수도 있다. 단순히 평균만을 집계하면 이렇게 느리게 처리된 요청 뒤에 유입된 요청들의 처리 속도는 알 수 없다. 대부분의 요청들이 50ms 안에 처리되었지만 5%의 요청들은 20배나 느리게 처리된 경우가 그림 4-1에 나타나있다. 평균 응답 시간을 기준으로 모니터링과 알림을 설정하면 하루 동안 아무런 변화가 없는 것처럼 보일 것이다.

 

그래서 이 책에서는 척도에 백분위 수를 사용해서 분포와 더불어 독특한 특징을 알아본다. 즉, 99번째나 99.9번쨰 백분위 수 같은 높은 수들은 최악의 경우의 상황을 보여주고, 50번째 백분위 수(median - 중간값)는 일반적인 경우의 상황을 보여준다. 사용자에 대한 연구에 의하면 사람들은 응답 시간의 변동이 큰 경우보다는 살짝 느리게 동작하는 시스템을 더 선호한다고 한다. 그러므로 99.9번째 백분위 수의 값이 양호하다면 사용자 경험 역시 훨씬 나아질 것이라는 점을 근거로 일부 SRE는 높은 백분위 수 값들에 더 주목하기도 한다.

결국 더 나은 경험을 위해서는 평균보다, 분포를 중요하게 보아야 한다는 말이다. Hystrix도 median값보다는 99%, 99.5%에 중심을 두고 있다. 99%를 주요하게 바라보고, 99%와 99.5%의 차이가 median보다 작은 경우가 많다는 경험에서 착안하여 99.5%는 99% + retry median으로 대체한다.

 

"통계적 오류에 대한 단상" 을 보면, 결국 평균 값 보다는 백분위 수(median과, 99% 등)를 중요하게 생각하라는 조언이 담겨져 있다. 평균의 오류라고 말하는 부분이다.

 

척도의 표준화

우리는 SLI들에 대한 일반적인 정의를 표준화하기를 권장한다.(척도들의 최우선 원칙이 무엇인지를 매번 고민할 필요가 없게 한다)

그렇게 표준화된 정의 템플릿을 따르는 모든 수치들은 개별 SLI의 명세에서 생략해도 무방하다. 

예를 들어보자.

  • 집계 간격 : '평균 1분'
  • 집계 범위 : '하나의 클러스터에서 수행되는 모든 태스크들'
  • 측정 빈도 : '매 10초'
  • 집계에 포함할 요청들 : '블랙박스 모니터링 잡이 수집한 HTTP GET 요청들'
  • 데이터의 수집 방식 : '모니터링 시스템에 의해 서버에서 수집'
  • 데이터 액세스 응답 시간 : '데이터의 마지막 바이트가 전송된 시간'

 


목표 설정에 대한 실습

중요한 것은 어떤 값을 측정할 수 있는지가 아니라, 사용자가 중요하게 생각하는 것이 무엇인지에 대해 생각해보는 것이다.

단순히 어떤 값을 측정할 수 있는지만을 생각한다면 그다지 유용하지 않은 SLO들을 설정하게 될 것이다. 

척도를 먼저 선택하고 목표를 설정하는 것보다는 목표를 먼저 설정한 후 적절한 척도를 찾는 것이 더 낫다는 것을 알아내었다.

 

목표 설정하기

명확성을 극대화하기 위해 SLO는 측정 방식과 유효한 기준이 반드시 명시되어야 한다. 아래의 문장들을 살펴보자

  • Get RPC 호출의 99%(1분 간의 평균)는 100밀리초 이내에 수행되어야 한다(모든 백엔드 서버에서 측정된 평균 시간이어야 한다).
  • Get RPC 호출의 99%는 100밀리초 이내에 수행되어야 한다. ( 첫 번째 항목과 동일하지만 중복을 제거하기 위해 앞선 SLI 공통 속성을 사용해 정의한 항목이다 )

만일 성능 그래프가 중요하다면 다음과 같이 여러 개의 SLO 목표들을 설정할 수 있다.

  • Get RPC 호출의 90%는 1밀리초 이내에 수행되어야 한다.
  • Get RCP 호출의 99%는 10밀리초 이내에 수행되어야 한다.
  • Get RCP 호출의 99.9%는 100밀리초 이내에 수행되어야 한다.

만일 사용자의 작업 부하가 처리량을 중시하는 대량 처리 파이프라인과 응답 시간을 중시하는 대화형 클라이언트로 분산된다면 부하의 종류에 따라 개별적인 목표를 설정하는 것이 좋다.

  • 처리량이 중요한 클라이언트로부터 발생한 Set RPC 호출의 95%는 1초 이내에 수행되어야 한다.
  • 응답 시간이 중요한 클라이언트로부터 발생한 페이로드(payload) 크기 1kb 미만의 Set RPC 호출은 10초 이내에 수행되어야 한다.

SLO를 100% 만족하는 것은 현실성이 없고, 충족하려 하면 혁신과 배포의 속도가 저하되며 높은 비용을 소비하거나 지나치게 보수적인 솔루션이 된다. 따라서 에러 예산을 산정하고 일/주단위로 추적하는 것이 훨씬 나은 방안이다. ( 물론 조직 내의 상위 관리자들에게는 월단위 혹은 분기단위로 평가를 보고하는 편이 낫다)

 

목표치 선택하기

목표치를 선택하는 것은 순수한 기술적 활동이라고 보기는 어렵다. 제품과 사업에 영향을 미치기 때문이다. SRE는 이런 논의에 반드시 참여해야 하며, 위험/실행가능성에 대해 조언을 할 수 있어야 한다. 논의에 도움이 되는 몇 가지 권고안을 도출할 수 있었다.

 

현재의 성능을 기준으로 목표치를 설정하지 말 것

시스템의 장점과 한계를 이해하는 것이 기본이므로 이것을 고려하지 않고 목표치를 설정하면 시스템에 엄청난 노력을 투입하게 되고 결국 방대한 재설계 없이는 시스템의 향상이 불가능하게 된다.

현재의 성능에 비해, 갈 수록 사용자들의 의존성이 높아지고 성능은 낮아지게 된다는 전제가 깔려있는 것으로 보인다. 그러므로 현재 성능만을 바라보지 말고, 시스템의 한계를 객관적으로 이해하는 것이 좋다고 이해했다.

 

최대한 단순하게 생각할 것 

SLI를 복잡하게 집계하면 시스템의 성능 변화를 명확하게 반영하지 못하고 그 원인을 파악하기 어렵게 된다.

단순하게 생각해서 집계하고, 그 데이터로 유의미한 Complex한 결과를 도출하는 과정이라고 생각한다. 직교성을 높인 데이터 집계가 필요하다는 뜻이 아닐까?

 

자기 만족에 얽매이지 말 것

응답 시간의 저하 없이 시스템의 부하를 '무한정' 확장하는 것은 상당히 매력적인데다가 '언제든지' 가능하기는 하지만 사실 이런 요구는 현실성이 없다. 이런 이상을 실현 가능한 시스템은 디자인하고 구축하는 데 긴 시간을 필요로 할 뿐 아니라 운영 비용도 엄청나다. 게다가 오버스펙일 것이다.

 

가능한 적은 수의 SLO를 설정할 것

시스템의 특성을 잘 확인할 수 있는 최소한의 SLO를 선택하는 것이 중요하다. 그리고 선택한 SLO를 옹호할 수 있어야 한다. 제품의 모든 특성이 SLO로 선정하기에 적합한 것은 아니다. SLO를 이용해서 '사용자의 만족'을 정의하는 것은 상당히 어렵다.

 

처음부터 완벽하게 하려고 하지 말 것

SLO의 정의와 목표는 시간이 지남에 따라 시스템의 동작을 살피면서 언제든지 다시 정의할 수 있다. 처음부터 지나치게 높은 목표를 설정해서 나중에 가서야 달성이 불가능한 것을 발견하고 완화하는 것보다는 우선은 조금 느슨한 목표를 설정한 후 조금씩 강화하는 것이 낫다. 

 

잘 설정된 SLO는 유용하며, 개발팀에게 어떤 기능을 정당하게 요구할 수 있는 토대가 된다. 하지만 SLO를 제대로 설정하지 못하면 지나치게 높은 SLO를 달성하기 위해 팀이 엄청난 노력을 투자하게 될 수도 있고, 너무 낮은 수준의 SLO 때문에 형편없는 제품이 만들어질 수도 있다. 현명하게 활용하자
전반적으로 점진적으로 완성도를 높여가도록 이야기하고 있다. 이를 위한 유의미한 주기적 모니터링, 체크를 통한 대비를 추천하고 있다. 프로덕션에서는 너무 완벽한 목표를 설정하는 것은 말이 안된다고 이야기하고 있다. 100%가 불가능하다고 말하는 이유다.

 

측정하기

SLI와 SLO는 시스템을 관리하는 데 사용되는 제어 루프의 핵심 요소다. 

  1. 시스템의 SLI들을 모니터하고 측정하기
  2. SLI를 SLO와 비교해서 별도의 대응이 필요한지 판단하기
  3. 대응이 필요한 경우 목표치를 달성하기 위해 어떻게 대응할지 파악하기
  4. 대응하기

예를 들어 두 번째 단계에서 응답 지연시간이 증가하고 있어서 아무런 대응을 하지 않을 경우 몇 시간 내에 SLO를 달성하지 못할 것이라고 보여지면 세 번째 단계에서는 부하 분산을 위해 CPU를 더 추가해야 한다는 결정을 내리기 위한 테스트가 포함되어야 한다. 

 

SLO를 설정하기 않았다면 대응을 해야 할지 말아야 할지 판단할 수 없을 것이다.

 

SLO는 기대치를 설정하는 것

결국 SLO는 동작에 대한 기대치를 설정하는 것이다. 사용자의 자신들에게 적합한 서비스인지를 판단하기 위해 어떤것을 서비스에 기대할 수 있는지를 알고 싶어한다. 

 

그러므로 현실적인 사용자의 기대치를 설정해야한다. 이를 위해 아래의 두 가지 중 하나 혹은 모두를 고려해야 한다.

안전 제한선을 지킬 것

사용자에게 광고한 SLO보다는 내부적으로 더 보수적으로 설정된 SLO를 지키면 만성적으로 발생하는 문제들이 외부로 노출되기 전에 대응할 수 있는 여력을 가질 수 있다. 재구현의 기회를 가질 수 있다는 뜻이다.

 

지나친 목표를 설정하지 말 것

서비스의 실제 성능이 공개된 SLO를 훨씬 웃돈다면 더 많은 서비스의 현재 성능에 계속 의존하게 될 것이다. 이런 경우 의도적으로 시스템이 다운되게 하거나, 요청 수를 제한하거나 부하가 낮은 상황에서도 아주 빠르게 동작하지 않도록 시스템을 디자인해서 의존도가 높아지는 것을 방지할 수 있다.

 

결국 현재 시스템의 상황을 잘 판단하기 위한 과정이 SLI, SLO를 정하는 것이라고 생각한다. 상황을 잘 알고 있고, 이해하고 있어야 시스템을 더 빠르고, 가용성이 뛰어나며, 더 탄력적으로 만들기 위한 투자를 할 것인지를 판단하는 데 도움이 된다. 혹은 잘 동작하고 있다고 판단하고, 기술 부채를 해결하거나 기능 추가, 다른 제품 개발 등의 우선순위가 더 높은 작업에 투입하는 판단을 내릴 수도 있다.

 

협약에 대한 실습

SLA를 수립하려면 사업부와 법무팀이 위반하는 경우 적절한 보상과 댓가를 수립해야 한다. SRE의 역할은 SLA에 명시된 SLO를 달성하는 데 있어서의 어려움과 가능성을 이해하도록 돕는 것이다. 사용자에게 공개하는 내용은 조금 보수적으로 설정하는 편이 좋다. 사용자 층이 두터워질수록 SLA를 변경하거나 삭제하기가 더 어려워지기 때문이다.