클라이언트가 키를 획득(A)하면 서버는 다음 세 가지 중 하나로 응답합니다.
| 키 상태 | 서버 동작 | 응답 |
|---|---|---|
| 등록 안 됨 | 즉시 등록(만료 = now + lease), 토큰 발급 | A + token + key |
| 등록됨 + 만료 지남 | 갱신(now + lease), 새 토큰 발급 | A + token + key |
| 등록됨 + 유효(점유 중) | 대기열에 등록, 응답 보류 | 반납/만료 시 A, wait 초과 시 T |
R)하면 대기열 맨 앞에게 직접 인계됩니다 — 재경쟁 없이 새 토큰과 함께 즉시 넘어갑니다.lease는 안전망입니다. 클라이언트가 죽거나 반납을 깜빡해도, lease 시간이 지나면 서버가 자동으로 키를 회수해 다음 대기자에게 넘길 수 있습니다. 그래서 정상적인 반납 흐름과 별개로 항상 lease를 넉넉히, 하지만 죽었을 때 너무 오래 묶이지 않을 값으로 설정하는 것이 좋습니다.wait는 획득 대기 상한입니다. 0이면 무한 대기, 그 외에는 그 시간(초) 안에 못 받으면 서버가 포기하고 T(타임아웃)로 응답합니다 — grant 없이 끝나므로 락이 새는 일이 없습니다.A 응답에 담긴 token은 그 grant의 단조 증가 u64입니다. 획득할 때마다 이전 어떤 토큰보다도 큰 값이 발급됩니다. 페일오버가 일어나도 새로 액티브가 된 노드는 복제받은 최대 토큰보다 큰 값에서 이어갑니다(승계) — 그래서 클러스터 전체를 통틀어도 토큰은 계속 증가합니다.
보호하려는 리소스(계좌, 파일, 주문 등)가 "지금 가진 토큰이 마지막으로 본 토큰보다 큰가"만 검증하면, lease 만료 뒤 뒤늦게 깨어난 클라이언트가 이미 무효화된 낮은 토큰으로 접근하는 것을 거부할 수 있습니다. 이 덕분에 락 서버가 매 순간 완벽히 일관적이지 않아도 안전을 지킬 수 있습니다.
공식 클라이언트들은 공통으로 다음과 같이 동작합니다(언어별 세부 API는 라이브러리 참고).
lease가 회수하지만, 그 전에 다른 대기자에게 더 빨리 넘겨주기 위함).peers 목록의 순서가 승격 우선순위입니다(맨 앞이 최우선). 살아 있는 노드 중 우선순위가 가장 높은 하나가 액티브, 나머지는 그 상태를 실시간 복제받는 스탠바이가 됩니다.M)받아 그쪽으로 옮겨갑니다.Ctrl+C) 시에는 액티브가 후임에게 먼저 승격을 넘긴(핸드오프) 뒤 클라이언트를 리다이렉트해, 액티브 공백을 최소화합니다.이 승격 방식은 쿼럼(과반 투표) 기반이 아닙니다. 그래서 홀수/짝수 대수가 중요하지 않고, 한 대라도 살아 있으면 서비스가 유지됩니다.
| 서버 수 | 무정지 | 동시 장애 허용 | 비고 |
|---|---|---|---|
| 1대 | ✗ | — | 가장 빠름. 재기동 시 짧은 순단 발생 |
| 2대 | ✓ | 1대 | 무정지의 최소 구성. 대부분 이걸로 충분 |
| 3대 | ✓ | 2대 | 한 대 점검 중에도 이중화 유지 |
| 4대+ | ✓ | N−1대 | 전파 비용만 늘어남 — 권장하지 않음 |
우선순위 기반 승격은 합의가 아니므로, 네트워크 파티션 순간에는 양쪽이 잠깐 동시에 액티브가 될 수 있고, 비동기 복제 특성상 페일오버 순간 일부 grant가 유실될 수 있습니다. 즉 페일오버/파티션 구간에서 상호배제가 100% 보장되지는 않습니다. 강한 보장이 필요하면 앞서 설명한 펜싱 토큰을 보호 대상 리소스가 검증하도록 구현하세요 — 오래된(작은) 토큰을 거부하면 락 서버가 완벽히 일관적이지 않아도 안전합니다.