개발 일지/대규모 시스템 설계

[대규모 시스템 설계] 3. 분산 시스템을 위한 유일 ID 생성기 설계

배발자 2023. 7. 23.
반응형

프로젝트를 진행해봤다면 DB를 하나 정도는 활용해봤을 것이다. 하지만, 같은 용도로 활용하는 DB 서버를 분산시켜서 트래픽을 분산시키는 작업을 진행하는 것은 실무가 아닌 이상 토이 프로젝트에 적용하는 것은 상당히 힘들 것이라고 생각한다. 'auto_increment' 속성이 설정된 관계형 데이터베이스를 통해 기본 키를 쓴다면 이것은 단일 서버에 한해서다. 분산 환경에서 이 접근법은 통하지 않는다. 

 

분산 환경에서 여러 DB를 구축을 한다면, 어느 DB로 해당 PK 값으로 데이터 정보를 불러올 것인가가 문제다. 기본적으로 데이터베이스 하나를 이용한다면 PK 값으로 해당 데이터베이스에서 Select문을 날리면 된다. 그러나 데이터베이스 서버가 여러개라면 해당 PK값을 가진 데이터가 어느 데이터베이스에 존재하는지 모른다는 것이다. 이를 해결하기 위해 유일성이 보장되는 ID를 어떻게 구축하는 것인지가 오늘의 주제이다. 

 

먼저 유일성이 보장되는 ID를 만들기 위한 방법이 무엇이 있는지 살펴보자. 하나씩 읽다보면 자연스럽게 이해가 될거다. 분산 시스템에서 유일성이 보장되는 ID를 만드는 방법은 다음과 같다. 

 

1. 다중 마스터 복제 
2. UUID
3. 티켓 서버
4. 트위터 스노플레이크 접근법 

 

다중 마스터 복제 

 

이 접근법은 데이터 베이스의 auto_increment 기능을 활용하는 것이다.

이때는 ID의 값에 1만큼 증가하는 것이 아니라 k만큼 증가하는 것이다. 예를 들면 서버가 2개라고 가정하면 A 서버에서는 1, 3, 5 씩 더해지고 B 서버에서는 2, 4, 6 씩 더해질 것이다. 이렇게 된다면 유일성이 보장이 된다는 것이다. 하지만 이 기술은 문제점이 존재한다. 

 

- 여러 데이터 센터에 걸쳐 규모를 늘리기가 어렵다. 

- 유일성은 보장되지만 그 값이 시간 흐름에 맞추어 커지도록 보장할 수는 없다. 

- 서버를 추가하거나 삭제할 때도 잘 동작하도록 만들기 어렵다. 

 

UUID

UUID는 컴퓨터 시스템에 저장되는 정보를 유일하게 식별하기 위한 128비트짜리 수다. UUID 값은 중복될 가능성이 거의

없다고 보면된다.

 

UUID 값은 09c93e21-40b3-428d-bf8b-c06e1030bfb2와 같은 형태를 띠며, 서버 간 조율 없이 독립적으로 생성 가능하다. 

 

 

위의 그림처럼 웹 서버는 독립적으로 ID 생성기를 사용해서 ID를 생성한다.  

 

장점으론 서버 사이의 조율이 필요 없으므로 동기화 이슈가 없는 매우 단순한 방식이다. 또한, 각 서버가 ID를 생성하니 규모 확장도 쉽다. 하지만 ID를 시간순으로 정렬할 수 없고, 128비트나 사용된다는 점. 또한, ID에 숫자가 아닌 값이 포함될 수 있다. 

 

티켓서버

 

auto_increment 기능을 갖춘 데이터베이스 서버, 즉 티켓 서버를 중앙 집중형으로 하나만 사용하는 것이다. 장점은 유일성이 보장되는 오직 숫자로만 구성된 ID를 쉽게 만들 수 있으며, 구현하기 쉽다.  단점은 티켓 서버가 SPOF가 된다. 즉, 이 서버가 터지면 모든 시스템에 영향이 가므로 이 이슈를 피하기위해 티켓 서버를 여러대 준비해야한다. 그렇게 하면 데이터 동기화 문제도 발생할 것이다. 

 

트위터 스노플레이크 접근법

트위터는 '스노플레이크'라고 부르는 독창적인 ID 생성 기법을 사용한다. 

 

 

사인(sign) 비트 1비트, 음수와 양수 구별
타임 스탬프 41비트, 기원 시각 이후로 몇밀리초 경과했는지
데이터센터 5비트, 32개 데이터 센터 지원
서버 ID 5비트 할당, 데이터 센터당 32개 서버 사용 가능 
일련번호 12비트 할당, 각 서버에서는 ID를 생성할 때마다 이 일련 번호를 1만큼 증가시킨다. 이 값은 1밀리초가 경과할 때마다 0으로 초기화된다. 

 

기본적으로 데이터 센터 ID와 서버 ID는 시스템이 시작할 때 결정되고 일반적으로는 시스템 운영 중에는 바뀌지 않는다. 타임 스탬프와 일련번호는 ID 생성기가 돌고 있는 중에 만들어지는 값이다. 

 

1. 타임 스탬프 

타임 스탬프는 시간의 흐름에 따라 점점 큰 값을 갖게 된다. 

즉, 사용자가 회원가입을 할 경우 기원 시간 이후로 몇 밀리초가 경과됐는지를 확인하고 생성되기 때문에 시간순으로 정렬이 가능하다는 것이다. 

41비트로 표현할 수 있는 타임스탬프의 최댓값은 2^41-1 = 2199023255551밀리초이다. 이 값은 대략 69년에 해당한다. 즉, 이 ID 생성기는 69년동안만 정상 동작되며 69년이 지나면 기원 시각을 바꾸거나 ID 체계를 다른 것으로 이전하여야한다. 

 

2. 일련번호

일련번호는 12비트이므로, 2^12 = 4096개의 값을 가질 수 있다. 어떤 서버가 같은 밀리초 동안 하나 이상의 ID를 만들어 낸 경우에만 0보다 큰 값을 갖게 된다. 즉, 밀리초동안 10명의 회원가입이 동시에 일어난다면 0, 1, 2, 3.... 으로 생성될 것이며, 해당 시간이 지나면 다시 0으로 초기화된다. 그러면 중복된 값이 생기지 않는가? 

위의 타임 스탬프가 밀리초씩 갱신되므로 중복되지 않을 것이다. 

 


 

이번장에서는 조금 간단하게 유일성이 보장되는 ID 생성기 구현 전략에 대해서 배워보았다. 

다음 포스팅에서는 안정 해시 설계를 주제로 다뤄볼 예정이다. 

 

 

 

 

반응형

댓글