백엔드 면접 용어 사전
시스템 설계분산 ID

Snowflake ID

타임스탬프·노드·시퀀스를 조합해 정렬 가능한 고유 ID를 만드는 방식.

여러 서버가 조율 없이도 겹치지 않는 고유 ID를 만들어 내는 방식. 트위터가 공개한 구조다.

64비트 구성

┌─┬─────────────────────────┬────────────┬──────────────┐
│0│  타임스탬프 41비트      │ 노드 10비트│ 시퀀스 12비트│
└─┴─────────────────────────┴────────────┴──────────────┘
 ↑
부호 비트(항상 0 — 음수가 되지 않게)
필드비트의미
타임스탬프41기준 시각부터의 밀리초. 2⁴¹ms ≈ 69년
노드 ID102¹⁰ = 1024대의 서버를 구분
시퀀스12같은 밀리초 안의 일련번호. 2¹² = 4096개

초당 생성 가능 수 = 1024대 × 4096개 × 1000ms = 약 41억 개/초

왜 이 구조인가

① 조율이 필요 없다 — 각 서버가 자기 노드 ID만 알면 혼자 만들 수 있다. 중앙 ID 서버에 물어볼 필요가 없어 네트워크 왕복도, 단일 장애점도 없다.

② 시간 순 정렬이 된다 — 타임스탬프가 맨 앞에 있으므로 숫자 크기 순 = 생성 시간 순이다. 이것이 결정적으로 중요하다.

  • DB 인덱스에 순차적으로 삽입된다
  • B+트리 오른쪽 끝에만 추가 → 페이지 분할 최소화
  • UUID(랜덤)는 곳곳에 삽입되어 분할이 잦고 인덱스가 비대해진다

③ 크기가 작다 — 8바이트. UUID는 16바이트(문자열이면 36바이트). InnoDB에서는 모든 보조 인덱스가 PK를 복사하므로 이 차이가 크게 누적된다.

UUID·auto_increment와의 비교

auto_incrementUUID v4Snowflake
크기8B16B8B
정렬
분산 생성✗ (DB 의존)
예측 가능성높음(보안 문제)없음시각은 노출
삽입 성능좋음나쁨좋음

auto_increment의 문제 — 샤딩하면 샤드마다 같은 번호가 생겨 충돌한다. 또 ID를 얻으려면 반드시 DB에 INSERT해야 해서, 미리 ID를 알 수 없다.

UUID v7은 앞부분에 타임스탬프를 넣어 정렬 가능하게 개선한 것으로, Snowflake와 같은 발상이다(다만 16바이트).

함정 ① — 시계 역행

  • NTP 동기화로 시계가 뒤로 감
  • 이미 발급한 것과 같은 타임스탬프
  • 시퀀스도 겹치면 중복 ID

대응

  • 마지막 발급 시각을 기억하고, 역행을 감지하면 대기하거나 예외
  • 작은 역행(수 ms)은 기다리고, 큰 역행은 즉시 실패시켜 사람이 개입
  • NTP를 slew 모드(천천히 보정)로 설정해 급격한 점프를 막는다

함정 ② — 노드 ID 할당

1024개를 어떻게 겹치지 않게 나눠 주느냐가 실제 운영 과제다.

  • 정적 설정 — : 배포 시 지정. 간단하지만 실수하기 쉽다
  • ZooKeeper/etcd : 기동 시 순번을 받아 옴. 확실하지만 의존성 추가
  • 쿠버네티스 — : StatefulSet의 ordinal(pod-0, pod-1)을 사용 ← 깔끔
  • IP 기반 — : 사설 IP 하위 비트를 사용. 대역이 겹치면 위험

같은 노드 ID를 가진 인스턴스가 둘이 되는 순간 중복이 발생하므로 가장 조심해야 할 부분이다.

함정 ③ — 정보 노출

ID를 보면 생성 시각을 알 수 있다. 순차적으로 조회하면 "이 서비스가 하루에 주문을 몇 건 받는지" 추정할 수도 있다. 외부에 노출하는 식별자는 별도의 불투명한 값을 쓰는 편이 안전하다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 시스템 설계·분산 — CAP·복제·샤딩·Saga·서킷브레이커