同じ 12 時間なのに可用性が 98.9% と 85.0% に割れた
한국어 원문으로 표시합니다.
목표
같은 12시간 자료를 네 가지 SLI 정의로 직접 재서 숫자가 얼마나 벌어지는지 보고, 하나를 골라 목표와 함께 선언한 뒤 그 정의로 배포를 허용할지 막을지 판단합니다.
왜 중요한가
SLO 를 몇 퍼센트로 걸 것인가는 무엇을 셀 것인가가 정해진 뒤의 문제다. 좋은 사건과 유효한 사건을 어떻게 정하느냐에 따라 같은 자료에서 98.9% 도 나오고 85.0% 도 나온다. 분모에 헬스체크를 넣으면 사용자가 겪은 장애가 희석되고, 느린 성공을 성공으로 세면 사용자가 떠난 시간이 기록에 남지 않는다. 사건의 단위를 요청에서 시간으로 바꾸면 새벽의 장애와 낮의 장애를 같은 무게로 세게 된다. 이 선택들은 나중에 배포를 막느냐 마느냐로 돌아오므로, 정의를 바꿀 때마다 지난 기간을 다시 재 보고 그 숫자로 살 수 있는지 확인하는 습관이 필요하다.
단계
/root/obs-sli-events/01-events.txt에 세 줄을 적으세요.metric=뒤에는 사건을 세는 데 쓸 카운터 지표 이름,failure_label=뒤에는 그 지표에서 실패 여부를 가르는 라벨 이름,valid_12h=뒤에는 최근 12시간 동안의 유효한 사건 수를 정수로 적습니다(job 은 shop-api 입니다). 값은 직접 쿼리를 던져서 얻으세요./root/obs-sli-events/a-request.promql에 '최근 12시간 동안 5xx 가 아닌 요청의 비율' 을 내는 PromQL 을 한 줄 이상으로 쓰고, 그 결과를/root/obs-sli-events/a-request.txt에 소수 넷째 자리까지 숫자 하나로 적으세요. 주석(#)은 남겨도 됩니다.- 같은 12시간을 '2xx 응답만 좋은 사건' 으로 다시 재세요. 쿼리는
/root/obs-sli-events/b-strict.promql, 값은/root/obs-sli-events/b-strict.txt에 소수 넷째 자리까지 적습니다. 분모는 앞 단계와 같아야 합니다. - '100밀리초 안에 끝난 요청' 을 좋은 사건으로 보는 정의로 12시간을 재세요. 쿼리는
/root/obs-sli-events/c-latency.promql, 값은/root/obs-sli-events/c-latency.txt에 소수 넷째 자리까지 적습니다. 그리고/root/obs-sli-events/04-note.txt에 '이 정의로는 상태 코드와 지연을 한 쿼리로 함께 볼 수 없다' 는 사실과 그 이유를 한 줄로 적으세요 —reason=로 시작하고 40자 이상이어야 합니다. - 1분 창을 사건으로 삼는 정의로 같은 12시간을 재세요. 어떤 1분 안에서 5xx 비율이 1% 미만이면 그 1분을 좋은 사건으로 봅니다. 쿼리는
/root/obs-sli-events/d-window.promql, 값은/root/obs-sli-events/d-window.txt에 소수 넷째 자리까지 적습니다. 그리고/root/obs-sli-events/05-badminutes.txt에 12시간(720분) 중 나쁜 분이 몇 분인지 정수로 적으세요. /root/obs-sli-events/budget.tsv를 만드세요. 머리글 없이 네 줄이고, 각 줄은 탭으로 나눈 세 칸<id> <가용성> <30일 허용 다운타임 분>입니다. id 는 순서대로a,b,c,d이고, 가용성은 앞 단계에서 적은 값, 세 번째 칸은 그 가용성이라면 30일(43200분) 동안 나빠도 되는 시간이 몇 분인지를 소수 첫째 자리까지 적습니다./root/obs-sli-events/choice.txt에 네 줄을 적으세요.sli=뒤에 고른 id(a·b·c·d 중 하나),query=뒤에 그 정의의 쿼리 파일 이름(예:d-window.promql),target=뒤에 걸 목표를 0 과 1 사이 소수로,reason=뒤에 왜 그 정의인지 60자 이상으로 적습니다. 채점기는query=가 가리키는 파일을 실제로 던져sli=와 맞는지 확인합니다./root/obs-sli-events/decision.txt에 두 줄을 적으세요. 각 줄은target=<목표> consumed=<소진비율> release=<allow|hold>이고 목표는 첫 줄이0.99, 둘째 줄이0.95입니다. 소진비율은 (1 − 측정된 가용성) ÷ (1 − 목표) 로 소수 셋째 자리까지, 판단은 소진비율이 1 이상이면hold, 미만이면allow입니다. 측정된 가용성은 7단계에서 고른 정의의 값을 씁니다.
참고
- 작업 디렉터리는
/root/obs-sli-events입니다. 없으면 먼저 만드세요. - 쿼리는
promq "<PromQL>"로 바로 던져 볼 수 있고, 원본 JSON 은promq -r입니다. 스크립트에서는curl -sG --data-urlencode "query=..." http://127.0.0.1:9090/api/v1/query를 씁니다. - 파드의 Prometheus 에는 12시간치가 미리 들어 있습니다. 그 안에 20분짜리 오류 급증이 한 번 들어 있습니다.
- 흔한 실수: 카운터를 increase 없이 그대로 나누는 것. 카운터는 누적값이라 비율이 전체 기간 평균으로 뭉개집니다.
- 흔한 실수: 지연 히스토그램에 상태 코드 라벨이 있다고 가정하는 것. 이 실습의 4단계가 바로 그 벽입니다.
- Implementing SLOs (SRE Workbook) · Service Level Objectives (SRE Book 4장) · Querying basics · Query functions · Histograms and summaries
무엇을 하나로 셀 것인지부터 정한다
/root/obs-sli-events/01-events.txt 에 세 줄을 적으세요. metric= 뒤에는 사건을 세는 데 쓸 카운터 지표 이름, failure_label= 뒤에는 그 지표에서 실패 여부를 가르는 라벨 이름, valid_12h= 뒤에는 최근 12시간 동안의 유효한 사건 수를 정수로 적습니다(job 은 shop-api 입니다). 값은 직접 쿼리를 던져서 얻으세요.
어떤 지표가 있는지는 promq "{__name__=~\"http.*\"}" 나 curl -s http://127.0.0.1:9090/api/v1/label/__name__/values | jq 로 봅니다. 12시간 동안 늘어난 카운터 양은 increase 로 구합니다. 라벨 이름은 값이 아니라 이름만 적습니다.
요청 기준 — 5xx 만 실패로 센다
/root/obs-sli-events/a-request.promql 에 '최근 12시간 동안 5xx 가 아닌 요청의 비율' 을 내는 PromQL 을 한 줄 이상으로 쓰고, 그 결과를 /root/obs-sli-events/a-request.txt 에 소수 넷째 자리까지 숫자 하나로 적으세요. 주석(#)은 남겨도 됩니다.
카운터는 누적이므로 구간 증가량으로 바꿔야 합니다. 분자와 분모를 각각 sum 으로 합친 뒤 나눕니다. 5xx 를 고르는 라벨 매칭은 정규식 매처를 씁니다.
400 대도 실패로 세면 얼마나 달라지나
같은 12시간을 '2xx 응답만 좋은 사건' 으로 다시 재세요. 쿼리는 /root/obs-sli-events/b-strict.promql, 값은 /root/obs-sli-events/b-strict.txt 에 소수 넷째 자리까지 적습니다. 분모는 앞 단계와 같아야 합니다.
400 대는 대개 클라이언트 잘못이라 서비스의 실패로 세지 않는 편이지만, 인증 실패가 폭증하는 사고처럼 우리 책임인 4xx 도 있습니다. 정의를 바꾸면 숫자가 어느 쪽으로 움직이는지 보세요.
느린 성공은 성공인가
'100밀리초 안에 끝난 요청' 을 좋은 사건으로 보는 정의로 12시간을 재세요. 쿼리는 /root/obs-sli-events/c-latency.promql, 값은 /root/obs-sli-events/c-latency.txt 에 소수 넷째 자리까지 적습니다. 그리고 /root/obs-sli-events/04-note.txt 에 '이 정의로는 상태 코드와 지연을 한 쿼리로 함께 볼 수 없다' 는 사실과 그 이유를 한 줄로 적으세요 — reason= 로 시작하고 40자 이상이어야 합니다.
히스토그램의 버킷은 누적입니다. le 가 어떤 값인 버킷이 '그 값 이하로 끝난 요청 수' 인지 보세요. 분모로 쓸 전체 요청 수는 히스토그램의 count 계열에 있습니다. 두 지표의 라벨 집합이 서로 다르다는 점이 핵심입니다.
요청을 세지 말고 분을 세어 본다
1분 창을 사건으로 삼는 정의로 같은 12시간을 재세요. 어떤 1분 안에서 5xx 비율이 1% 미만이면 그 1분을 좋은 사건으로 봅니다. 쿼리는 /root/obs-sli-events/d-window.promql, 값은 /root/obs-sli-events/d-window.txt 에 소수 넷째 자리까지 적습니다. 그리고 /root/obs-sli-events/05-badminutes.txt 에 12시간(720분) 중 나쁜 분이 몇 분인지 정수로 적으세요.
부분 쿼리(subquery) [12h:1m] 로 1분 간격의 값을 만들고, 비교 연산자 뒤에 bool 을 붙이면 참이 1, 거짓이 0 인 계열이 됩니다. 그 계열의 평균이 곧 좋은 분의 비율입니다. 나쁜 분 수는 720 에서 거꾸로 셉니다.
네 정의를 30일 허용 다운타임으로 환산한다
/root/obs-sli-events/budget.tsv 를 만드세요. 머리글 없이 네 줄이고, 각 줄은 탭으로 나눈 세 칸 <id> <가용성> <30일 허용 다운타임 분> 입니다. id 는 순서대로 a, b, c, d 이고, 가용성은 앞 단계에서 적은 값, 세 번째 칸은 그 가용성이라면 30일(43200분) 동안 나빠도 되는 시간이 몇 분인지를 소수 첫째 자리까지 적습니다.
허용 다운타임은 (1 − 가용성) × 43200 입니다. 네 줄의 숫자가 얼마나 벌어지는지가 이 단계의 핵심입니다 — 정의 하나를 바꾸면 운영팀이 감당해야 하는 시간이 몇 배로 달라집니다.
고른 정의를 기계가 읽을 수 있게 선언한다
/root/obs-sli-events/choice.txt 에 네 줄을 적으세요. sli= 뒤에 고른 id(a·b·c·d 중 하나), query= 뒤에 그 정의의 쿼리 파일 이름(예: d-window.promql), target= 뒤에 걸 목표를 0 과 1 사이 소수로, reason= 뒤에 왜 그 정의인지 60자 이상으로 적습니다. 채점기는 query= 가 가리키는 파일을 실제로 던져 sli= 와 맞는지 확인합니다.
정답은 하나가 아닙니다. 다만 고른 근거가 앞 단계의 숫자와 이어져야 합니다 — 예를 들어 지연 기준을 고른다면 30일 허용 다운타임이 감당 가능한지 6단계 표에서 확인한 뒤 골라야 합니다.
같은 자료, 다른 목표 — 배포를 허용할 것인가
/root/obs-sli-events/decision.txt 에 두 줄을 적으세요. 각 줄은 target=<목표> consumed=<소진비율> release=<allow|hold> 이고 목표는 첫 줄이 0.99, 둘째 줄이 0.95 입니다. 소진비율은 (1 − 측정된 가용성) ÷ (1 − 목표) 로 소수 셋째 자리까지, 판단은 소진비율이 1 이상이면 hold, 미만이면 allow 입니다. 측정된 가용성은 7단계에서 고른 정의의 값을 씁니다.
소진비율 1 은 '이 기간에 쓸 수 있는 에러 버짓을 정확히 다 썼다' 는 뜻입니다. 같은 자료라도 목표를 어디에 거느냐에 따라 배포 결정이 뒤집힙니다 — 그래서 목표는 숫자가 아니라 합의입니다.