SLO burn rate 알림 튜닝하다가 새벽에 두 번 깨진 이야기
지난달 얘기다. 우리 팀 결제 API에 SLO를 새로 걸었고, burn rate 알림도 같이 설정했다. Google SRE 워크북에 나온 그 유명한 멀티 윈도우, 멀티 burn rate 알림 말이다. 문서 그대로 따라 붙였으니 잘 돌 줄 알았는데, 첫 주에만 새벽에 두 번 깨졌다. 둘 다 진짜 장애는 아니었다.
처음 걸었던 설정
우리 SLO는 30일 창(window) 기준 가용성 99.9%다. 워크북에서 권장하는 대로 두 개 알림을 걸었다.
- alert: HighErrorBudgetBurnFast
expr: |
(
job:slo_errors_ratio:rate1h{job="payment-api"} > (14.4 * 0.001)
and
job:slo_errors_ratio:rate5m{job="payment-api"} > (14.4 * 0.001)
)
for: 2m
labels:
severity: page
- alert: HighErrorBudgetBurnSlow
expr: |
(
job:slo_errors_ratio:rate6h{job="payment-api"} > (6 * 0.001)
and
job:slo_errors_ratio:rate30m{job="payment-api"} > (6 * 0.001)
)
for: 15m
labels:
severity: ticket
14.4는 30일 예산의 2%를 1시간 만에 태우는 속도, 6은 6시간 동안 5%를 태우는 속도다. 워크북 표에 그대로 나와 있다.
새벽 3시, 첫 번째 페이지
배포 다음 날 새벽에 페이지가 왔다. 로그인해서 대시보드를 봤는데, 에러율은 이미 정상으로 돌아와 있었다. 정확히 새벽 2시 47분에서 2시 52분 사이에 5xx가 몇십 건 튀었고, 그 뒤로 잠잠했다.
이게 왜 페이지까지 왔을까? 계산을 해보니 답이 나왔다. 우리 결제 API 새벽 트래픽은 초당 3~5 요청 수준이다. 5분 동안 총 요청이 1000건 정도. 여기서 5xx가 30건만 나와도 5분 rate는 3%까지 튄다. 14.4 * 0.001 = 1.44% 임계값을 가볍게 넘긴다.
낮에는 초당 200~300 요청이니까 같은 30건이 나와도 5분 rate가 0.03% 수준이다. 알림이 안 뜬다. 근데 새벽엔 요청 자체가 적어서 절대적으로 작은 오류도 rate가 크게 나오는 거다. Google SRE 문서에서도 저트래픽 시스템은 이 방식이 잘 안 맞을 수 있다고 짧게 언급하는데, 우리 팀 상황이 딱 그거였다.
두 번째 페이지, 그리고 진짜 원인
이틀 뒤에 또 새벽에 페이지가 왔다. 이번에는 좀 달랐다. payment-worker-3 파드 하나가 CrashLoopBackOff 상태로 5분 정도 재시작을 반복하다가 스스로 회복됐다. 그동안 이 파드로 라우팅된 요청이 다 실패했고, 새벽 트래픽이라 다른 파드가 부담을 흡수했어도 실패 자체는 남았다.
이 케이스는 사실 알림이 온 게 맞다. 파드 하나가 죽었다 살아난 걸 감지한 거니까. 근데 문제는 페이지를 받을 만한 수준이었냐는 거다. 사용자 영향은 5분간 새벽 트래픽의 극히 일부. 정상 회복까지 자동으로 됐다. 이건 새벽 3시에 사람이 깨서 봐야 할까? 아니다.
그래서 뭘 바꿨나
두 번의 삽질 뒤에 세 가지를 손댔다.
첫째, 저트래픽 구간에는 최소 요청 수 조건을 추가했다. 5분 rate 알림에 and rate(http_requests_total[5m]) > 1 같은 조건을 붙였다. 요청이 아예 없다시피 하면 rate 계산 자체가 의미 없기 때문이다.
expr: |
(
job:slo_errors_ratio:rate1h{job="payment-api"} > (14.4 * 0.001)
and
job:slo_errors_ratio:rate5m{job="payment-api"} > (14.4 * 0.001)
and
rate(http_requests_total{job="payment-api"}[5m]) > 2
)
둘째, page 임계값을 조금 완화했다. 14.4 대신 20으로 올렸다. 워크북 표에는 없는 값이지만, 우리 SLO는 30일 기준 99.9%니까 20 burn rate면 30일 예산의 약 2.8%를 1시간에 태우는 속도다. 이 정도는 진짜 심각한 상황일 때만 나온다.
셋째, HighErrorBudgetBurnSlow는 slack 채널로만 알림 가게 severity를 낮췄다. 이건 원래 티켓 수준이었는데, 알림 노이즈 줄이려고 아예 페이지에서 제외했다.
아직 완벽하진 않다
이렇게 바꾸고 2주가 지났는데 새벽 알림은 안 왔다. 근데 이게 튜닝을 잘한 건지, 아니면 진짜 장애가 없었던 건지는 아직 모르겠다. 트래픽이 낮은 시간대에 진짜 장애가 발생했을 때 이 조건들이 잘 잡아낼지는 다음 사고가 나봐야 안다.
한 가지 배운 건, SRE 워크북 예제는 초당 수천 요청 오는 서비스를 가정하고 쓰여 있다는 거다. 우리처럼 새벽엔 초당 3 요청 오는 서비스에 그대로 붙이면 저런 새벽 3시 이벤트가 반복된다. 트래픽 프로파일에 맞게 임계값이랑 최소 요청 조건을 손봐야 한다.
혹시 저트래픽 서비스 SLO 알림 다른 방식으로 푸신 분 있으면 어떻게 하셨는지 궁금하다. 합성 트래픽(synthetic monitoring)으로 최소 요청 수를 인위적으로 만드는 방법도 고민 중인데 아직 결정 못 했다.
태그: SRE, SLO, 프로메테우스, burn-rate, 알림튜닝, 인시던트