Foundry
분산 ID 생성기 설계
중급
핵심

무작위로 만들기

조율이 사라지고 크기와 정렬을 낸다

중앙 발급기가 탈락한 이유는 왕복이었습니다. 왕복을 없애는 가장 단순한 방법은 아무에게도 묻지 않고 아주 큰 무작위 값을 뽑는 것입니다.

충돌하지 않는 이유

값의 범위가 충분히 크면 두 번 같은 값이 나올 확률이 무시할 만큼 작아집니다. 128비트 규모에서는 하루 86억 건을 수십 년 뽑아도 충돌 확률이 사실상 0입니다.

이것은 확률에 기대는 보장입니다. 구조로 막는 것과 다르지만, 확률이 충분히 작으면 실무에서는 같은 값으로 취급합니다. 무작위성이 나쁜 생성기를 쓰면 이 전제가 깨지므로 그 부분만 주의합니다.

얻는 것과 잃는 것

무작위 방식은 조율이 없는 대신 크기가 두 배이고 정렬이 없다 인덱스에 담기는 크기 64비트 86억 건에 약 69GB 128비트 두 배 인덱스가 메모리에 들어가는지가 조회 속도를 정한다 얻는 것: 아무에게도 묻지 않는다. 노드 수 제한이 없다 잃는 것: 크기가 두 배이고 시간순 정렬이 없다 정렬이 필요 없는 곳이라면 이 방법이 가장 단순하다
항목내용
얻는 것왕복 0. 조율 0. 노드 수 제한 없음. 구현이 가장 단순
잃는 것크기가 두 배. 시간순 정렬이 없음

크기가 요구사항 64비트 를 어깁니다. 그리고 정렬이 없으므로 앞 단계에서 본 삽입 비용 문제가 그대로 생깁니다.

두 대가는 서로 다른 무게다

크기는 저장과 인덱스 메모리를 두 배로 만듭니다. 아프지만 계산 가능한 비용입니다.

정렬이 없는 것이 더 무겁습니다. 삽입 위치가 흩어지면 쓰기가 느려지고, 그 영향은 데이터가 커질수록 나빠집니다. 인덱스가 메모리에 다 들어가는 규모에서는 차이가 작지만, 넘어가는 순간 급격히 벌어집니다.

앞부분에 시각을 넣는 변형

무작위 값의 앞부분을 시각으로 바꾸면 정렬을 되찾을 수 있습니다. 뒷부분은 그대로 무작위로 둡니다.

앞: 시각. 시간순으로 커진다
뒤: 무작위. 같은 순간의 충돌을 확률로 막는다

이 방식은 정렬과 조율 없음을 함께 얻습니다. 크기는 여전히 크지만 요구사항이 크기를 강하게 제한하지 않는다면 좋은 선택입니다. 실제로 많이 쓰입니다.

이 요구사항에서는 크기가 발목을 잡는다

64비트 정수 요구가 남아 있습니다. 무작위 부분을 줄여 64비트에 맞추면 충돌 확률이 급격히 올라갑니다. 초당 10만 규모에서 확률에 기대기에는 여유가 부족합니다.

그래서 다음 단계에서 무작위를 쓰지 않고 유일성을 구조로 얻는 방법을 봅니다. 같은 순간에 같은 값이 나올 수 없도록 칸을 나눠 쓰는 방식입니다.

면접에서 이렇게 나옵니다

Q.무작위 식별자가 충돌하지 않는 이유는 무엇인가요

값의 범위가 충분히 크면 같은 값이 두 번 나올 확률이 무시할 만큼 작아집니다.

128비트 규모에서는 하루 86억 건을 수십 년 뽑아도 충돌 확률이 사실상 0입니다.

이것은 확률에 기대는 보장입니다. 구조로 막는 것과 성질이 다릅니다. 실무에서는 확률이 충분히 작으면 같은 값으로 취급하지만, 전제가 하나 있습니다.

무작위성이 나쁜 생성기를 쓰면 이 전제가 깨진다

흔한 실수: 무작위 값의 일부만 잘라 짧게 쓰는 것. 예를 들어 128비트 중 앞 64비트만 쓰면 충돌 확률이 계산과 전혀 다른 값이 됩니다. 확률에 기대는 방식에서 길이를 줄이는 것은 보장을 버리는 것입니다.

Q.무작위 방식이 이 요구사항에서 왜 탈락하나요

크기 64비트 와 시간순 정렬을 둘 다 못 지킵니다.

항목내용
얻는 것왕복 0. 조율 0. 노드 수 제한 없음
잃는 것크기가 두 배. 정렬 없음

크기를 맞추려고 무작위 부분을 줄이면 초당 10만 규모에서 충돌 확률이 급격히 올라갑니다. 확률에 기대기에 여유가 부족합니다.

정렬이 없는 것은 앞 단계에서 본 삽입 비용 문제를 그대로 만듭니다.

흔한 실수: 두 대가를 같은 무게로 보는 것. 크기는 계산 가능한 비용이지만 정렬 없음은 데이터가 커질수록 나빠집니다. 인덱스가 메모리를 넘어가는 순간 차이가 급격히 벌어집니다.

Q.무작위 방식으로 정렬을 얻을 수 있나요

네. 앞부분을 시각으로 바꾸면 됩니다.

앞: 시각. 시간순으로 커진다
뒤: 무작위. 같은 순간의 충돌을 확률로 막는다

정렬과 조율 없음을 함께 얻습니다. 크기는 여전히 크지만 요구사항이 크기를 강하게 제한하지 않는다면 좋은 선택이고 실제로 많이 쓰입니다.

이 변형이 다음 단계의 방식과 닮았습니다. 차이는 뒷부분을 무작위로 두는지, 노드 번호와 순번으로 나눠 쓰는지입니다.

흔한 실수: 시각을 앞에 넣는 것만으로 크기 문제가 해결됐다고 보는 것. 정렬은 되찾지만 길이는 그대로입니다. 두 요구를 각각 확인해야 합니다.

Q.무작위 방식이 가장 좋은 선택인 경우는 언제인가요

정렬이 필요 없고 조율을 피하고 싶을 때입니다.

상황무작위 방식이
클라이언트가 ID를 만들어야 한다유일한 방법에 가깝다
노드 수를 미리 알 수 없다제한이 없어 편하다
정렬이 필요 없다대가가 크기뿐이다

특히 클라이언트에서 만드는 경우가 중요합니다. 오프라인에서 작성한 데이터에 ID를 붙여야 한다면 서버에 물어볼 수 없고, 노드 번호를 줄 방법도 없습니다.

흔한 실수: ID 방식을 시스템 전체에 하나로 통일하려는 것. 클라이언트가 만드는 임시 ID와 서버가 만드는 정본 ID는 다른 요구를 받으므로 다른 방식이어도 됩니다. 통일이 목적이 되면 어느 쪽 요구도 못 지킵니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

분산 ID 생성기 설계 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.