1단계 문제 이해 및 설계 번위 확정
2단계 개략적 설계안 제시 및 동의 구하기
분산 시스템에서 유일성이 보장되는 ID 만드는 선택지
다중 마스터 복제
UUID
티켓 서버
트위터 스노플레이크 접근법
다중 마스터 복제
데이터베이스의 auto_increment 기능을 활용하는 접근법
다음 ID의 값을 구할 때 +1 증가가 아니라 +k(현재 사용 중인 데이터베이스 서버의 수) 증가
=> 이 방법을 통해 규모 확장성 문제를 어느 정도 해결할 수 있음
=> 초당 생산 가능 ID 수도 늘릴 수 있기 때문
단점
- 여러 데이터 센터에 걸쳐 규모를 늘리기 어려움
- ID의 유일성은 보장되지만, 그 값이 시간의 흐름에 맞춰 커지도록 보장 X
- 서버를 추가하거나 삭제할 때 잘 동작하게 만들기 어려움
UUID
UUID: 컴퓨터 시스템에 저장되는 정보를 유일하게 식별하기 위한 128비트짜리 수
- UUID 값은 충돌 가능성이 아주 낮음
- 서버 간 조율 없이 독립적으로 생성 가능
=> n개의 웹 서버가 별도의 ID 생성기를 사용해 독립적으로 ID를 만들어냄
장점
- UUID를 만드는 것은 단순하고, 서버 사이의 조율이 필요하지 않아 동기화 이슈 X
- 각 서버가 자기가 쓸 ID를 알아서 만드는 구조라 규모 확장 쉬움
단점
- ID가 128비트로 긴데, 이번 장에서 다루는 문제의 요구사항은 64비트
- ID를 시간순으로 정렬할 수 X
- ID에 숫자 아닌 값이 포함될 수 있음
티켓 서버
플리커(Flickr)가 분산 기본 키를 만들어내기 위해 이 기술을 이용함
이 아이디어의 핵심은 auto_increment 기능을 갖춘 데이터베이스 서버(티켓 서버)를 중앙 집중형으로 하나만 사용하겠다는 것
장점
- 유일성이 보장되는 오직 숫자로만 구성된 ID를 쉽게 만들 수 있음
- 구현이 쉽고 중소 규모 애플리케이션에 적합함
단점
티켓 서버가 SPOF가 됨
-> 이 서버에 장애가 발생하면 해당 서버를 이용하는 모든 시스템이 영향을 받음
-> n개의 티켓 서버를 놓는 경우 데이터 동기화 같은 새로운 문제 발생
트위터 스노플레이크 접근법
이 방법은 이번 장에서 풀어야 하는 문제의 요구사항을 만족시킬 수 있음
그러나 ID를 바로 생성하는 대신 각개 격파 전략(divide and conquer)을 적용해 보자
생성해야 하는 ID의 구조를 여러 절(section)으로 분할하는 것임

- 사인 비트: 1비트를 할당, 지금으로는 쓰임새가 없지만 나중을 위해 유보 -> 음수와 양수를 구별할 때 사용할 수 있음
- 타임스탬프: 41비트 할당, 기원 시간 이후로 몇 밀리초가 경과했는지 나타내는 값
- 데이터센터 ID: 5비트를 할당, 데이터센터당 2^5=32개 서버 사용 가능
- 일련번호: 12비트 할당, 각 서버에서는 ID를 생성할 때마다 이 일련번호를 1만큼 증가 -> 이 값은 1밀리초가 경과할 때마다 0으로 초기화됨
3단계 상세 설계
트위터 스노플레이크 접근법을 사용하여 보다 상세한 설계를 진행해 보자

- 데이터센터ID, 서버ID: 시스템이 시작될 때 결정, 일반적으로 시스템 운영 중에 바뀌지 않음 -> 잘못 변경하게 되면 ID 충돌이 발생할 수 있으므로 그런 작업을 해야 할 땐 신중해야 함
- 타임스탬프, 일련번호: ID 생성기가 돌고 있는 중 만들어지는 값
타임스탬프
- ID 구조에서 가장 중요한 41비트를 차지하고 있음
- 타임스탬프는 시간의 흐름에 따라 점점 큰 값을 갖게 되므로 결국 ID는 시간순 정렬이 가능해질 것
- ID 구조를 따르는 값의 이진 표현 형태로부터 UTC 시각을 추출하는 예시 (역으로 적용하면 어떤 UTC 시각도 상술한 타임스탬프 값으로 변환할 수 있음)

- 41비트로 표현할 수 있는 타임스탬프의 최댓값은 대략 69년에 해당 -> 이 ID 생성기는 69만 정상 동작하고, 기원 시각을 현재에 가깝게 맞춰 오버플로 발생 시점을 늦춰 놓은 것
- 69년이 지나면 기원 시각을 바꾸거나 ID 체계를 다른 것으로 이전해야 함
일련번호
- 12비트를 가지므로 2^12=4096개의 값을 가질 수 있음
- 어떤 서버가 같은 밀리초 동안 하나 이상의 ID를 만들어 낸 경우에만 0보다 큰 값을 갖게 됨
4단계
스노플레이크를 선택 -> 모든 요구사항을 만족하면서 분산 환경에서 규모 확장이 가능하기 때문에
추가 논의 사항
- 시계 동기화 => 보편적으로 NTP(Network Time Protocol) 사용
- 각 절(section) 길이 최적화 => 동시성이 낮고 수명이 긴 애플리케이션이라면 일련번호 절의 길이를 줄이고 타임스팸프 절의 길이를 늘리는 게 효과적일 수 있음
- 고가용성 => ID 생성기는 필수 불가결 컴포넌트이므로 아주 높은 고가용성 제공 필요