단일 시스템에서는 하드웨어가 올바르게 동작하면, 같은 연산은 항상 같은 결과를 냄(결정적)
하드웨어 문제가 있으면 시스템은 완전히 실패하며, 성공과 실패 그 중간 상태가 되지는 않음
분산 시트템에서는 시스템의 어떤 부분은 잘 동작하지만 다른 부분은 예측할 수 없는 방식으로 고장날 수 있음(부분 장애, 비결정적)
분산 시스템이 동작하게 만들려면 부분 장애 가능성을 받아들이고 소프트웨어에 내결함성 메커니즘을 넣어야 함
엔지니어는 분산 시스템 하에서 신뢰성의 제약을 이해해야하고, 결함이 발생하면 소프트웨어가 어떻게 동작할지 알고 있어야 할 것
다시말해 분산 시스템에서의 애플리케이션 설계는 신뢰성이 없는 구성 요소를 토대로 신뢰성 있는 시스템을 구축하는 것이며, 이상한 소리같지만 이러한 예는 매우 다양
IP(Internet Protocol, 인터넷 프로토콜)는 신뢰성이 없다. IP를 사용할 때 패킷은 누락 또는 지연되거나 중복될 수도 있
고 순서가 바뀔 수도 있다. TCP(Transmission Control Protocol, 전송 제어 프로토콜)는 IP 위에서 더욱 신뢰성이 높
은 전송 계층을 제공한다. TCP는 손실된 패킷을 재전송하고 중복된 것은 제거하며 패킷을 보낸 순서에 맞춰 재조립되도록 보장해 준다.
하지만 TCP는 패킷 손실 및 중복, 순서가 섞이는 문제는 감춰주지만 네트워크 지연을 마법처럼 제거할 수는 없다.
비공유 시스템, 네트워크로 연결된 다수의 장비를 가정
즉, 각 장비는 자신만의 메모리와 디스크를 갖고 있으며, 다른 장비의 메모리나 디스크에 접근할 수 없음
내부 네트워크(흔히 이더넷)은 비동기 패킷 네트워크임. 즉, 노드는 다른 노드로 메시지(패킷)을 보낼 수 있지만, 네트워크는 메시지가 언제 도착할지 혹은 메시지가 도착하기는 할 것인지 보장하지 않음
따라서 여러 장애 문제를 다루는 흔한 방법은 타임 아웃임
많은 시스템은 결함 있는 노드를 자동으로 감지할 수 있어야 함
로드 밸런서는 죽은 노드로 요청을 그만 보내야 함
단일 리더 복제를 사용하는 분산 데이터베이스에서 리더에 장애가 나면 팔로워 중 하나가 리더로 승격되어야 함
하지만, 네트워크의 불확실성 때문에 노드가 동작 중인지 아닌지 구별하기가 힘듦
그렇다면 거의 유일한 해결책으로 보이는 타임아웃은 얼마나 길어야 할까?
타임아웃이 길면 노드가 죽었다고 선언될 때까지 기다리는 시간이 길어지고, 반대로 짧으면 노드가 일시적으로 느려졌을 뿐인데도 죽었다고 잘못 선언할 위험이 높아짐
만일 노드가 과부하 상황에서 느려졌고, 타임아웃이 짧아 그 노드의 부하를 다른 노드로 전달한다면 연쇄적인 장애를 유발할 수 있음
네트워크에서 패킷 지연의 변동성은 큐 대기 때문인 경우가 많음
여러 다른 노드가 동시에 같은 목적지로 패킷을 보내려고 하면 네트워크 스위치는 패킷을 큐에 넣고 한 번에 하나씩 목적지 네트워크 링크로 넘겨야 함
네트워크는 잘 동작하고 있더라도 들어오는 데이터가 많아서 스위치 큐를 꽉 채울 정도가 되면 패킷이 유실되어 재전송해야 함
패킷이 목적지 장비에 도착했을 때 모든 CPU 코어가 바쁜 상태라면 네트워크에서 들어온 요청은 애플리케이션에서 처리할 준비가 될 때까지 운영체제가 큐에 넣어 둠
TCP는 흐름 제어(flow control)를 수행한다(UDP는 수행하지 않음). 혼잡 회피(congestion avoidance)나 배압(backpressure)이라고도 하는 흐름 제어는 노드가 네트워크 링크나 수신 노드에 과부하를 가하지 않도록 자신의 송신율을 제한하는 것. 데이터가 네트워크로 들어가기 전에도 부가적인 큐 대기를 할 수 있다는 뜻
실험적으로 타임아웃을 선택하는 것이 일반적임. 즉, 여러 장비에 걸쳐 네트워크 속도를 측정하고 적절한 타임아웃을 부여
가장 좋은 방법은 고정된 타임아웃 대신 시스템이 지속적으로 응답 시간과 변동성을 측정해 자동으로 타임아웃을 조절하는 방법임. 파이 증가 장애 감지기(Phi Accural failure detector)를 사용하며, 사용 사례는 Akka와 카산드라가 있음
패킷 전송 지연 시간의 최대치를 고정하며, 하드웨어 수준에서 네트워크를 신뢰성있게 만들 수는 없을까?
전화 네트워크와 비슷한 방식으로 네트워크를 동기식으로 구성할 수 있을까?
전화 네트워크에서 통화를 할 때는 회선(circuit)이 만들어 짐. 통화를 하는 두 명 사이에 있는 전체 경로를 따라서 그 통화에 대해 고정되고 보장된 양의 대역폭이 할당되며 회선은 통화가 끝날 때까지 유지됨
따라서 데이터가 여러 라우터를 거치더라도 큐 대기 문제를 겪지 않게 됨. 네트워크의 다음 홉에 통화당 16비트의 공간이 이미 할당 됐기 때문(큐 대기가 없도록함으로서 최대치를 고정)
이를 제한 있는 지연이라고 함
전화 네트워크의 회선은 TCP 연결과 매우 다름
회선은 만들어져 있는 동안 다른 누구도 사용할 수 없는 고정된 양의 예약된 대역폭이지만 TCP 연결의 패킷은 가용한 네트워크 대역폭을 기회주의적으로 사용
이더넷과 IP는 큐 대기의 영향을 받는 패킷 교환(packet-switch) 프로토콜이고 따라서 네트워크에 기약 없는 지연이 존재함
데이터센터 네트워크와 인터넷이 패킷 교환을 사용하는 이유는 순간적으로 몰리는 트래픽(bursty traffic)에 최적화됐기 때문임
반면 회선은 통화를 하는 동안 보내는 초당 비트 개수가 상당히 고정돼 있는 음성과 영상 통화에 적합함