Foundry
분산 ID 생성기 설계
심화
핵심

ID를 외부에 보일 때

순서가 드러나면 사업 지표가 드러난다

마지막으로 이 ID를 외부에 보여도 되는지를 봅니다. 지금까지의 판단이 모두 내부 성능과 유일성에 관한 것이었고, 이 절은 성질이 다릅니다.

순차 ID는 발급량을 드러낸다

두 시점의 ID 를 비교하면 그 사이 발급량을 알 수 있다 주문 하나를 넣고 ID 를 받는다 1월 1일: ID 앞자리 A 2월 1일: ID 앞자리 B 두 값을 빼면 한 달 주문 수가 나온다 내부용 ID 와 외부에 보여줄 식별자를 따로 둔다 외부 식별자는 순서가 드러나지 않는 값으로 만든다 다만 접근 제어를 추측 난이도에 기대지 않는다 권한 검사가 본질이고 식별자 모양은 보조다

주소나 화면에 ID가 그대로 보이면 누구나 두 시점의 값을 비교할 수 있습니다. 그 차이가 그 사이 발급량입니다.

주문 번호라면 매출 규모가, 가입 번호라면 사용자 증가 속도가 드러납니다. 경쟁사가 계정 하나로 알아낼 수 있는 정보입니다.

시각 칸이 앞에 있으므로 발급 시각도 드러납니다. 대개 무해하지만, 노드 번호 칸에서 발급기 대수가 드러나는 것도 함께 알아 둡니다.

다음 값을 추측할 수 있다

순차적이면 다음 값도 예상할 수 있습니다. 그것으로 남의 데이터에 접근하려는 시도가 가능해집니다.

여기서 판단을 정확히 해야 합니다. 이 문제의 본질은 ID가 추측 가능한 것이 아니라 권한 검사가 없는 것입니다.

대응성질
추측하기 어려운 식별자로 바꾼다시도를 줄인다. 보조 수단이다
요청마다 권한을 검사한다근본 대응이다

식별자를 어렵게 만드는 것만으로 막으려 하면, 한 번 유출된 주소가 곧 접근 권한이 됩니다.

내부용과 외부용을 나눈다

정렬 요구는 내부 저장소를 위한 것이었습니다. 외부에는 그 성질이 필요하지 않습니다.

내부: 시간순으로 커지는 64비트. 인덱스에 좋다
외부: 순서가 드러나지 않는 별도 식별자

두 값을 함께 저장하고 외부 통신에서는 뒤쪽만 씁니다. 비용은 컬럼 하나와 그 인덱스이고, 얻는 것은 사업 지표를 감추는 것입니다.

모든 데이터에 필요하지는 않습니다. 주문이나 가입처럼 수량이 의미를 갖는 것에만 두면 됩니다.

이 설계가 하지 않기로 한 것

후보결정과 근거
중앙 발급기하지 않는다. 왕복이 예산 1ms 를 넘고 정렬도 못 지킨다
무작위 식별자하지 않는다. 크기 64비트 요구를 어긴다
빈틈 없는 연속 번호하지 않는다. 조율이 필수가 된다
밀리초 안 순서 보장하지 않는다. 조율을 없애려고 포기했다
시계 되돌림 때 그냥 발급하지 않는다. 회복 불가능한 실패를 만든다

각 결정에 숫자나 원칙이 붙어 있는 것이 중요합니다. 요구사항이 달라지면 그 근거로 다시 계산할 수 있습니다.

면접에서 이렇게 나옵니다

Q.순차 ID를 외부에 보이면 무엇이 문제인가요

두 시점의 값을 비교하면 그 사이 발급량이 드러납니다.

주문 번호라면 매출 규모가, 가입 번호라면 사용자 증가 속도가 드러납니다. 계정 하나로 알아낼 수 있는 정보입니다.

시각 칸이 앞에 있으므로 발급 시각도 드러나고, 노드 번호 칸에서 발급기 대수도 드러납니다.

1월에 받은 ID 와 2월에 받은 ID 를 뺀다
그 값이 한 달 발급량이다

흔한 실수: 이것을 보안 문제로만 보는 것. 접근 권한과 무관하게 사업 지표가 새는 문제이고, 그래서 대응도 권한 검사가 아니라 식별자 분리입니다.

Q.ID를 추측해 남의 데이터에 접근하는 것은 어떻게 막나요

권한 검사로 막습니다. 식별자를 어렵게 만드는 것은 보조 수단입니다.

대응성질
추측하기 어려운 식별자시도를 줄인다. 보조다
요청마다 권한 검사근본 대응이다

식별자를 어렵게 만드는 것만으로 막으려 하면 한 번 유출된 주소가 곧 접근 권한이 됩니다. 주소는 로그와 공유 링크와 브라우저 기록에 남습니다.

흔한 실수: 무작위 식별자로 바꾸고 권한 검사를 미루는 것. 이 문제의 본질은 ID의 모양이 아니라 검사가 없는 것입니다. 순서를 감추는 것은 사업 지표를 감추는 목적으로만 값이 있습니다.

Q.내부용과 외부용 식별자를 나누면 어떤 비용이 드나요

컬럼 하나와 그 인덱스입니다.

내부: 시간순으로 커지는 64비트. 인덱스에 좋다
외부: 순서가 드러나지 않는 별도 식별자

외부 통신에서는 뒤쪽만 쓰고, 조회할 때 그 값으로 찾아야 하므로 인덱스가 필요합니다. 정렬이 없는 값이라 그 인덱스의 삽입 비용은 앞에서 본 무작위 삽입 문제를 그대로 갖습니다.

그래서 모든 데이터에 두지 않습니다. 주문이나 가입처럼 수량이 의미를 갖는 것에만 둡니다.

흔한 실수: 외부 식별자를 기본 키로 바꾸는 것. 그러면 정렬을 위해 애쓴 것이 전부 사라집니다. 정본은 내부 ID 로 두고 외부 식별자는 찾아가는 값으로만 씁니다.

Q.이 설계에서 하지 않기로 한 것들을 말해 주세요

요구사항의 숫자와 원칙으로 각각 잘랐습니다.

후보결정과 근거
중앙 발급기왕복이 1ms 를 넘고 정렬도 못 지킨다
무작위 식별자크기 64비트 요구를 어긴다
빈틈 없는 연속 번호조율이 필수가 된다
밀리초 안 순서 보장조율을 없애려고 포기했다
시계 되돌림 때 그냥 발급회복 불가능한 실패를 만든다

마지막 줄이 이 설계의 성격을 잘 보여줍니다. 회복 가능한 실패를 고르는 것이 여러 판단에서 반복된 기준이었습니다.

흔한 실수: 기법을 나열하고 하나를 고르는 것으로 끝내는 것. 고르지 않은 것들에 각각 다른 이유가 붙어야 합니다. 이유가 요구사항의 숫자에서 나오면, 요구사항이 달라질 때 결정을 다시 계산할 수 있습니다.

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

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

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