본문으로 바로가기

33

장애 조치(페일오버)

예비를 두는 것만으로는 부족하다. 죽었다는 사실을 알아채고 실제로 옮겨 타야 한다

먼저 보면 좋은 강의: 단일 장애점

단계별로 보기

스페이스바로 재생/정지, 좌우 화살표로 단계 이동, R로 처음으로 돌아갑니다.

대기 중1 / 4 단계 — 둘 다 살아 있을 때

로드밸런서가 요청을 두 서버에 번갈아 보냅니다. 각 서버가 절반씩 받습니다. 아무 문제도 없습니다. 그리고 이 상태에서는 예비가 제대로 작동할지 아무도 알 수 없습니다. 평상시에는 페일오버가 되는지 안 되는지 알 방법이 없습니다.

이 강의를 마치면

  • 중복을 두는 것과 실제로 넘겨받는 것이 별개의 문제임을 설명한다.
  • 고장을 알아채는 데 걸리는 시간이 곧 사용자가 겪는 장애 시간임을 설명한다.
  • 점검 주기를 짧게 할 때 얻는 것과 잃는 것을 함께 설명한다.
  • 서버 한 대가 죽어도 서비스가 유지되는 구성을 직접 만든다.

예비가 있어도 불은 꺼진다

앞 강의에서 단일 장애점을 없앴습니다. 서버를 두 대 두었습니다. 끝일까요?

아닙니다. 아주 중요한 게 남았습니다. 서버 1이 죽었다는 걸 누가, 언제 아는가?

로드밸런서는 서버 1이 죽은 걸 모릅니다. 아무도 알려주지 않았으니까요. 그래서 계속 서버 1로 요청을 보냅니다. 그리고 그 요청들은 전부 실패합니다.

서버 1 사망 (0초)
  ↓
로드밸런서는 여전히 절반을 서버 1로 보냄 → 전부 실패
  ↓
로드밸런서가 알아챔 (3초)
  ↓
서버 2로만 보냄 → 정상

3초 동안 요청의 절반이 실패했습니다. 예비 서버는 처음부터 멀쩡히 살아 있었는데도 말입니다. 예비를 사두는 것과 실제로 옮겨 타는 것은 다른 일입니다.

죽었는지 어떻게 아는가

로드밸런서는 주기적으로 각 서버에 물어봅니다. "살아 있나요?" 이것을 헬스체크라고 합니다.

응답이 없으면 몇 번 더 물어보고, 계속 없으면 명단에서 뺍니다. 명단에서 빠진 서버에는 요청을 보내지 않습니다. 이것이 장애 조치의 전부입니다.

감지 시간 = 장애 시간

여기서 가장 중요한 공식이 나옵니다.

사용자가 겪는 장애 시간 ≈ 점검 주기 × 필요한 연속 실패 횟수

1초마다 점검하고 3번 연속 실패해야 뺀다면 → 약 3초입니다. 그 3초 동안 서버 1로 간 요청은 전부 실패합니다.

점검 주기연속 실패 기준장애 시간평상시 점검 부하
10초3회30초매우 낮음
1초3회3초낮음
0.1초3회0.3초높음

더 자주 물어볼수록 빨리 알아챕니다. 그럼 0.01초마다 물어보면 되지 않을까요?

왜 무한정 짧게 못 하는가

두 가지가 막습니다.

첫째, 점검도 부하입니다. 서버 100대에 0.01초마다 물으면 초당 1만 건입니다. 고장을 찾으려고 서버를 괴롭히는 꼴입니다.

둘째, 이게 더 중요한데 — 성급하면 오진합니다. 서버가 잠깐 느려진 것뿐인데 죽었다고 판단해서 명단에서 빼버립니다. 그러면 남은 서버로 트래픽이 몰립니다. 그 서버도 느려집니다. 그것도 죽었다고 판단합니다. 멀쩡한 서버를 하나씩 꺼버리는 것입니다.

이것을 연쇄 장애라고 합니다. 고장을 빨리 찾으려던 장치가 아무 고장도 없는 시스템을 무너뜨립니다.

그래서 "3번 연속 실패해야 뺀다" 같은 규칙을 둡니다. 한 번의 실패로는 판단하지 않습니다. 이 규칙이 감지를 느리게 만들지만, 오진을 막습니다. 빠른 감지와 정확한 감지는 맞바꿔야 하는 관계입니다.

남은 서버가 감당하나

또 하나 자주 놓치는 것이 있습니다.

서버 두 대가 각각 초당 50건씩, 합쳐서 초당 100건을 처리하고 있습니다. 한 대가 죽으면 남은 한 대가 초당 100건을 전부 받아야 합니다. 그런데 그 서버의 한계도 초당 50건입니다.

살아남은 서버가 곧바로 무너집니다. 그리고 그 서버까지 죽으면 전체가 끝납니다. 이것도 연쇄 장애입니다.

그래서 중복을 둘 때는 한 대가 죽어도 남은 대수가 전체 부하를 감당하는지를 같이 계산해야 합니다. 두 대로 100건을 처리한다면, 한 대가 죽었을 때를 대비해 각 서버는 100건을 감당할 수 있어야 합니다. 이 말은 평소에는 절반을 놀린다는 뜻입니다.

이 놀리는 용량이 아깝다고 줄이면, 장애가 났을 때 그대로 무너집니다. 여유는 낭비가 아니라 보험료입니다.

직접 해보세요

아래 과제는 서버 한 대가 10초 시점에 죽습니다. 지금 상태로 실행하면 그 순간부터 전부 실패합니다. 죽어도 서비스가 유지되도록 고쳐 보세요. 로드밸런서가 알아채는 데 걸리는 짧은 시간 동안은 약간의 실패가 남습니다. 그것까지 0으로 만들 수는 없습니다.

이 강의가 단순화한 것

교육용 모형은 언제나 무언가를 생략합니다. 무엇을 생략했는지 아는 것도 학습의 일부입니다.

전제한 것

  • 이 시뮬레이터에서 노드를 죽이면 로드밸런서는 헬스체크 주기에 따라 그 사실을 알아챈다. 그 사이의 실패는 정상적인 관측이며, 이 강의의 요점이다.
  • 죽은 서버는 조용히 응답을 멈춘다고 본다. 실제로는 느려지기만 하거나 틀린 답을 주는 '반쯤 죽은' 상태가 더 흔하고 훨씬 다루기 어렵다.
  • 이 과제의 서버는 상태를 갖지 않는다고 본다. 세션이나 진행 중인 작업이 있으면 넘겨받는 일이 훨씬 복잡해진다.
  • 장애 시간 계산(점검 주기 × 연속 실패 횟수)은 근사이며, 실제로는 타임아웃과 네트워크 지연이 더해진다.

다루지 않은 것

  • 반쯤 죽은 서버(느리지만 응답은 하는) 판정 문제
  • 장애 조치 후 원래 서버가 살아났을 때 되돌리는 절차
  • 상태를 가진 서비스의 장애 조치
  • 헬스체크의 종류(단순 응답 확인 vs 실제 의존성 확인)

더 읽을거리: Google SRE Book — Load Balancing in the Datacenter

이제 직접 만들어 보세요

읽어서 아는 것과 만들어서 아는 것은 다릅니다. 컴포넌트를 배치하고 트래픽을 흘려서 실제로 동작하는지 확인해 보세요.

실습 과제 열기

이 강의에 물어보기

하루 5번

이 강의 본문만 근거로 답합니다. 강의에 없는 내용은 지어내지 않습니다.