SLO 란? 에러 버짓과 번 레이트로 배포를 멈추는 법

요약

SLO는 특정 사용자 동작이 고정된 기간 동안 얼마나 안정적이어야 하는지를 정한 목표입니다. 100%와 목표치 사이의 차이가 에러 버짓입니다. 버짓이 남아 있으면 배포하고, 바닥나면 기능 개발을 멈춥니다. 번 레이트 알림은 SLI 자체가 아니라 버짓 소모 속도에 반응하며, SLO 게이트는 릴리스를 스스로 되돌리게 합니다.

야간 엔지니어링 데스크에서 서비스 신뢰성 그래프를 보여주는 모니터 두 대

SLO 란 무엇인가요? 서비스 수준 목표(SLO)는 특정 사용자 대상 동작이 고정된 기간 동안 얼마나 안정적이어야 하는지를 정한 목표치입니다. "30일 동안 체크아웃 요청의 99.9%가 800ms 안에 성공한다"는 SLO입니다. "사이트가 빨라야 한다"는 바람일 뿐입니다. 숫자 자체보다 중요한 것은 그 숫자가 무엇을 통제하느냐입니다. SLO는 언제 계속 배포하고 언제 멈출지를 결정합니다.

03시 12분입니다. PagerDuty가 체크아웃 지연이 "상승 중"이라고 알립니다. 대시보드를 열어 보니 p99 선이 40분째 천천히 올라가고 있습니다. 이것이 문제인지 아무도 말해 주지 못합니다. 어느 정도면 너무 느린지 누구도 적어 둔 적이 없기 때문입니다. 통화 중에 한쪽 눈으로 Slack을 확인하며 이어지는 그 논쟁이, SLO가 없을 때 치르는 대가입니다.

온콜 알림이 울리는 밤, 침대 머리맡에서 빛나는 휴대폰

SLI, SLO, SLA: 세 단어, 세 책임자

사람들은 이 말을 같은 뜻으로 섞어 씁니다. 실제로는 서로 다른 개념이고, 이것을 혼동하면 지킬 수 없는 계약을 떠안게 됩니다.

SLO를 다룬 Google SRE 책의 장도 같은 선을 긋습니다. SLO는 외부에 약속하는 어떤 수치보다 더 엄격한 내부 목표입니다. SLI와 SLO는 엔지니어링 팀이 소유하고, SLA는 제품팀과 법무팀이 소유합니다.

이미 수집하고 있는 지표마다 네 번째 단어를 새로 붙일 필요는 없습니다. CPU, 메모리, 큐 깊이는 디버깅에는 유용하지만, 고객이 직접 겪는 값이 아니므로 SLI가 아닙니다.

실무에서 좋은 SLI는 어떤 모습인가

좋은 SLI는 비율이고, 가능한 한 사용자 가까이에서 측정하며, '좋음'의 정의가 분명합니다.

요청 기반 서비스라면 기본은 SLI 두 개입니다. 가용성(유효한 요청 중 5xx가 아닌 응답의 비율)과 지연 시간(유효한 요청 중 임계값 안에 끝난 비율)입니다. 평균이 아니라 임계값을 쓰세요. 평균은 꼬리를 숨기고, 지원 티켓은 대개 그 꼬리에서 나옵니다.

로드 밸런서나 엣지에서 측정하고, 서비스 내부에서 재지 마세요. 시작할 때 크래시가 나는 서비스는 받지도 못한 요청에 대해 완벽한 에러율을 보고합니다. 서버 쪽 지표는 이 장애를 보지 못하지만, 사용자는 이를 그대로 장애로 겪습니다.

제외 대상도 분명히 적어 두세요. 헬스 체크, 자체 모니터링의 합성 프로브, 잘못된 클라이언트 입력 때문에 생긴 4xx 응답은 보통 점수에서 빼야 합니다. 제외 규칙은 SLO 옆에 적어 두세요. 장애 리뷰에서 숫자를 두고 다툴 때, 논쟁은 대시보드에 무엇이 보이는지가 아니라 정의를 두고 벌어져야 합니다.

9를 고르기 전에 아무도 하지 않는 계산

9가 하나 늘 때마다 허용 다운타임은 10분의 1로 줄어듭니다. 문서에 남겨 둘 표는 이것입니다.

마지막 줄을 다시 읽어 보세요. 99.99%에서는 감지하고 되돌리는 데 5분이 걸리는 배포 한 번으로 한 달치 버짓이 이미 날아갑니다. 사람이 호출을 받고, 노트북을 열고, 4분 안에 롤백하는 것은 어렵습니다. 그러니 이 목표는 자동화로만 도달할 수 있습니다. 버짓이 바닥나기 전에 롤아웃을 멈추는 자동 게이트가 필요합니다.

그러니 서비스에 실제로 필요한 숫자를 고르세요. 대부분의 내부 API는 99.9%에서 무리 없이 돌아갑니다. 결제 경로라면 더 높여도 정당합니다. 야간에 도는 배치 작업은 99%면 충분할 수 있습니다. 그럴듯해 보인다는 이유로 99.99%를 고르면, 인원이 채워지지 않는 온콜 로테이션에 스스로를 묶는 셈입니다.

모래가 거의 다 떨어진 모래시계, 에러 버짓을 상징

에러 버짓이 핵심이다, SLO 숫자가 아니라

SLO가 99.9%라는 것은 0.1%까지 실패해도 된다는 뜻입니다. 이 0.1%가 에러 버짓이며, 이 분야 전체에서 가장 유용한 개념입니다.

버짓은 논쟁을 숫자로 바꿉니다. 제품팀은 위험한 마이그레이션을 내보내고 싶어 하고, SRE는 위험하다고 말합니다. 버짓이 없으면 의견끼리의 대립이고, 결국 연차가 이깁니다. 버짓이 있으면 질문이 바뀝니다. 얼마나 남았는가, 그리고 이번 변경이 그것을 얼마나 태울 것 같은가?

이 방식이 작동하려면 두 가지 규칙이 필요합니다.

  1. 버짓이 남아 있으면 배포합니다. 위험을 감수해도 되니 감수하세요. 버짓을 한 번도 쓰지 않는 팀은 사용자가 요구하지 않은 신뢰성에 과투자하고 있는 것입니다.

  2. 버짓이 바닥나면 동결합니다. 신뢰성 작업으로 SLI가 목표 위로 돌아올 때까지 기능 개발을 멈춥니다. 이 규칙은 첫 장애가 나기 전에 경영진이 합의해 둔 경우에만 성립합니다. 장애가 한창일 때 합의하면 소용없습니다.

두 번째 규칙을 미리 합의하지 않았다면, 그것은 SLO가 아닙니다. 초록색과 빨간색 구역이 있는 대시보드일 뿐입니다.

SLI 자체가 아니라 번 레이트에 알림을 걸어라

대부분의 첫 시도가 여기서 무너집니다. 가용성이 99.9% 아래로 떨어지면 알림을 걸어 두는 식입니다. 그러면 알림은 피해가 이미 생긴 뒤에 울리거나, 사소한 흔들림마다 울리거나, 둘 다 합니다.

더 나은 신호는 번 레이트입니다. 버짓이 얼마나 빠르게 소진되는지를, 기간 끝에 정확히 바닥나는 속도와 비교한 값입니다. 번 레이트 1은 한 달 끝에 버짓이 0이 된다는 뜻입니다. 번 레이트 14.4는 약 이틀 만에 한 달치 버짓을 태운다는 뜻입니다.

SLO 알림을 다룬 Google SRE 워크북은 긴 창과 짧은 창을 짝지어, 알림이 의미가 있으면서도 아직 진행 중인 상태만 잡도록 권합니다. 30일 SLO라면 시작점으로 두 가지 페이지 알림이 적당합니다.

계산은 단순합니다. 30일 창은 720시간입니다. 14.4배 속도로 1시간 동안 타면 14.4 / 720 = 버짓의 2%를 씁니다. 짧은 창은 문제가 이미 끝난 뒤에도 한 시간 동안 알림이 울리는 일을 막아 줍니다.

첫 번째 규칙을 Prometheus 알림으로 쓰면 다음과 같습니다. 창마다 에러 비율을 기록하고 있다고 가정합니다.

groups:
  - name: checkout-slo-burn
    rules:
      - alert: CheckoutErrorBudgetFastBurn
        expr: |
          job:checkout_error_ratio:rate1h > (14.4 * 0.001)
          and
          job:checkout_error_ratio:rate5m > (14.4 * 0.001)
        labels:
          severity: page
        annotations:
          summary: "체크아웃이 30일 에러 버짓을 시간당 2%씩 소모하고 있습니다"

0.001은 99.9% SLO에서 허용되는 에러 비율입니다. 목표를 바꾸면 이 상수도 함께 바뀌어야 합니다. 한 곳에서만 관리하세요. 그렇지 않으면 알림과 SLO가 아무도 모르게 어긋납니다.

느린 번에는 페이지가 필요 없습니다. 3일 동안 지속되는 번 레이트 1은 다음 근무일 아침에 처리할 티켓 감입니다. 느린 누수 때문에 사람을 깨우면, 온콜 팀은 페이저를 무시하는 법을 배우게 됩니다.

상태 표시등이 켜진 서버 랙이 늘어선 데이터센터 통로

두 번째 플랫폼을 사지 않고 SLI를 계산하는 곳

시작하는 데 전용 SLO 제품은 필요 없습니다. 좋은 이벤트 카운터, 전체 이벤트 카운터, 그리고 그 값을 30일 동안 보관할 곳이 있으면 충분합니다.

이미 호스팅 플랫폼에 지표를 두고 있다면, SLO 기능은 보통 이미 돈을 내고 쓰는 데이터 위에 얇게 얹힌 층일 뿐입니다.

Datadog은 번 레이트 알림을 포함한 SLO를 기본으로 제공합니다. 트레이스와 지표가 이미 거기 있다면 가장 쉬운 길입니다. 다만 비용이 함정입니다. 커스텀 메트릭과 고카디널리티 태그는 빠르게 늘어나므로, 약정하기 전에 SLI 시리즈의 가격부터 확인하세요.

Prometheus를 쓴다면 Grafana가 recording rule과 SLO 도구로 같은 영역을 다룹니다. 설정과 직접 쏟는 시간이 더 필요합니다.

정직한 비교 기준은 첫 쓸모 있는 알림까지 걸리는 시간과 규모에서의 비용입니다. 첫 번째는 Datadog이, 두 번째는 대개 Prometheus와 Grafana가 이깁니다. 팀에 무엇이 부족한지에 따라 고르세요.

대부분의 팀이 건너뛰는 부분: SLO를 롤아웃에 연결하기

보고서만 만드는 SLO는 절반만 쓰는 것입니다. 행동을 실제로 바꾸는 단계는 버짓을 배포 경로에 연결해서, 릴리스가 스스로 멈추게 만드는 것입니다.

SLO 게이트가 있는 점진적 롤아웃은 이렇게 작동합니다. 플래그 뒤에서 트래픽 1%에 배포합니다. 그 코호트의 SLI를 기준선과 비교해 지켜봅니다. 카나리 코호트의 번 레이트가 임계값을 넘으면 자동으로 되돌립니다. 괜찮다면 5%, 25%, 100%로 올립니다.

이것은 03시 12분에 누군가 지켜보고 있어야 하는 대시보드와는 다릅니다. 03시 12분에는 생각하고 싶지 않습니다. 버튼이 필요하고, 더 좋게는 버튼조차 필요 없어야 합니다.

여기서 기능 플래그가 가치를 증명합니다. 플래그가 있으면 되돌리기가 재배포(10분)가 아니라 몇 초짜리 설정 변경이 됩니다.

LaunchDarkly 같은 플랫폼은 비율 롤아웃과 킬 스위치를 제공합니다. 대부분이 사람에게 남겨 두는 것은 결정입니다. 어떤 SLI를 읽을지, 어떤 임계값을 나쁨으로 볼지, 누가 이를 재정의할 수 있는지입니다. SLO 기반 자동 롤백 파일럿이 메우려는 틈이 바로 이것이며, upstreamapi가 취하는 각도도 그렇습니다. SDK 범위와 엔터프라이즈 통제 기능에서는 LaunchDarkly이 앞서며, 그 점은 그대로 인정합니다.

게이트의 형태를 TypeScript로 보면 다음과 같습니다. 어떤 플래그 시스템을 쓰든 직접 작성할 가치가 있는 부분은 판단 로직입니다.

type Cohort = { good: number; total: number };

const SLO_TARGET = 0.999;
const BUDGET = 1 - SLO_TARGET; // 0.001
const PAGE_BURN_RATE = 14.4;

function burnRate(c: Cohort): number {
  if (c.total === 0) return 0;
  const errorRatio = 1 - c.good / c.total;
  return errorRatio / BUDGET;
}

export function rolloutDecision(canary: Cohort): "advance" | "hold" | "revert" {
  if (canary.total < 500) return "hold"; // 판단하기에 트래픽이 부족함
  return burnRate(canary) > PAGE_BURN_RATE ? "revert" : "advance";
}

hold 분기에 주목하세요. 한적한 서비스의 1% 카나리는 10분 동안 요청이 40개뿐일 수 있고, 40개 중 에러 1개는 2.5% 에러율입니다. 최소 표본이 없으면 게이트는 잡음에 반응해 되돌리고, 팀은 게이트를 믿지 않게 됩니다.

80명 규모 팀에서 반복되는 실수와 이번 주에 쓸 첫 SLO

여러 팀에서 같은 몇 가지 실패가 반복되는데, 기술적인 문제인 경우는 거의 없습니다.

프로그램을 만들 필요는 없습니다. 무너지면 CEO가 누군가에게 전화를 걸게 만드는 사용자 여정 하나를 고르세요. 그 여정에 대해 가용성 SLI 하나와 지연 SLI 하나를 정의합니다. 첫 분기 목표는 99.9%로 잡고, 동결 정책을 두 문장으로 적고, 제품팀이 서면으로 "동의"라고 답하게 하세요.

그다음 번 레이트 알림과, 팀 전체가 남은 버짓을 볼 수 있는 곳을 추가하세요.

전면적인 플랫폼을 도입하기 전에 가볍게 시작할 곳이 필요하다면 Better Stack이 가동 시간 모니터링과 장애 호출을 훨씬 작은 설정으로 처리합니다. 다만 버짓 계산은 공짜로 해주지 않습니다.

첫 버전은 틀릴 것입니다. 괜찮습니다. 중요한 것은 다음 장애 리뷰가 느낌이 아니라, 미리 적어 둔 숫자에서 시작되는 것입니다. 지난번 팀이 겪은 장애를 떠올려 보세요. 그것이 중요한지 말해 주는 숫자가 적혀 있었나요? 아니라고 답한다면, 그것이 여러분의 첫 SLO이고, 사후 분석이 이미 무엇을 측정해야 하는지 알려 주고 있습니다.

자주 묻는 질문

SLO란 간단히 무엇인가요?
SLO는 고정된 기간 동안 특정 사용자 대상 동작에 대한 신뢰성 목표입니다. 예를 들어 30일 동안 요청의 99.9%가 성공하는 것입니다. 허용되는 실패의 양과 배포를 멈출 시점을 팀에 알려 줍니다.
SLI, SLO, SLA의 차이는 무엇인가요?
SLI는 측정값으로, 좋은 이벤트 대 유효한 이벤트의 비율입니다. SLO는 그 비율에 대한 내부 목표입니다. SLA는 위반 시 보상금이 붙는 고객 계약이며, 항상 SLO보다 느슨해야 합니다.
99.9%는 다운타임을 얼마나 허용하나요?
30일 기준으로 99.9%는 전체 중단 43.2분을 허용합니다. 99%는 7.2시간, 99.95%는 21.6분, 99.99%는 4.32분을 허용합니다.
에러 버짓이란 무엇인가요?
에러 버짓은 100%에서 SLO 목표를 뺀 값입니다. 99.9%에서는 이벤트의 0.1%입니다. 버짓이 남아 있으면 팀은 릴리스 위험을 감수할 수 있고, 버짓이 바닥나면 신뢰성이 회복될 때까지 기능 개발을 멈춥니다.
SLO 알림에서 번 레이트란 무엇인가요?
번 레이트는 기간 끝에 정확히 버짓을 다 쓰게 되는 속도와 비교해 에러 버짓을 얼마나 빨리 소모하는지를 나타냅니다. 번 레이트 14.4가 1시간 지속되면 30일 버짓의 2%를 소모합니다.
서비스마다 SLO는 몇 개가 적당한가요?
핵심 사용자 여정 하나당 두세 개면 충분하며, 보통 가용성 SLI 하나와 지연 SLI 하나입니다. 그보다 많으면 아무도 기억하지 못해 어떤 결정도 바꾸지 못합니다.
처음에는 어떤 SLO 목표로 시작해야 하나요?
가장 중요한 사용자 여정 하나에 99.9%로 시작하세요. 분기가 지난 뒤 검토하고, 현재 성능이 아니라 사용자가 문제를 느끼기 시작하는 수준에 맞추세요.