Skip to content

CH8 - 분산 시스템의 골칫거리 #7

Description

@won983212

결함과 부분 장애

단일 시스템에서는 소프트웨어가 결정적으로 동작한다.

  • 하드웨어가 정상적: 항상 같은 결과를 냄
  • 하드웨어가 고장: 완전히 동작하지 않는다.
  • 즉 동작하지 않을 수 있어도, 잘못된 결과를 주진 않음

💡 이는 다루기 힘든 잘못된 결과를 피하기 위해 의도적으로 설계된 것. '완전히'라는 키워드가 중요

네트워크로 연결된 분산 시스템은 전체가 아니라 일부만 예상치 못한 방식으로 고장날 수 있다.

  • 이를 부분장애라고 하며, 부분 장애는 비결정적
  • 부분장애의 비결정성때문에 분산 시스템은 다루기 매우 까다롭다.

내 짧은 경력 동안 한 데이터 센터에서 발생한 장기간의 네트워크 분단, PDU(power distribution unit, 전원 분배 유닛)장애, 스위치 장애, 전체 랙에서 주기적으로 일어난 전원 사고, 전체 DC 백본 장애, 전체 DC 전원 장애를 겪었고, 저혈당증을 앓는 운전자가 자신의 포드 픽업 트럭을 DC의 HVAC(난방, 통풍, 공조) 시스템에 처박은 적도 있었다.
심지어 나는 운영 담당 직원도 아니였다.

- 코다 헤일(Coda Hale) -

클라우드 컴퓨팅과 슈퍼컴퓨팅

구분 슈퍼컴퓨팅 클라우드 컴퓨팅
시스템 단일 노드 컴퓨터에 가깝다. 분산 시스템
하드웨어 전용 하드웨어로 구축 상용 장비로 구축
신뢰성 노드가 서로 가깝고 전용 하드웨어를 사용해 높은 신뢰성 노드가 멀리 떨어져있고 인터넷으로 통신하므로 비교적 낮은 신뢰성
사용 일기예보나 분자 동력학 등 큰 과학 계산에 주로 사용 인터넷 서비스 등...
장애복구 부분 장애를 전체 장애로 확대
- 가끔씩 계산 상태를 체크포인트로 저장한다.
- 장애 발생시 모든 계산을 중단한다.
- 복구가 끝나면 계산을 재시작한다.
부분 장애를 허용
- 인터넷 애플리케이션 특성상 가용성이 중요하므로 장비를 중단할 수 없음.
- 소프트웨어에 내결함성 메커니즘을 넣어야 함

분산 시스템에서는 신뢰성 없는 구성요소를 모아 신뢰성 있는 시스템 구축해야한다.

  • 예시로 IP가 있다. IP는 신뢰성이 낮은데, TCP에서는 IP위에서 패킷 누락/중복/순서 뒤엉킴이 발생하지 않도록 보장해준다.
  • 물론 완벽하진 않아서 패킷 지연은 막을 수 없다.

신뢰성 없는 네트워크

여기서는 분산 시스템은 비공유 시스템이라고 가정한다.

  • 네트워크로 연결된 다수의 장비를 의미
  • 다른 장비의 RAM/Disk등에 직접 접근 불가
  • 실제로 대부분의 분산 인터넷 애플리케이션 서비스는 비공유 방식으로 동작

왜 인터넷 서비스에서 비공유 시스템이 주로 사용되는가?

  • 상용 장비를 사용하므로 장비값이 비교적 저렴
  • 상품화된 클라우드(AWS, NCP, GCP, ...)를 사용할 수 있음
  • 지리적으로 분산된 여러 IDC에 분산 배포하여 신뢰성 확보

비동기 패킷 네트워크

인터넷 서비스는 대부분 비동기로 패킷을 전송한다.

  • 그래서 요청 전송후 기다릴 때 여러 결함이 발생할 수 있다.
  • 응답을 받지 못해도 그 이유을 알 수 없다.
  • 심지어 요청이 잘 처리되었는지 조차도 알 수 없다. (ex. 스티커가 잘 수집 되었는지)

응답을 받지 못하는건 여러 이유가 있을 수 있는데

  • 케이블 선이 고장나서 요청 손실
  • 원격 노드에 불남 (카카오)
  • 네트워크 스위치 설정 문제로 요청이 다른 곳으로 전송
  • 해저 케이블을 상어가 뜯어먹어서 지연
  • 스위치 SW 업데이트 중 토폴로지 재구성
  • 네트워크 장비가 과부하되어 지연 등...

이 문제를 처리하기 위해 타임아웃을 주로 사용한다. 하지만 원격 노드가 응답을 받았는지는 여전히 알 수 없다.

현실의 네트워크 결함

이처럼 네트워크 결함은 생각보다 많이 발생한다. 항상 네트워크 결함이 있다고 가정해도 될 정도.

  • 소프트웨어 차원에서 네트워크 결함을 잘 처리해야한다.
  • 네트워크 문제에 소프트웨어가 어떻게 반응하는지 알고 복구할 수 있도록 해야한다.
    • 카오스 몽키

결함 감지

고가용성을 보장하기 위해서 분산 시스템에서는 결함을 잘 감지해야한다.

  • 로드 벨런서는 결함 있는 노드로 요청을 보내지 말아야 한다.
  • 단일 리더 복제에서는 리더에 장애가 발생하면 한 팔로워를 리더로 승격시켜야 한다.

네트워크의 불확실성 때문에 결함을 완벽하게 감지하는건 어렵다. 그래서 타임아웃을 두어 일정 시간 응답을 못받으면 결함이라고 가정한다.

좀 더 빠른 처리를 위해 애플리케이션에서 명시적으로 피드백을 주는 방법도 있다.

  • ex1) 어떤 노드 프로세스가 죽었다면 응답으로 죽었다고 전달한다.
  • ex2) IP주소에 도달할 수 없다고 라우터가 확신하면 ICMP Destination Unreachable을 전달한다.
  • 타임아웃을 끝까지 기다릴 필요가 없다는 장점이 있다.
  • 하지만 이러한 피드백 조차도 네트워크 문제로 전달되지 않을 수 있으니 의존하면 안된다.

타임아웃과 기약 없는 지연

적절한 타임아웃 시간은 산출하기 어렵다.

👉 타임아웃이 길면

  • 기다리는 시간이 길어진다. 요청이 많은 경우 소켓 고갈 가능성이 있다.

👉 타임아웃이 짧으면

  • 실제로 살아있어도 죽었다고 판단할 확률이 높아진다.
  • 같은 동작을 두 번이상 할 수도 있다. (멱등성이 보장되지 않은 경우)
    • ex) 같은 스티커가 두 번 수집될 수 있다.

네트워크 혼잡과 큐 대기

네트워크 패킷 지연이 매번 다른건 큐 대기때문인 경우가 많다.

  • 동시에 같은 목적지로 많이 전송: 여러 다른 노드가 동시에 같은 목적지(ex. 스위치 포트)로 패킷을 보내려고 하면 패킷은 슬롯을 얻을 때 까지 대기
  • 원격 노드 CPU가 바쁨: 패킷이 도착했는데 CPU가 바쁜 상태면 운영체제가 잠시 큐에 패킷넣어 버퍼링
  • 가상 환경에서 CPU 시간 뺏김: 잠깐 다른 가상 장비가 CPU코어를 사용하면 데이터를 큐에 넣어 버퍼링
  • TCP 흐름제어: 네트워크에 과부하를 가하지 않도록 자신의 송신률을 제한
    • 타임아웃이 지나면 패킷을 다시 재전송

네트워크 지연 변동성이 커서 타임아웃을 고정적으로 설정하는 것보단, 응답 시간에 따라 동적으로 타임아웃을 조절하는 것이 더 좋다. (ex. phi accrual failure detector)

동기 네트워크와 비동기 네트워크

전화 회선 (동기식)

  • 전용 선을 할당받아 데이터를 주고받는다.
  • 고정된 대역폭을 할당받는다.
    • 대역폭이 예상 가능하므로 큐 대기 문제가 없다.
    • 네트워크 지연 시간 최대치를 알 수 있다.

인터넷 네트워크 (비동기식)

  • 하나의 선에 여러 곳에서 온 데이터들이 전달될 수 있다.
  • 대역폭을 동적으로 공유한다.
    • 네트워크 지연 시간 변동성이 크다.

인터넷 네트워크를 비동기식으로 구성한 이유는 몰리는 트래픽을 효과적으로 처리하기 위해서이다.

  • 전화 회선은 전용 선으로 통신하므로 트래픽이 많아져도 다른 회선을 쓸 수 없다. 전용 선만 써야하므로 리소스 낭비이다.
  • 인터넷은 대역폭을 공유하므로 잠깐 더 많은 대역폭을 점유해서 쓸 수 있다. 더 효율적으로 네트워크 회선을 사용할 수 있다.
  • 즉 네트워크 지연 변동성과 전송 효율 사이의 트레이드 오프인 것.
  • 그래서 결국 타임아웃은 실험적으로 결정할 수 밖에 없다.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions