PATTERN · INTERMEDIATE읽기 20분검토일 2026-08-29
분산 환경의
고유 ID 생성 설계
충돌하지 않는 숫자만 만들면 끝나는 문제가 아닙니다. 정렬 가능한 ID가 시계 역행과 worker 소유권 충돌에서도 중복되지 않도록 두 장애를 따로 막아야 합니다.
운영자 직접 작성·기술 검토·최종 검토 2026.08.29
개념 이해장애 대응운영 관점진도 저장
#30초 핵심 요약
시계 역행과 worker ID 충돌은 원인이 다릅니다. 시간 문제는 논리 시각 guard로, 소유권 문제는 lease와 fencing token으로 막고, 한쪽 안전장치가 다른 쪽을 대신하지 않게 설계합니다.
발급 경로로컬·무중앙 RPC
충돌 방지Lease + fencing
시계 이상Guard + alert
DESIGN DECISION · 설계 판단
시계 역행과 worker ID 충돌을 어떻게 다른 장애로 막을 것인가?
예시 전체 피크
1,000,000 ID/s
설계 가정
예시 worker 공간
1,024개
계산 결과
worker 이론 한계
4,096,000 ID/s
계산 결과
최종 선택
논리 시각 guard + worker lease·fencing
시간·worker·sequence 조합은 로컬에서 생성합니다. 시계 역행은 마지막 논리 시각과 sequence로 막고, worker 소유권 충돌은 임대와 fencing token으로 오래된 생성기를 차단합니다.
선택 이유
- ID 생성 핫패스를 중앙 DB 왕복에서 분리할 수 있습니다.
- 시간원 문제와 소유권 문제를 서로 다른 지표·대응으로 조사할 수 있습니다.
- 저장 경로가 오래된 fencing token을 거부해 분단된 구 프로세스를 차단합니다.
포기한 대안
시계가 정상이라면 worker ID도 안전하다고 가정
두 프로세스가 같은 worker ID를 가지면 정상 시각과 같은 sequence에서도 실제 중복 ID를 만들 수 있습니다.
감수한 단점
- worker 임대와 fencing 검증을 운영해야 합니다.
- 큰 시계 역행이나 sequence 소진 때 발급을 멈출 수 있습니다.
- ID는 정렬 힌트일 뿐 리전 간 정확한 사건 순서를 보장하지 않습니다.
01 · REQUIREMENTS
유일성과 순서를 분리해서 묻는다
# 요구사항“정렬되는 ID”와 “전역 순서가 보장되는 ID”는 다릅니다. 먼저 namespace, 공개 여부, 리전 독립성, 초당 피크를 확정해 어떤 종류의 고유성이 필요한지 좁힙니다.
R1전역 유일성서로 다른 worker와 재시작 이후에도 동일 bit 조합을 만들지 않습니다.
R2정렬은 힌트시간 비트는 인덱스 지역성을 돕지만 동시 이벤트의 총순서를 뜻하지 않습니다.
R3고가용 발급registry는 제어 평면이고, 정상 상태 발급에는 매 요청 참여하지 않습니다.
R4공개 경계추측 가능한 ID를 URL에 쓰더라도 접근 제어를 생략하지 않습니다.
02 · HIGH-LEVEL DESIGN
비트 조합과 clock guard의 이중 방어
# 아키텍처아래 값은 41비트 시간·10비트 worker·12비트 sequence라는 예시 설계 가정입니다. UUIDv7은 표준 UUID 형식이며 이 worker/sequence 구성을 요구하지 않습니다.
로컬 ID 발급과 시계 역행 방어 SVG DIAGRAM · 예시 bit budget
구분해야 할 두 장애 · 시계 역행은 한 생성기의 시간원 문제이고, worker-id 충돌은 둘 이상의 생성기가 같은 소유권을 가진 배포·제어 평면 문제입니다. sequence 증가만으로 worker-id 충돌을 해결할 수 없습니다.
03 · WRITE / READ FLOW
발급은 로컬, 소유권은 검증 가능하게
# 흐름1Lease 확보시작 시 registry의 CAS로 worker-id와 fencing token을 임대합니다.
2시간 비교now와 last_timestamp를 비교해 새 ms 또는 같은 ms를 판별합니다.
3Sequence 증가같은 ms면 증가시키고 소진 시 다음 ms까지 backpressure를 겁니다.
4쓰기·읽기객체의 primary key로 쓰고, 읽기 정렬에는 정확한 전역 순서를 가정하지 않습니다.
04 · TRADEOFFS
표준 UUID, 중앙 시퀀스, bit 조합의 선택
# 트레이드오프조합형 ID는 중앙 왕복을 줄이는 대신 시간과 worker 소유권을 직접 운영해야 합니다. 정렬성이 필요 없는 경로까지 같은 방식을 강제하지 않고 요구 조건에 따라 UUID·중앙 시퀀스와 나눕니다.
DB sequence
중앙
단순한 순서 모델
primary·failover가 쓰기 한계가 될 수 있음
UUIDv4
로컬
노드 조율 불필요
확률적 충돌, 인덱스 지역성 약함
UUIDv7
로컬
시간 정렬에 유리한 표준 형식
시계·단조성 구현 정책 확인
time + worker + seq
로컬 + 제어
작고 높은 처리량
lease·fencing·clock guard 필요
05 · FAILURE MODES
충돌이 나기 전에 멈추고 증명한다
# 장애 5가지↶시계 역행
NTP 보정이나 VM 재개 뒤 현재 시간이 last_timestamp보다 작아집니다.
대응 · logical time 유지 또는 fail closed; rollback 폭과 지속 시간을 경보로 보냅니다.
≡worker-id 충돌
두 프로세스가 같은 worker bit를 동시에 사용하면 실제 중복 후보가 생깁니다.
대응 · CAS lease와 fencing token으로 이전 소유자를 격리합니다.
↑sequence 소진
한 worker가 한 밀리초의 sequence 공간을 모두 씁니다.
대응 · 다음 tick 대기, 큐·rate limit, worker 분산으로 p99를 보호합니다.
⌁registry 분할
새 인스턴스가 안전하게 lease를 얻거나 갱신할 수 없습니다.
대응 · 새 발급자는 fail closed; quorum·grace 정책을 사전 시험합니다.
↻재시작 상태 유실
프로세스가 마지막 논리 시간을 잊은 채 너무 이른 시각에서 시작합니다.
대응 · 안전 상태 저장 또는 시작 보류로 last time 재사용을 막습니다.
⌛timestamp 수명 종료
epoch와 timestamp bit의 유효 기간이 다가오면 해석·발급이 깨질 수 있습니다.
대응 · versioned generator를 병행하고 파서·저장소 호환성을 검증합니다.
06 · OPERATIONS
보안·관측·비용을 발급기와 함께 운영한다
# 운영⌾보안과 개인정보ID는 인증 토큰이 아닙니다. 객체마다 인가를 확인하고, 로그의 원문 ID는 hash·샘플·보존 기간으로 통제합니다.
audit: lease change + instance identity
⌁관측 가능성충돌의 최종 신호인 duplicate key는 0이어야 합니다. rollback, sequence 대기, lease 잔여 시간을 분리해 봅니다.
clock_rollback_ms · sequence_wait_ms
₩비용과 용량발급 RPC는 줄지만 quorum registry, 감사 로그, cardinality, 백업과 chaos test 비용은 남습니다.
8B ID ≠ index + replica + WAL cost
면접 모드 · 추가 질문05:00
“여러 리전에서 초당 100만 개 주문 ID를 발급해야 합니다. DB sequence를 쓰지 않는다면 bit budget을 어떻게 정하고, 시계 역행과 worker-id 충돌을 각각 어떻게 막으며, 어떤 지표로 안전성을 증명하겠습니까?”
요구사항 분리lease·fencingclock guardduplicate key 검증
답변 구조 보기 5단계
- 먼저 “전역 유일성, 정렬 정도, 공개 여부, 리전 독립성”을 확인 질문으로 분리한다.
- 낮은 규모라면 DB sequence를 우선 제시하고, 중앙 병목·다중 리전 요구가 생길 때 로컬 generator로 확장한다.
- 시간+worker+sequence의 bit budget과 초당 상한을 계산하되, 계산값을 설계 가정이라고 명시한다.
- 시계 역행과 worker-id 충돌을 별개의 장애로 설명한다. 각각 clock guard, lease·fencing을 제시한다.
- duplicate key, rollback, sequence 포화, lease 만료를 지표·경보·chaos test로 검증하고, UUIDv7·DB sequence와의 트레이드오프로 마무리한다. 이번 선택: 시간원과 worker 소유권을 서로 다른 안전장치로 운영한다. 깨지는 신호: clock rollback과 fencing 불일치를 하나의 “ID 오류” 지표로만 합친다. 다음 검증: 46ms 역행과 중복 worker 배포를 독립 주입해 각각의 차단 경로가 다른지 확인한다.
INTERVIEW ↔ PRACTICE · 면접과 실무의 차이
46ms 시계 역행과 중복 worker 배포를 분리해 복구하기
INTERVIEW · 면접
두 장애의 원인과 안전장치가 다름을 먼저 설명합니다.
- 시계 역행은 논리 시각 유지 또는 fail-closed로 막습니다.
- worker 충돌은 lease·fencing으로 구 프로세스를 격리합니다.
- duplicate key를 높은 우선순위 무결성 경보로 다룹니다.
PRACTICE · 실무
시간원과 소유권 장애를 독립적으로 주입합니다.
- 46ms 역행 구간에서 중복 ID 0건을 확인합니다.
- 한 worker ID에 활성 token 하나만 남깁니다.
- sequence 포화와 임대 만료를 별도 대시보드로 관측합니다.
NEXT PATTERN분산 레이트 리미터 설계
→
EDITORIAL NOTES
작성·검토·참고 자료
- 콘텐츠 원칙
- 이 문서는 독립적으로 재작성한 한국어 학습 자료입니다. 사실과 학습용 설계 가정을 구분합니다.
- 작성·기술 검수
- 프로젝트 운영자가 직접 작성·기술 검토했습니다. 주제별 공식·1차 자료와 명시적인 설계 가정을 확인하며, 독립적인 제3자 검수가 아닙니다. 경력 범위와 검수 원칙 보기
- 최종 검토
- 예상 학습 시간
- 20분
참고 자료
- IETF RFC 9562, Universally Unique IDentifiers (UUIDs): https://www.rfc-editor.org/rfc/rfc9562.html
- Discord Developer Documentation, Snowflakes: https://discord.com/developers/docs/reference#snowflakes
- IETF RFC 5905, Network Time Protocol Version 4: https://www.rfc-editor.org/rfc/rfc5905.html
- 이 글의 처리량·비트 배치·운영 정책은 특정 서비스의 보장값이 아닌 설계 가정이며, 실제 환경에서는 부하 시험과 장애 주입으로 검증해야 한다.
사실 오류·출처 정정은 문의·정정 페이지로 알려 주세요.