분산 시스템의 골칫거리
결함과 부분 장애
단일 컴퓨터에서 소프트웨어는 결정적인 방식으로 동작한다. 하지만 네트워크로 연결된 컴퓨터에서는 비결정적으로 동작하고, 분산시스템에서 고장나는것을 부분장애라고 한다.
클라우드 컴퓨팅과 슈퍼 컴퓨팅
HPC(고성능 컴퓨팅)과 클라우드 컴퓨팅으로 나뉜다. 철학에 따라 결함 처리 방법도 다르다. 슈퍼컴퓨터에서 실행되는 작업은 지속성 있는 저장소에 체크포인트로 저장하고, 장애 발생시 클러스터 작업 부하를 중단 후 체크포인터부터 재시작 (마치 단일 노트 처럼) 즉, 부분 장애를 전체 장애로 확대
- 슈퍼컴퓨터는 특화된 하드웨어를 통해 구축하며, 노드 사이에는 공유메모리, 원격접근 사용 / 반면 클라우드는 상용장비로 구축하고, 낮은 비용으로 동일 성능 제공하지만 실패율도 높다
- 데이터 센터 네트워크는 클로스 토폴로지 - 슈퍼 컴퓨터는 다차원 메시나 토러스
- 장애가 난 노드를 감내할 수 있고 계속 동작 가능하면 운영과 유지보수에 매우 유용
- 지리적 분산 배포된 경우 로컬 네트워크에 비해 통신이 느리고 신뢰성 떨어짐 / 슈퍼컴은 일반적으로 모든 노드가 가까이에 있다고 가정 분산 시스템이 동작하게 만드려면 부분 장애 가능성 받아들이고, 소프트웨어에 내결함성 매커니즘 넣어야 한다
신뢰성 없는 구성요소를 위해 신뢰성 있는 시스템 구축하기 위해 ‘오류수정코드’ 사용하거나, ‘TCP’ 같은 프로토콜 사용한다
신뢰성 없는 네트워크
분산시스템은 비공유 시스템으로 네트워크로 연결되어 있으며 다른 장비의 메모리나 디스크에 접근할 수 없다 네트워크 대부분은 비동기 패킷 네트워크로 다른 노드에 패킷을 보낼 수 있지만 도착을 보장하진 았는다. 타임아웃을 이용해 이 문제를 주로 해결한다. (잘못될 수 있는 여러 상황은 278p 그림참조)
현실의 네트워크 결함
드물더라도 네트워크 결함이 일어날 수 있으며 -> 여러분의 소프트웨어가 이를 처리해야 한다
결함 감지
결함있는 노드를 자동으로 감지할 수 있어야 한다 피드백을 받을 수 있는 방법은 유용하지만 일반적으로 아무 응답도 받지 못할 것이라고 가정해야 한다.
타임아웃과 기약 없는 지연
타임아웃만이 결함을 감지하는 확실한 수단이다 -> 타임아웃은 얼마나 길어야 할까? 너무 짧으면 결함을 빨리 발견하지만 죽었다고 잘못 선언할 위험이 커진다. 게다가 노드가 잘못 죽었다고 선언하면 다른 노드와 네트워크에 추가적인 부하를 준다 => 2d + r 을 타임아웃으로 사용 (d: 패킷 전송 시간, r: 처리 시간)
네트워크 혼잡과 큐 대기
패킷 지연의 변동성은 큐 대기 때문인 경우가 많고 여러가지 이유가 잇다 네트워크 혼잡 때문일수도, CPU 코어가 바빠서 일수도, TCP 프로토콜의 특성 때문 일수도.. 지터를 측정하여 타임아웃을 자동으로 조절하게 하는 방법 도 있다
동기 네트워크 대 비동기 네트워크
전화는 동기 네트워크로 고정되고 보장된 양의 대역폭이 할당된다. 이는 동기식이다 하지만 TCP는 비동기 네트워크로 패킷 교환 프로토콜을 사용하며, 이를 사용하는 이유는 순간적으로 몰리는 트래픽에 최적화됐기 때문이다.
신뢰성 없는 시계
분산시스템에서는 통신이 즉각적이지 않으므로 시간은 다루기 까다롭다. 네트워크에 있는 개별 장비는 자신의 시계를 가지고 있으며, 보편적으로 네트워크 시간 프로토콜 (NTP)로 시간을 동기화 한다.
단조 시계(monotonic) 대 일 기준(time-of-day clock) 시계
- 일기준 시계: 직관적으로 시계에 기대하는 일을 하며, 예를들어 리눅스 clock_gettime(), 자바 System.currentTimeMillis() 는 에포크 이래로 흐른 초 수를 반환, NTP로 동기화됨, 경과시간 측정에는 적합하지 않음, 역사적으로 거친 해상도 가짐
- 단조시계: 타임아웃이나 지속시간(시간구간) 재는데 적합, 항상 앞으로 흐른다는 뜻에서 단조시계란 이름 붙임, 한 시점과, 일 한후의 시점 차이를 재는데 적합
시계 동기화와 정확도
일기준 시계는 NTP 서버등에 맞춰 설정되어야 유용하지만, 기대만큼 신뢰성이 있거나 정확하진 않다. 이유: 컴퓨터의 수정 시계는 아주 정확하진 않다, 컴퓨터 시계와 NTP 서버가 차이가 심하면 동기화 거부되거나 로컬시계 리셋됨, 방화벽 이슈로 막히면 잘못된 설정값이 안알려질 수 있다, NTP 동기화는 잘해야 네트워크 지연만큼 좋다, NTP 서버가 이상이 있을수도 있다 윤초 발생시 골치아프다, 가상 장비에서 하드웨어 시계의 문제, 완전히 제어할 수 없는 장치를 사용하는 경우
동기화된 시계에 의존하기
동기화된 시계에 의존시 극적인 고장보다는 조용하고 미묘한 데이터 손실이 발행할 가능성이 높다. 그래서 동기화된 시계가 필요한 소프트웨어 사용시 필수적으로 모든 장비의 시계차이를 조심스럽게 모니터링 해야한다.
- 이벤트 순서화용 타임스탬프
- 시계 읽기는 신뢰 구간이 았다.
- 전용 스냅숏용 동기화된 시계
프로세스 중단
분산시스템에서 리더만 쓰기를 받아들이도록 하는 경우 -> 리더가 다른 노드로부터 임차권을 얻는 방식으로 구현
지식, 진실, 그리고 거짓말
분산 시스템에서 우리는 시스템 모델에 관해 정한 가정을 명시하고, 이런 가정을 만족시키는 방식으로 실제 시스템을 설계할 수 있다.
진실은 다수결로 결정된다
분산 알고리즘은 정족수에 의존한다. 정족수를 이룬 노드들이 다른 노드를 죽었다고 선언한다면, 죽은 것이다.
- 리더와 잠금 하나의 리더만 필요한경우, 어떤 노드가 스스로를 선택된 자 라고 가정하는 것을 주의 해야한다
- 펜싱토큰 fencing: 잠금 서버가 잠금이나 임차권 승인시 펜싱토큰을 반환한다. 잠금 승인시마다 증가되는 숫자로 클라이언트가 쓰기 요청을 저장소 서비스로 보낼 때마다 펜싱 토큰을 포함하도록 요구한다.
비잔틴 결함
펜싱토큰은 부주의에 의한 오류는 감지하고 차단할 수 있지만, 분산시스템의 경우 거짓말을 하는 노드가 등장하면 상황은 어려워진다. 이러한 경우를 비잔틴 결함이라고 하며, 신뢰할 수 없는 환경에서 합의에 도달하는 문제를 비잔틴 장군 문제라고도 한다. 비잔틴 내결함성을 지닌다 : 악의적인 공격자가 네트워크 방해해도 시스템이 올바르게 동작한다 대부분의 경우는 보통 비잔틴 결함이 없다고 가정할 수 있고, 웹브라우저 같은 경우만 클라이언트 행동이 악의적일 수 있다고 생각해야 한다.
- 약한 형태의 거짓말: 하드웨어 문제나 잘못된 설정 같은 경우를 보호해주는 메커니즘을 소프트웨어에 추가할 수 있다
시스템 모델과 현실
시스템에서 발생할 것으로 예상되는 결함의 종류를 정형화 해야 하는데 - 시스템 모델을 정의해서 정형화 한다
- 동기식 모델: 네트워크지연, 프로세스 중단, 시계 오차에 모두 limit있다고 가정 (현실적이진 않음)
- 부분 동기식 모델: 대부분 시간에는 동기식으로 동작 때때로 한계치 초과 (현실적임)
- 비동기식 모델: 타이밍에 대한 어떤 가정도 할 수 없다
노드 장애의 경우
- crash-stop 결함: 어느 순간 죽으면 돌아오지 않음
- crash-recovery 결함: 잠깐 죽었다 다시 살아남
- 비잔틴 결함
crash-recovery, 부분 동기식 모델이 가장 일반적인 시나리오 -> 이 모델에 대응하는 방법
- 알고리즘의 정확성
- safety와 liveness: 안정성 - 나쁜일은 일어나지 않는다, 활동성 - 좋은 일은 결국 일어난다
- 시스템 모델을 현실세계에 대응시키기