반응형
데이터 중심 애플리케이션 설계 8장. 분산 시스템의 골칫거리를 정리한 내용입니다.
분산 시스템에서는 공유 메모리가 없고 지연 변동이 큰 신뢰할 수 없는 네트워크를 통해 메시지를 보낼 수만 있을 뿐이며 부분 장애, 신뢰성 없는 시계, 프로세스 중단에 시달릴 수 있다.
분산 시스템의 어려움
- 네트워크로 패킷을 보내려고 할 때는 언제나 패킷이 손실되거나 임의대로 지연될 수 있다. (마찬가지로 응답도 손실되거나 지연될 수 있으므로 응답을 받지 못하면 메시지가 전달됐는지 아닌지를 알 수 없다)
- 노드의 시계는 다른 노드와 심하게 맞지 않을 수도 있고, 시간이 갑자기 앞뒤로 뛸 수도 있다. 그리고 시계의 오차 구간을 측정할 좋은 수단이 없을 가능성이 크므로 분산 시스템에서 시계에 의존하는 것은 위험하다.
- 프로세스는 실행 도중 어느 시점에서(stop-the-world GC 등) 상당한 시간 동안 멈출 수 있고, 다른 노드에 의해 죽었다고 선언될 수 있으므로 되살아났을 때 멈췄다는 사실을 알지 못할 수도 있다.
부분 실패
부분 실패가 생길 수 있다는 사실은 분산 시스템의 뚜렷한 특성으로, 소프트웨어가 다른 노드와 연관된 뭔가를 하려고 할 떄는 언제나 가끔씩 실패하거나 임의로 느려지거나 전혀 응답하지 않을 가능성이 있다.
- 분산 시스템에서는 우리는 구성 요소의 일부가 고장 나더라도 전체로서의 시스템은 계속 동작할 수 있도록 부분 실패에 대한 내성을 소프트웨어에 내장하려고 노력해야 한다.
결함 감지
결함을 견뎌내려면 그것을 감지하는 게 첫 걸음이지만 그조차도 어렵다.
- 대부분의 시스템은 노드에 장애가 발생했는지 알 수 있는 정확한 메커니즘이 없어서 대부분의 분산 알고리즘은 원격 노드를 아직 쓸 수 있는지 결정하기 위해 타임아웃을 사용한다.
- 그러나 타임아웃은 네트워크 장애와 노드 장애를 구별할 수 없고, 변동이 큰 네트워크 지연 때문에 때때로 노드가 죽은 것으로 잘못 의심받을 수 있다.
정족수
분산 시스템에서 노드가 상황에 대한 자신의 판단을 반드시 믿을 수 없다. 분산 시스템에서 진실을 다수결로 결정된다.
- 분산 시스템은 한 노드에만 의존할 수는 없다.
- 노드는 언제든 장애가 나서 잠재적으로 시스템이 멈추고 복구할 수 없게 될 수도 있기 때문이다.
- 대신 여러 분산 알고리즘은 정족수 (노드들 사이의 투표)에 의존한다.
- 특정 노드 하나에 대한 의존을 줄이기 위해 결정을 하려면 여러 노드로부터 어떤 최소 개수의 투표를 받아야 한다.
- 노드의 과반수 이상을 정족수로 삼는 게 가장 흔하다.
- 과반수 정족수를 사용하면 개별 노드들에 장애가 나더라도 시스템은 계속 동작할 수 있다. (노드가 3대면 한 대에 장애가 나도 괜찮다)
리더와 잠금
- 스플릿 브레인을 피하기 위해 오직 한 노드만 데이터베이스 파티션의 리더가 될 수 있다.
- 특정한 자원이나 객체에 동시에 쓰거나 오염시키는 것을 방지하기 위해 오직 하나의 트랜잭션이나 클라이언트만 어떤 자원이나 객체의 잠금을 획득할 수 있다.
- 사용자명으로 사용자를 유일하게 식별할 수 있어야 하므로 오직 한 명의 사용자만 특정한 사용자명으로 등록할 수 있다.
분산 시스템에서 이를 구현하려면 주의이해야 한다.
어떤 노드가 스스로를 리더라고 믿을지라도 노드의 정족수도 반드시 동의한다는 뜻은 아니다.
- 어떤 노드가 이전에 리더였더라도 시간이 흐른 사이(네트워크 단절이나 GC 중단 등의 이유)에 다른 노드들이 그 노드가 죽었다고 선언하면 그 노드는 강등되고 다른 리더가 이미 선출됐을지도 모른다.
- 노드의 과반수가 어떤 노드가 죽었다고 선언했음에도 그 노드가 리더인 것처럼 계속 행동한다면 신중하게 설계되지 않은 시스템에서는 문제를 유발할 수 있다. (데이터 오염 등)
펜싱 토큰
- 파일 저장소와 같은 리소스에 대한 접근을 보호하기 위해 잠금이나 임차권을 쓸 때, 자신이 선택된 자라고 잘못 믿고 있는 노드가 나머지 시스템을 방해할 수 없도록 보장해야 한다. 이 목적을 달성하는 상당히 단순한 기법으로 펜싱이 있다.
- 잠금 서버가 잠금이 임차권을 승인할 때마다 펜싱 토큰도 반환하다고 가정한다. (펜싱 토큰은 잠금이 승인될 때마다 증가하는 숫자이다.)
- 클라이언트 1은 33번 토큰으로 임차권을 획득했지만, 오랫동안 중단돼서 임차권이 만료된다.
- 클라이언트 2는 34번 토큰으로 임차권을 얻은 후 저장소 서비스로 34번 토큰을 포함한 쓰기 요청을 보낸다.
- 그 후 클라이언트 1이 되살아나고 저장 서비스로 33번 토큰을 포함한 쓰기 요청을 보내지만, 저장소 서버는 자신이 더 큰 토큰 번호(34)를 가진 쓰기를 이미 처리했음을 기억하므로 33번 토큰으로 온 요청을 거부한다.
이 매커니즘은 자원 자체가 이미 처리된 것보다 오래된 토큰을 사용해서 쓰는 것을 거부함으로써 토큰을 확인하는 활동적인 역할을 맡아야 한다.
반응형
'공통 > 인프라 & 시스템 설계' 카테고리의 다른 글
[CDN] CDN이란? CDN의 구성요소 간단 정리 (0) | 2022.08.13 |
---|---|
[데이터 중심 애플리케이션 설계 정리] 스트림, Dual Write, CDC 정리 (0) | 2022.04.15 |
[대규모 시스템 설계 기초 정리] 피드 시스템 설계 (0) | 2022.01.27 |
[데이터 중심 애플리케이션 설계 정리] 6. 파티셔닝 (0) | 2022.01.25 |
[대규모 시스템 설계 기초 정리] 분산 키-값 저장소 with Cassandra DB (0) | 2022.01.18 |