menuTicketing

동작 원리


락의 획득과 반납

클라이언트가 키를 획득(A)하면 서버는 다음 세 가지 중 하나로 응답합니다.

키 상태서버 동작응답
등록 안 됨즉시 등록(만료 = now + lease), 토큰 발급A + token + key
등록됨 + 만료 지남갱신(now + lease), 새 토큰 발급A + token + key
등록됨 + 유효(점유 중)대기열에 등록, 응답 보류반납/만료 시 A, wait 초과 시 T
  • 반납은 FIFO로 공정하게 처리됩니다. 보유자가 반납(R)하면 대기열 맨 앞에게 직접 인계됩니다 — 재경쟁 없이 새 토큰과 함께 즉시 넘어갑니다.
  • lease는 안전망입니다. 클라이언트가 죽거나 반납을 깜빡해도, lease 시간이 지나면 서버가 자동으로 키를 회수해 다음 대기자에게 넘길 수 있습니다. 그래서 정상적인 반납 흐름과 별개로 항상 lease를 넉넉히, 하지만 죽었을 때 너무 오래 묶이지 않을 값으로 설정하는 것이 좋습니다.
  • wait는 획득 대기 상한입니다. 0이면 무한 대기, 그 외에는 그 시간(초) 안에 못 받으면 서버가 포기하고 T(타임아웃)로 응답합니다 — grant 없이 끝나므로 락이 새는 일이 없습니다.

펜싱 토큰

A 응답에 담긴 token그 grant의 단조 증가 u64입니다. 획득할 때마다 이전 어떤 토큰보다도 큰 값이 발급됩니다. 페일오버가 일어나도 새로 액티브가 된 노드는 복제받은 최대 토큰보다 큰 값에서 이어갑니다(승계) — 그래서 클러스터 전체를 통틀어도 토큰은 계속 증가합니다.

보호하려는 리소스(계좌, 파일, 주문 등)가 "지금 가진 토큰이 마지막으로 본 토큰보다 큰가"만 검증하면, lease 만료 뒤 뒤늦게 깨어난 클라이언트가 이미 무효화된 낮은 토큰으로 접근하는 것을 거부할 수 있습니다. 이 덕분에 락 서버가 매 순간 완벽히 일관적이지 않아도 안전을 지킬 수 있습니다.

클라이언트의 동작

공식 클라이언트들은 공통으로 다음과 같이 동작합니다(언어별 세부 API는 라이브러리 참고).

  • 주소마다 영속 연결을 하나씩 유지하고 백그라운드에서 관리합니다. 주소를 하나만 주면 내부적으로 같은 노드에 연결을 두 개 유지해, 그중 하나가 잠깐 끊겨도 서비스가 끊기지 않게 합니다.
  • 라운드로빈으로 연결을 고릅니다. 연결이 끊긴 노드는 자동으로 제외되고, 3초 간격으로 백그라운드에서 재연결을 시도합니다.
  • 요청은 파이프라이닝됩니다. 응답을 기다리지 않고 다음 요청을 보낼 수 있고, 응답 순서가 요청 순서와 달라도 됩니다 — 클라이언트는 에코된 (op, 키) 조합으로 어떤 요청에 대한 응답인지 구분합니다. 같은 (op, 키) 조합의 요청이 여러 개면 보낸 순서대로 매칭됩니다.
  • 획득 시도 중 연결이 끊기면 다음 연결로 자동 전환합니다. 등록된 연결 수만큼 시도한 뒤에도 쓸 수 있는 연결이 없으면 그제서야 오류로 알립니다.
  • 반납은 5초 동안 200ms 간격으로 재시도합니다 — 반납 순간에 마침 연결이 끊겨 있어도 락이 서버에 계속 남아있지 않도록(결국은 lease가 회수하지만, 그 전에 다른 대기자에게 더 빨리 넘겨주기 위함).

클러스터 — 우선순위 기반 무정지

  • peers 목록의 순서가 승격 우선순위입니다(맨 앞이 최우선). 살아 있는 노드 중 우선순위가 가장 높은 하나가 액티브, 나머지는 그 상태를 실시간 복제받는 스탠바이가 됩니다.
  • 클라이언트 요청은 액티브만 처리합니다. 스탠바이에 접속한 클라이언트는 액티브 주소로 안내(M)받아 그쪽으로 옮겨갑니다.
  • 액티브 장애/재기동 → 스탠바이가 승격해서 이어받습니다.
  • graceful 종료(Ctrl+C) 시에는 액티브가 후임에게 먼저 승격을 넘긴(핸드오프) 뒤 클라이언트를 리다이렉트해, 액티브 공백을 최소화합니다.
  • 자동 데모션: 네트워크 파티션 등으로 두 노드가 동시에 액티브가 되면, 우선순위가 낮은 쪽이 상대를 감지해 스스로 스탠바이로 물러납니다(영구 스플릿 브레인 방지).

이 승격 방식은 쿼럼(과반 투표) 기반이 아닙니다. 그래서 홀수/짝수 대수가 중요하지 않고, 한 대라도 살아 있으면 서비스가 유지됩니다.

서버 수무정지동시 장애 허용비고
1대가장 빠름. 재기동 시 짧은 순단 발생
2대1대무정지의 최소 구성. 대부분 이걸로 충분
3대2대한 대 점검 중에도 이중화 유지
4대+N−1대전파 비용만 늘어남 — 권장하지 않음

정합성에 대해 알아둘 것

우선순위 기반 승격은 합의가 아니므로, 네트워크 파티션 순간에는 양쪽이 잠깐 동시에 액티브가 될 수 있고, 비동기 복제 특성상 페일오버 순간 일부 grant가 유실될 수 있습니다. 즉 페일오버/파티션 구간에서 상호배제가 100% 보장되지는 않습니다. 강한 보장이 필요하면 앞서 설명한 펜싱 토큰을 보호 대상 리소스가 검증하도록 구현하세요 — 오래된(작은) 토큰을 거부하면 락 서버가 완벽히 일관적이지 않아도 안전합니다.