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

중앙에서 발급하기

가장 단순하고 가장 확실한데 왕복이 든다

유일성을 구조로 보장하는 가장 단순한 방법은 한 곳에서만 발급하는 것입니다. 이 방법부터 재 보고 왜 탈락하는지 봅니다.

한 곳에서 번호를 센다

중앙 발급기에서 하나씩 받는 방식과 구간을 미리 받아 두는 방식의 비교 하나씩 받으면 발급기 중앙 서버 발급마다 왕복 한 번 예산 1ms 를 그대로 쓴다 그리고 이 서버가 멈추면 전부 멈춘다 구간을 미리 받으면 발급기 1000개를 한 번에 받아 로컬에서 나눠 쓴다 왕복이 사라진다 1000번에 한 번만 재시작하면 남은 구간이 버려진다. 번호에 빈틈이 생긴다 노드마다 다른 구간을 쓰므로 시간순 정렬도 깨진다

저장소의 증가하는 번호나 전용 서버 하나가 번호를 셉니다. 중복이 원리적으로 불가능하고, 요구사항에서 뺐던 빈틈 없는 연속 번호까지 얻습니다.

문제는 둘입니다.

문제내용
왕복발급마다 물어봐야 한다. 예산 1ms 를 그대로 쓴다
단일 장애점그 곳이 멈추면 모든 서비스의 쓰기가 멈춘다

발급량 초당 10만 도 그 한 곳의 처리량 상한에 걸립니다.

구간을 미리 받아 두면

한 번에 1,000개를 받아 로컬에서 나눠 쓰면 왕복이 1,000번에 한 번으로 줄어듭니다. 이 방법은 실무에서 널리 쓰입니다.

그런데 대가가 둘 생깁니다.

재시작하면 남은 구간이 버려진다. 번호에 빈틈이 생긴다
노드마다 다른 구간을 쓰므로 시간순 정렬이 깨진다

정렬이 깨지는 것이 치명적입니다. 앞 단계에서 정렬을 저장 비용 요구사항으로 정했는데, 구간 임대는 그것을 지키지 못합니다. 노드 A가 11000을, 노드 B가 10012000을 받으면 시간 순서와 번호 순서가 무관해집니다.

노드마다 증가폭을 다르게 주는 방법

노드 수만큼 증가폭을 두고 시작점을 다르게 주는 방법도 있습니다. 노드 셋이면 1, 4, 7 과 2, 5, 8 과 3, 6, 9 를 각각 씁니다.

이 방법은 왕복이 없지만 노드 수가 규칙에 들어 있습니다. 노드를 추가하려면 증가폭을 바꿔야 하고, 그러면 이미 발급한 번호와 충돌할 수 있습니다. 안정 해시에서 본 문제와 같은 모양입니다.

그래도 이 방법이 맞는 경우

중앙 발급기를 나쁜 방법으로 외우면 안 됩니다.

상황중앙 발급기가
발급량이 초당 수천 이하충분하다. 더 정교한 방법은 과설계다
빈틈 없는 연속 번호가 필요유일한 방법이다. 청구서 번호나 영수증 번호
이미 저장소를 쓰고 있다새 부품 없이 된다

요구사항에 연속 번호가 있으면 다른 선택지가 없습니다. 이 설계는 그것을 뺐기 때문에 다른 길이 열렸습니다.

이 요구사항에서는 탈락한다

지연 1ms 와 정렬 요구를 함께 지킬 수 없습니다. 왕복을 없애려면 구간 임대가 필요하고, 구간 임대는 정렬을 깨뜨립니다.

그래서 다음 단계에서 아무에게도 묻지 않고 만드는 방법을 봅니다.

면접에서 이렇게 나옵니다

Q.중앙 발급기 방식의 장점은 무엇인가요

중복이 원리적으로 불가능하고, 빈틈 없는 연속 번호까지 얻습니다.

한 곳에서만 번호를 세므로 유일성을 확률이 아니라 구조로 보장합니다. 그리고 구현이 가장 단순합니다. 이미 저장소를 쓰고 있다면 새 부품 없이 됩니다.

상황중앙 발급기가
발급량 초당 수천 이하충분하다
연속 번호가 필요유일한 방법이다

청구서 번호나 영수증 번호처럼 빈틈이 문제가 되는 곳에서는 이 방법밖에 없습니다.

흔한 실수: 중앙 발급기를 무조건 나쁜 방법으로 외우는 것. 규모가 작으면 가장 좋은 선택이고, 요구사항에 연속 번호가 있으면 다른 선택지가 없습니다. 무엇을 요구하는지가 방식을 정합니다.

Q.이 요구사항에서 중앙 발급기가 왜 탈락하나요

지연 1ms 와 정렬 요구를 함께 지킬 수 없습니다.

문제내용
왕복발급마다 물어봐야 한다. 예산을 그대로 쓴다
단일 장애점그곳이 멈추면 모든 쓰기가 멈춘다
처리량발급량 초당 10만 이 그 한 곳의 상한에 걸린다

왕복을 없애려면 구간을 미리 받아야 하는데, 구간 임대는 노드마다 다른 구간을 쓰므로 시간순 정렬이 깨집니다.

흔한 실수: 단일 장애점만 이유로 대는 것. 이중화로 완화할 수 있으므로 그것만으로는 근거가 약합니다. 왕복과 정렬을 함께 지킬 수 없다는 것이 결정적인 이유입니다.

Q.구간을 미리 받아 두는 방식의 대가는 무엇인가요

빈틈이 생기고 시간순 정렬이 깨집니다.

재시작하면 남은 구간이 버려진다. 번호에 빈틈이 생긴다
노드 A 가 1~1000, 노드 B 가 1001~2000 을 쓴다
시간 순서와 번호 순서가 무관해진다

빈틈은 요구사항에서 이미 허용했으므로 문제가 아닙니다. 정렬이 깨지는 것이 치명적입니다. 앞 단계에서 정렬을 저장 비용 요구사항으로 정했기 때문입니다.

구간 크기를 줄이면 정렬은 나아지지만 왕복이 늘어납니다. 두 요구가 서로를 밀어냅니다.

흔한 실수: 구간을 크게 잡아 왕복을 줄이는 것만 보는 것. 구간이 클수록 노드 사이 번호 격차도 커져 정렬이 더 깨지고, 재시작 시 버려지는 번호도 많아집니다.

Q.노드마다 증가폭을 다르게 주는 방식은 어떤가요

왕복은 없지만 노드 수가 규칙에 들어 있습니다.

노드 셋이면 각각 1, 4, 7 과 2, 5, 8 과 3, 6, 9 를 씁니다. 서로 겹치지 않으므로 조율 없이 유일합니다.

문제는 노드를 추가할 때입니다. 증가폭을 바꿔야 하고, 그러면 이미 발급한 번호와 충돌할 수 있습니다. 안정 해시에서 본 문제와 같은 모양입니다.

노드 수가 규칙의 일부가 되면 노드 수를 바꾸기 어렵다

그리고 시간순 정렬도 지켜지지 않습니다. 노드마다 다른 속도로 번호를 소비하기 때문입니다.

흔한 실수: 노드를 넉넉하게 미리 정해 두면 된다고 답하는 것. 그러면 쓰지 않는 노드 몫의 번호가 계속 비어 있고, 나중에 그 수를 넘길 때 같은 문제가 그대로 돌아옵니다.

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

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

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