300대 규모에서 노드는 늘 죽고 살아납니다. 배포, 재시작, 하드웨어 교체, 순간적인 네트워크 끊김이 모두 여기 해당합니다. 잠깐 죽는 것이 정상 상태입니다.
쓰기 성공 수를 못 채우는 순간
쓰기 성공 수를 둘로 정했으므로 사본 하나가 죽어도 괜찮습니다. 그런데 두 대가 겹쳐 죽으면 둘을 채울 수 없습니다.
요구사항은 쓰기를 거절하지 말라고 했습니다. 그러면 방법은 하나입니다. 원래 사본이 아닌 노드에 대신 받아 두는 것입니다.
대신 받은 노드는 그 데이터를 자기 것과 섞지 않습니다. "이것은 사본 3의 몫" 이라고 표시해 따로 보관하고, 사본 3이 돌아오면 넘기고 자기 쪽에서 지웁니다.
얻는 것과 잃는 것
| 항목 | 내용 |
|---|---|
| 얻는 것 | 두 대가 죽어도 쓰기를 계속 받는다 |
| 잃는 것 | 그 쓰기는 정족수가 약속한 사본에 아직 없다 |
이것이 정족수의 약속을 느슨하게 만듭니다. 읽기 둘을 받아도 그 둘이 원래 사본이면 대신 받아 둔 값을 못 봅니다. 즉 방금 성공한 쓰기가 읽기에서 안 보일 수 있습니다.
요구사항이 쓰기 가용성을 우선했으므로 이 대가를 받아들입니다. 무엇을 우선했는지가 이 판단의 근거입니다.
대신 받아 두는 것의 한계
이 방법은 잠깐 죽는 경우에만 통합니다.
| 죽어 있는 시간 | 결과 |
|---|---|
| 몇 분 | 대신 받아 둔 것을 넘기면 끝난다 |
| 몇 시간 | 대신 받아 둔 양이 그 노드 메모리와 디스크를 압박한다 |
| 영구히 | 넘길 곳이 없다. 다른 방법이 필요하다 |
그래서 보관에 상한을 둡니다. 상한을 넘으면 대신 받기를 멈추고, 그 사본은 영구 장애로 다루는 쪽으로 넘깁니다. 다음 단계가 그 이야기입니다.
돌아온 노드가 위험한 순간
죽었다 돌아온 노드는 낡은 데이터를 들고 있습니다. 그 상태로 읽기를 받으면 옛 값을 최신으로 내놓습니다.
돌아오자마자 읽기를 받으면 낡은 값을 준다
넘겨받기가 끝날 때까지 읽기에서 빼 두는 편이 낫다
읽기 정족수가 둘이므로 낡은 사본 하나가 섞여도 다른 하나가 최신을 줍니다. 그래도 응답 두 개를 비교해 낡은 쪽을 걸러내는 장치가 있어야 이 보호가 작동합니다.
두 죽음을 구분해야 한다
잠깐 죽은 것과 영구히 죽은 것의 대응이 정반대입니다.
| 판단 | 대응 |
|---|---|
| 잠깐 | 데이터를 그대로 두고 기다린다 |
| 영구 | 그 몫을 다른 노드에 새로 채운다 |
성급히 영구로 판단하면 수백 기가를 헛되게 복사하고, 늦게 판단하면 사본 수가 부족한 상태가 오래 이어집니다. 그래서 판단에 시간 기준을 두고, 그 기준을 대신 받아 두는 상한과 맞춥니다.