7. 분산 시스템을 위한 유일 ID 생성기
요구사항
ID는 유일해야한다
ID는 숫자로만구성되어야 한다
ID는 64 비트로 표현될 수 있는 값이 어야 한다
unsigned 64bit = 0 ~ 2^64 - 1
signed 64 bit = -2^63 ~ 2^63 - 1
ID는 발급 날짜에 따라 정렬 가능해야 한다
초당 10,000 개의 ID를 만들 수 있어야 한다
해결 방법
다중 마스터 복제
데이터베이스의 auto_increment 기능을 활용하는 것
다음 ID의 K (데이터베이스 서버의 수) 만큼 증가 시킴
문제점
여러 데이터 센터에 걸쳐 규모를 늘리기 어렵고,
ID 유일성은 보장되지만, 시간이 흐름에 맞추어 커지도록 보장할 수 없음.
서버를 추가하거나 삭제할 때도 정상적으로 동작하도록 보장하기 어려움
UUID
시스템에 저장되는 정보를 유일하게 식별하기 위한 128 비트의 수
장점
단순, 서버가 조율 필요없음. 동기화 이슈 없음
규모 확장도 쉽다. 왜? 각 서버가 자기가 쓸 ID를 알아서 만드는 구조여서
단점
128비트, 길다. (요구사항에 맞지 않는다.)
시간 순으로 정렬할 수 없다 (요구사항에 맞지 않음)
ID에 숫자가 아닌 문자가 들어간다. (요구사항에 맞지 않음)
티켓 서버
![[Pasted image 20250824132226.png]]
auto_increment 기능을 갖춘 데이터베이스 서버(=티켓 서버) 를 하나만 가져간다.
장점
유일성 보장되는 구조.
숫자로 만든 ID
구현 쉽고, 중소 규모 애플리케이션에 적합
단점
SPOF (Single-Point-Of-Failure)
티켓 서버 장애는 모든 시스템에 영향
트위터 스노플레이크
생성해야하는 ID 구조를 여러 절로 분할 하는 것 ![[Pasted image 20250824132413.png]]
sign bit : 1bit, 음수 양수를 구분하는데 사용
timestamp bit : 41bit, 기원시각(epoch) 이후 몇밀리초가 경과했는지 나타내는 값.
datacenter id : 5bit, 2^5 = 32개 데이터 센터를 지원
server id : 5bit 데이터센터당 32개 서버 사용할 수 있음.
일련 번호 : 12 bit, 각 서버에서는 ID를 생성할 때 마다 일련번호를 1만큼 증가. 이 값은 1 밀리초 가 경과할 때 마다 0으로 초기화 됨.
상세 설계
![[Pasted image 20250824132413.png]]
데이터 센터 ID, 서버 ID는 시스템 시작할 때 결정 = 운영 중에는 변경되지 않음.
타임스탬프, 일련번호는 운영 중에 생성되는 값
타임 스탬프
시간 순으로 정렬되어야 한다는 조건을 만족해야함
과정
현재 시간을 밀리초로 가져오기
기준 시간 (Epoch) 빼기
41비트에 맞추기
// 1. 현재 시간을 밀리초 단위로 얻기
const currentTime = Date.now(); // 예: 1724484123456
// 2. Snowflake의 기준 시간 (보통 서비스 시작 시점을 설정)
const EPOCH = 1288834974657; // 2010-11-04 01:42:54 (Twitter 기준)
// 2. 실제 타임스탬프 = 현재시간 - 기준시간
const timestamp = currentTime - EPOCH;
// 3. 41비트로 제한 (최대값: 2^41 - 1)
const snowflakeTimestamp = timestamp & 0x1FFFFFFFFFF;
왜 기준 시간(Epoch) 를 빼는가?
절약 : 2010년 이후의 시간만 저장하면 더 오래 사용 가능
2^41 - 1 = 2,199,023,255,551
1970년 기준: 이미 한계에 근접
2010년 기준: 69년의 여유 확보
효율성 : 더 작은 숫자로 더 긴 시간을 표현
41비트로 얼마나 오래 사용할 수 있는가?
2^41 밀리초 = 약 69년
2010년 기준으로 2079년까지 사용가능
마무리
시계 동기화 (clock synchronization)
ID 생성 서버가 전부 같은 시계를 사용했다.
그러지 않을 수 있음.
NTP(Network Time Protocol)
각 selection 의 길이 최적화
동시성이 낮고, 수명이 긴 어플리케이션이라면 '일련번호' 의 비트를 줄이고, '타임스탬프' 길이를 늘리는게 효과적일 수 있음
clock synchronization
문제
시계 동기화 오차
노드1: 2025-08-24 15:30:00.100
노드2: 2025-08-24 15:30:00.050 (50ms 늦음)
노드3: 2025-08-24 15:30:00.200 (100ms 빠름)
노드가 가지고 있는 시계에 따라서 ID 순서가 다를 수 있음.
해결 방법
NTP(Network Time Protocol)
# 정기적으로 시계 동기화
ntpdate -s time.nist.gov
인터넷을 통해, 컴퓨터들의 시계를 정확하게 맞춰줌
어떻게 동작하는 가?
Stratum 0: 원자시계, GPS 위성 (최고 정확도)
↓
Stratum 1: 직접 연결된 서버들 (time.nist.gov 등)
↓
Stratum 2: Stratum 1에서 시간을 받는 서버들
↓
Stratum 3: 일반 회사 서버들
↓
Stratum 4: 개인 컴퓨터들
1. 내 컴퓨터 → NTP 서버: "지금 몇 시예요?" (T1 시점에 전송)
2. NTP 서버: 요청 받음 (T2 시점에 도착)
3. NTP 서버 → 내 컴퓨터: "지금 XX시입니다" (T3 시점에 응답)
4. 내 컴퓨터: 응답 받음 (T4 시점에 도착)
네트워크 지연까지 고려한다.
왕복 시간 = (T4 - T1) - (T3 - T2)
한쪽 지연 = 왕복 시간 / 2
실제 서버 시간 = T3 + 한쪽 지연
정확도
LAN 환경: ±1ms 이내
인터넷: ±10-100ms
일반적: ±50ms 정도 한계
네트워크 지연에 영향 받음
완벽한 동기화는 불가능
Last updated
Was this helpful?