관측성 · SLI 를 무엇으로 셀 것인가 · 이론
분모를 바꾸면 가용성이 바뀐다
한 줄 요약
SLI 는 쿼리가 아니라 정의다. 무엇을 좋은 사건으로 세고 무엇을 유효한 사건으로 셀지를 정하는 일이 숫자의 대부분을 결정한다.
왜 이게 필요했나
장애 회의에서 가장 자주 나오는 문장은 "우리 가용성은 몇 퍼센트였나" 다. 그런데 같은 12시간 자료를 놓고 세 사람이 각각 98.9%, 97.7%, 97.2% 를 들고 온다. 셋 다 계산은 맞다. 다른 질문에 답했을 뿐이다.
첫 사람은 5xx 응답만 실패로 셌다. 두 번째 사람은 400 대 응답도 실패로 셌다. 세 번째 사람은 요청이 아니라 분(分) 을 셌다 — 1분 동안 오류 비율이 기준을 넘으면 그 1분을 통째로 나쁜 분으로 본 것이다.
이 차이는 말장난이 아니라 돈과 사람의 시간이 걸린 차이다. 정의가 느슨하면 에러 버짓이 남아 있는 것처럼 보여 위험한 배포가 통과하고, 정의가 지나치게 빡빡하면 아무 일도 없는 밤에 사람이 깨어난다. 그래서 목표(SLO)를 몇 퍼센트로 걸 것인가보다 무엇을 셀 것인가 를 먼저 합의해야 한다.
어떻게 동작하나
Google SRE Workbook 은 SLI 를 한 문장으로 적는다 — 유효한 사건 중 좋은 사건의 비율. 그래서 정의를 쓸 때는 세 칸을 채워야 한다.
| 칸 | 정하는 것 | 흔한 실수 |
| --- | --- | --- |
| 사건(event) | 무엇을 하나로 셀 것인가 | 요청과 시간 창을 섞어 쓴다 |
| 좋은 사건(good) | 무엇을 성공으로 볼 것인가 | 상태 코드만 보고 느린 성공을 성공으로 센다 |
| 유효한 사건(valid) | 무엇을 분모에 넣을 것인가 | 헬스체크·봇·내부 호출까지 분모에 넣는다 |
세 칸 중 하나만 바꿔도 숫자가 바뀐다. 특히 분모가 무섭다. 초당 여섯 번씩 도는 헬스체크를 분모에 넣으면, 사용자가 겪는 실패가 헬스체크 성공에 희석돼 장애가 소수점 아래로 밀려난다. 반대로 분모를 사용자 여정 하나로 좁히면 같은 사고가 훨씬 크게 보인다.
사건의 단위를 요청에서 시간으로 바꾸면 성질 자체가 달라진다. 요청 기준은 트래픽이 많은 시간대의 사고에 더 큰 벌점을 준다. 시간 기준은 새벽 두 시의 20분 장애와 낮 두 시의 20분 장애를 똑같이 20분으로 센다. 어느 쪽이 옳은가는 서비스가 사용자에게 무엇을 약속했는가에 달렸다.
지연을 성공 조건에 넣을 때는 히스토그램의 한계를 알아야 한다. 요청 수 카운터에는 상태 코드 라벨이 있지만, 지연 히스토그램에는 대개 없다. 그러면 "200 이면서 100밀리초 안에 끝난 요청" 을 한 쿼리로 셀 수 없다. 두 신호를 곱해서 쓰려면 지표를 그렇게 내보내도록 계측을 고쳐야 한다 — 정의가 계측을 결정하는 순간이다.
측정하는 자리도 정의의 일부다. 같은 요청을 애플리케이션 안에서 재느냐, 앞단 프록시에서 재느냐, 브라우저에서 재느냐에 따라 숫자가 달라진다. 애플리케이션 안에서 재면 연결이 끊겨 응답이 사용자에게 닿지 못한 경우가 성공으로 남고, 프록시에서 재면 프록시 자신이 죽은 시간이 기록에서 통째로 사라진다. 어느 자리에서 재든 그 자리가 보지 못하는 실패가 무엇인지 함께 적어 두어야 나중에 숫자를 믿을 수 있다.
기간을 어떻게 끊을지도 정해야 한다. 달력 기준(매월 1일에 예산이 초기화됨)은 계약서에 쓰기 좋지만 월말에 몰아서 위험한 배포를 하게 만든다. 굴러가는 창(최근 30일)은 그런 벼락치기를 막는 대신 지난 사고가 한 달 동안 따라다닌다. 둘 다 맞는 선택이 있는 것이 아니라, 어느 쪽이 팀의 행동을 원하는 방향으로 바꾸는지로 고른다.
마지막으로, SLI 를 여러 개 만들어 하나로 평균 내지 않는다. 가용성과 지연과 정확성은 서로 다른 약속이라 평균을 내면 어느 약속도 지키지 않으면서 숫자만 좋아 보이는 상태가 만들어진다. 각각을 따로 재고, 각각에 목표를 걸고, 각각의 예산을 따로 소진시키는 편이 훨씬 다루기 쉽다. 여러 SLI 를 한 숫자로 묶고 싶다는 요구는 대개 보고서를 짧게 만들고 싶다는 뜻인데, 그 요구를 들어주는 순간 어느 약속이 깨졌는지 아무도 알 수 없게 된다.
현장에서 만나는 모습
결제 서비스에서 한 번은 이런 일이 있었다. 대시보드의 가용성은 99.9% 를 넘고 있는데 고객 문의는 계속 들어왔다. 분모에 내부 배치 호출이 들어 있었고, 그 호출이 전체의 절반이었다. 사용자 요청만 분모로 좁히자 같은 시간의 가용성이 99.2% 로 떨어졌다. 숫자가 나빠진 것이 아니라 그제야 맞는 숫자가 나온 것이다.
반대 방향의 사고도 흔하다. 어떤 팀은 "느린 것도 실패" 라는 원칙을 세우고 임계값을 100밀리초로 잡았다. 그 순간 가용성이 85% 로 내려앉았고, 에러 버짓이 매일 아침 소진돼 배포가 영영 막혔다. 임계값이 사용자의 체감이 아니라 담당자의 취향에서 나왔기 때문이다. 정의를 바꿀 때는 그 정의로 지난 30일을 다시 재 보고, 그 숫자로 살 수 있는지부터 확인해야 한다.
다음 실습에서 할 것
파드의 Prometheus 에 들어 있는 12시간치 자료로 네 가지 SLI 를 직접 계산한다. 요청 기준으로 5xx 만 실패로 세고, 400 대까지 실패로 세고, 지연 100밀리초를 성공 조건에 넣고, 마지막으로 1분 창을 사건으로 세어 본다. 네 숫자가 얼마나 벌어지는지 보고 30일 허용 다운타임으로 환산한 뒤, 하나를 골라 기계가 읽을 수 있는 형식으로 선언하고 두 가지 목표에서 배포를 허용할지 막을지 판단한다.