서비스 복구 시간
고친 사람 github-actions[bot]
서비스 복구 시간은 내보낸 변경이 서비스를 망가뜨렸을 때 되살리기까지 얼마나 걸리는지를 잽니다. 배포를 되돌리거나 급히 고쳐서 서비스가 다시 정상으로 도는 때까지를 셉니다. 자기가 내보낸 변경이 낸 실패만 봅니다. 밖에서 온 장애는 세지 않습니다.
쉽고 빠른 이해
서비스 복구 시간은 배포한 변경이 서비스를 망가뜨렸을 때 다시 돌아오기까지 걸린 시간입니다. 새 버전을 올린 뒤 결제가 멎었고 9분 만에 이전 버전으로 되돌려 결제가 살아났다면 그 9분입니다.
이 값이 없으면 「우리는 실패해도 금방 되돌린다」가 느낌으로만 남습니다. 되돌리기를 자동으로 만들어도 그 손질이 멎어 있던 시간을 줄였는지 확인할 방법이 없습니다.
도는 순서:
- 배포가 낸 실패만 세기로 정하고, 바깥에서 온 장애는 뺍니다
- 실패한 배포마다 서비스가 정상으로 돌아오기까지 걸린 시간을 적어 둡니다
- 정한 기간의 그 시간들을 모아 하나의 수로 봅니다
대가는 무엇을 실패로 셀지 사람이 정해야 한다는 것입니다. 작은 실패를 세지 않으면 수는 줄지만 서비스가 멎어 있던 시간은 줄지 않습니다.
상세
자동차에 새 부품을 갈아 끼웠습니다. 그런데 시동이 안 걸립니다. 서비스 복구 시간은 차가 다시 굴러가기까지 걸린 시간을 잽니다. 길에서 못이 박혀 타이어가 터진 일은 이 셈에 안 들어갑니다.
다만 차는 굴러가면 고쳐진 것이 분명합니다. 서비스는 어디까지를 돌아왔다고 할지 사람이 먼저 정해야 합니다.
세는 대상 — 배포가 낸 실패
서비스 복구 시간이 다른 복구 지표와 갈리는 곳은 세는 대상입니다. 자기가 내보낸 배포가 낸 실패에서 돌아오는 시간만 봅니다. 데이터센터 정전이나 통신 회선 절단처럼 바깥에서 온 장애는 빼고 셉니다.
세는 범위를 겹쳐 그리면 이렇습니다.
flowchart TD
subgraph S1["사고 전체 · 다른 복구 지표는 여기까지 센다"]
subgraph S2["서비스 복구 시간이 세는 것"]
A["자기가 내보낸 배포가 낸 실패"]
end
B["데이터센터 정전"]
C["통신 회선 절단"]
end
안쪽 상자에 든 것만 셉니다. 바깥 상자까지 세는 이웃 지표는 뒤에서 가릅니다.
가르는 까닭은 이 값이 묻는 것이 다르기 때문입니다. 「우리 시스템이 얼마나 안 멎느냐」가 아니라 「우리가 낸 변경을 얼마나 빨리 걷어낼 수 있느냐」를 묻습니다. 정전과 회선 절단에는 팀이 손댈 수 없는 것이 섞여 있습니다. 배포가 낸 실패는 팀이 만든 배포 흐름에 달려 있습니다.
서비스 복구 시간은 DORA(DevOps Research and Assessment)가 쓰는 지표 가운데 하나입니다. DORA 는 소프트웨어를 만들어 내보내는 팀을 여러 해 조사해 온 연구입니다.
DORA 가 재는 것은 소프트웨어 배달 성능입니다. 변경을 얼마나 빨리 내보내고 얼마나 안 깨뜨리는지를 묶어 부르는 말입니다.
이 성능을 재는 지표는 두 무리로 갈립니다. 변경이 얼마나 잘 흐르나를 보는 처리량 쪽과, 얼마나 안 깨지나를 보는 안정성 쪽입니다.
「실패한 배포 복구 시간」이라는 이름으로도 부릅니다. 세는 대상이 배포에 묶여 있다는 것을 이름에 드러낸 것입니다.
시계를 켜고 끄는 때
같은 실패를 재도 팀마다 값이 갈립니다. 갈리는 곳은 시계를 켜고 끄는 때입니다.
켜는 때의 후보는 둘입니다. 배포가 나간 때부터 재면 아무도 문제를 알아채지 못하고 흘려보낸 시간까지 들어갑니다. 실패를 알아챈 때부터 재면 알아챈 뒤의 시간만 들어갑니다.
끄는 때는 서비스가 정상으로 돌아온 때입니다. 원인을 찾아 없앤 때가 아닙니다. 급히 되돌려 서비스를 살려 두고 원인은 다음 날 뽑는 일이 흔합니다. 이 값은 서비스가 돌아온 때에서 멈춥니다.
한 사고의 다섯 때를 세로로 세우고, 그 위에 두 측정 창을 점선으로 겹치면 이렇습니다.
flowchart TD
A["배포가 나갔다"] --> B["실패가 났다"]
B -->|"감시가 줄이는 구간"| C["실패를 알아챘다"]
C -->|"배포 방식이 줄이는 구간"| D["서비스가 정상으로 돌아왔다"]
D --> E["원인을 없앴다"]
A -.->|"배포가 나간 때부터 재는 창 · 흘려보낸 시간까지 들어간다"| D
C -.->|"알아챈 때부터 재는 창 · 알아챈 뒤만 들어간다"| D
점선 둘이 끝나는 곳은 같고 시작하는 곳만 다릅니다. 「원인을 없앴다」에는 어느 점선도 닿지 않습니다. 거기는 시계를 끄는 때가 아니기 때문입니다. 화살표에 붙은 말은 그 구간을 무엇이 줄이는지입니다.
어느 때에 켜고 끌지는 팀이 고릅니다. 다만 한 번 정했으면 바꾸지 않아야 지난달과 이번 달을 견줄 수 있습니다. 기준을 적어 두지 않은 값은 오르내려도 무엇이 변한 것인지 알 수 없습니다.
되살리는 두 길
실패한 배포를 걷어내는 길은 크게 둘입니다. 이전 버전으로 되돌리는 롤백과, 문제를 급히 고쳐 새로 내보내는 핫픽스입니다.
롤백은 이미 돌던 버전으로 가는 것이라 무엇이 나올지 알고 갑니다. 핫픽스는 한 번도 안 돌아본 코드를 급한 상태에서 내보내는 것이라 두 번째 실패를 낳기 쉽습니다. 그래서 되돌릴 수 있게 만들어 두는 일이 이 값을 줄이는 첫 손질입니다.
앞의 길을 아예 막아 버리는 것도 있습니다. 표 구조를 바꾸는 데이터베이스 마이그레이션이 대표입니다. 한번 바꾼 표 구조는 되돌리는 절차를 따로 만들어 두지 않으면 못 되돌립니다.
그래서 한 배포에 표 구조 변경과 코드 변경을 같이 실으면 코드만 걷어낼 수 없습니다. 남는 길은 핫픽스뿐입니다.
실패한 배포 하나가 어느 길로 가는지는 조건 둘이 정합니다.
flowchart TD
A["실패한 배포"] --> B{"표 구조 변경이 같이 실렸나"}
B -->|그렇다| E["급히 고쳐 다시 내보낸다"]
B -->|아니다| C{"되돌릴 수 있나"}
C -->|그렇다| D["이전 버전으로 되돌린다"]
C -->|아니다| E
D --> F["서비스가 정상으로 돌아온다"]
E --> F
첫 칸에서 「그렇다」로 빠지면 되돌리는 길은 아예 안 열립니다.
짧게 만드는 손질
복구 시간을 줄이는 손질은 대개 복구가 시작된 뒤가 아니라 배포를 만들 때 들어갑니다. 실패를 알아채기까지, 무엇을 되돌릴지 정하기까지, 되돌린 것이 퍼지기까지가 모두 배포 방식에 달려 있기 때문입니다.
아래 표에 낯선 이름이 셋 나옵니다. 기능 플래그는 배포를 되돌리지 않고 문제가 된 기능만 꺼 두는 스위치입니다.
카나리 배포는 새 버전을 일부 사용자에게만 먼저 보내 실패를 일찍 드러내는 방식입니다. 블루-그린 배포는 새 버전을 쓰는 무리와 옛 버전을 쓰는 무리를 둘 다 띄워 두고 오가는 방식이라, 되돌아갈 옛 버전이 늘 떠 있습니다.
| 미리 해 두는 것 | 복구가 짧아지는 까닭 |
|---|---|
| 배포 단위를 작게 쪼갠다 | 되돌릴 덩어리가 작아 무엇을 되돌릴지 고르는 데 시간이 안 든다 |
| 되돌리기를 명령 한 번으로 만든다 | 급한 때에 사람이 절차를 기억해 내지 않아도 된다 |
| 기능 플래그를 심어 둔다 | 배포를 되돌리지 않고 문제 난 기능만 끈다 |
| 카나리 배포·블루-그린 배포를 쓴다 | 되돌아갈 옛 버전이 이미 떠 있다 |
| 실패를 알아채는 감시를 붙인다 | 아무도 모르고 흘려보내는 시간이 줄어든다 |
표의 마지막 줄을 맡는 것이 모니터링과 경보입니다. 사람이 손을 대기 전까지의 시간은 감시가 정합니다. 손을 댄 뒤의 시간은 배포 방식이 정합니다.
안정성 쪽에 서는 까닭
서비스 복구 시간은 얼마나 자주 깨지느냐가 아니라 깨진 뒤 얼마나 오래 멎어 있느냐를 봅니다. 둘 다 내보낸 변경이 낸 실패를 보는 값이라, 변경 실패율과 함께 안정성 쪽에 놓입니다.
그런데 이 값은 처리량 쪽까지 같이 끌고 내려갑니다. 망가진 프로덕션을 되살리는 동안에는 다음 변경을 내보내기 어렵습니다. 배포 경로가 한 건에 붙들려 있으니 그 뒤에 선 변경들이 같이 멈춥니다.
배포 경로가 막힌 모습을 그리면 이렇습니다.
flowchart TD
H["복구 중인 실패 배포 · 배포 경로를 붙들고 있다"]
H -.->|"머리가 안 빠진다"| W
subgraph W["뒤에 선 변경들"]
C1["다음 변경"] --> C2["그다음 변경"] --> C3["그다음 변경"] --> C4["나머지"]
end
머리가 안 빠지면 뒤에 선 것들은 순서를 기다리는 수밖에 없습니다.
그래서 이 값이 길어지면 변경 리드 타임이 늘고 배포 빈도가 떨어집니다. 안정성 쪽 값 하나가 처리량 쪽 값 둘을 같이 끌어내립니다. 네 지표를 한 묶음으로 읽는 까닭입니다.
값 하나로 줄일 때
실패한 배포마다 시간이 하나씩 나옵니다. 기간을 정해 그 시간들을 하나의 수로 줄여야 추세가 보입니다.
평균만 쓰면 유난히 긴 한 건이 수를 끌어올립니다. 복구 시간은 대개 짧고 가끔 아주 긴 값이라 그 쏠림이 큽니다.
12분 · 9분 · 51분 // 세 건의 복구 시간
평균 24분 // 긴 한 건이 올린다
가운데 값 12분 // 흔한 쪽에 가깝다
그래서 평균과 중앙값을 같이 봅니다. 실패한 배포 건수도 함께 적습니다. 세 건의 평균과 서른 건의 평균은 무게가 다릅니다.
헷갈리는 이웃 이름
가까운 이름이 셋 있습니다. 가르는 기준은 둘입니다. 무엇을 세는가, 그리고 미리 정한 약속인가 지나간 일을 잰 결과인가입니다.
평균 복구 시간(MTTR, Mean Time To Recovery)은 세는 대상이 넓습니다. 배포가 낸 실패든 바깥에서 온 장애든 가리지 않고 사고(인시던트)를 모아 평균을 냅니다.
복구 목표 시간(RTO, Recovery Time Objective)은 미리 정해 둔 약속입니다. 이 값은 지나간 배포를 재서 나온 결과입니다. 약속이 한 시간이어도 결과는 세 시간일 수 있습니다.
변경 실패율은 방향이 다릅니다. 그쪽은 얼마나 자주 깨졌는지를 셉니다. 이 값은 깨진 뒤 얼마나 오래 멎어 있었는지를 잽니다. 배포 열 건 중 한 건만 깨져도 그 한 건이 하루를 멎어 있었다면 사용자가 겪은 시간은 짧지 않습니다.
쓰는 데와 안 쓰는 데
한 서비스를 같은 기준으로 재서 추세를 볼 때 값이 있습니다. 사후 분석에서 나온 후속 조치가 멎어 있던 시간을 줄였는지는 이 추세로 확인합니다.
다른 팀이나 다른 서비스와 견주는 데는 쓰지 않습니다. 무엇을 실패로 셀지와 시계를 언제 켤지가 서로 다릅니다. 하루에 수십 번 내보내는 서비스와 분기마다 내보내는 서비스는 실패의 성격도 다릅니다.
목표치로 못 박고 사람을 평가하는 데도 쓰지 않습니다. 수를 낮추는 가장 쉬운 길은 복구를 서두르는 것이 아니라 작은 실패를 실패로 안 세는 것이기 때문입니다. 그러면 기록만 사라지고 사고는 그대로 남습니다.
관련 항목
이 값과 한 묶음으로 보는 배달 성능 지표
변경 리드 타임 · 배포 빈도 · 변경 실패율 · 배포 재작업률 · DORA · 소프트웨어 배달 성능 · 처리량
복구를 앞당기려고 배포에 미리 심어 두는 수단
롤백 · 핫픽스 · 기능 플래그 · 카나리 배포 · 블루-그린 배포 · 배포 파이프라인 · 지속적 전달 · 데이터베이스 마이그레이션
실패를 알아채는 데 쓰는 감시 수단
모니터링 · 관측성 · 경보 · 골든 시그널 · 대시보드 · 헬스 체크
복구에 사람이 붙는 사고 대응 절차
사고 대응 · 온콜 · 사후 분석 · 인시던트 · 에스컬레이션 · 런북
이름이 헷갈리는 이웃 지표
평균 복구 시간 · 복구 목표 시간 · 복구 시점 목표 · 평균 고장 시간 · 가용성 · 서비스 수준 목표
여러 건을 한 수로 줄일 때 쓰는 통계값
이 지표를 굴리는 개발 방식
다른 이름: time to restore service · failed deployment recovery time · 실패한 배포 복구 시간 · 배포 실패 복구 시간