Chapter 8

분산 시스템의 골칫거리

  • 8.1 결함과 부분 장애
  • 8.2 신뢰성 없는 네트워크
  • 8.3 신뢰성 없는 시계
  • 8.4 지식, 진실, 그리고 거짓말

분산 시스템에서는 아무것도 확실하지 않아. 네트워크는 패킷을 잃고, 시계는 어긋나고, 프로세스는 언제든 멈출 수 있어. 이걸 전제로 설계하지 않으면 반드시 당하게 돼.

단일 컴퓨터는 결정론적이야. 하드웨어가 정상이면 같은 연산은 항상 같은 결과를 내고, 문제가 있으면 전체가 멈추지. 분산 시스템은 근본적으로 달라 — 시스템의 일부가 예측 불가능하게 고장 나면서 나머지는 계속 돌아가는 부분 장애가 핵심 문제야. 뭐가 잘못됐는지 알 수조차 없을 수도 있거든.

네트워크부터 봐. 비동기 패킷 네트워크에서 메시지를 보내면 유실, 큐잉, 상대 죽음, 응답 유실 — 뭐든 일어날 수 있고, 보내는 쪽에서는 원인을 구분할 수 없어. 유일한 선택은 타임아웃인데, 너무 길면 장애 감지가 느리고 너무 짧으면 멀쩡한 노드를 죽은 걸로 판단해서 캐스케이딩 장애를 일으킬 수 있지. 네트워크 혼잡, TCP 재전송, OS 큐잉, VM CPU 빼앗김, GC — 전부 지연을 예측 불가능하게 만드는 원인이야.

시계는 더 교활해. 각 머신의 수정 발진기는 점점 어긋나고(시계 드리프트), NTP 동기화도 네트워크 지연 때문에 완벽하지 않아. 일 시계는 NTP 동기화 시 뒤로 갈 수 있어서 경과 시간 측정에 부적합하고, 단조 시계만 경과 시간에 쓸 수 있어. 이벤트 순서를 타임스탬프로 정하면 시계가 어긋난 노드의 쓰기가 잘못 덮어써질 수 있어 — 데이터가 조용히 유실되는 거야. 구글의 스패너는 TrueTime API로 시계의 신뢰 구간을 노출하고, 구간이 겹치지 않을 때까지 기다려서 인과적 순서를 보장하는 독특한 접근을 취했지.

프로세스 중단도 무시 못 해. GC가 수십 초간 프로세스를 멈출 수 있고, VM 라이브 마이그레이션으로 전체가 잠시 서고, 멈춰 있는 동안 다른 노드에 의해 "죽은 것"으로 선언될 수도 있어. 그래서 분산 시스템에서 진실은 한 노드가 결정하는 게 아니라 과반수(정족수) 가 결정하는 거야. 펜싱 토큰 — 잠금을 줄 때 단조 증가하는 번호를 함께 제공하고, 리소스가 이전보다 작은 번호의 요청을 거부하게 하는 것 — 이 옛 리더의 쓰기를 안전하게 막아주지.


정리

8장 읽고 기억할 거:

  1. 분산 시스템에서는 아무것도 확실하지 않다. 네트워크는 패킷을 잃고, 시계는 어긋나고, 프로세스는 언제든 멈출 수 있다. 이걸 전제로 설계해야 한다
  2. 타임스탬프로 이벤트 순서를 정하는 건 위험하다. 시계는 신뢰할 수 없고, 신뢰 구간을 고려하지 않으면 데이터가 조용히 유실된다
  3. 진실은 과반수가 결정하고, 펜싱 토큰으로 보호한다. 한 노드의 주장은 믿을 수 없고, 정족수의 합의와 토큰 기반 검증이 안전한 분산 시스템의 기초다