분산 시스템에서 auto_increment 방식이 어려운 이유

단일 시스템에서는 auto_increment로 충돌 없이 ID를 생성할 수 있지만, 분산 시스템에서는 여러 노드가 동시에 ID를 생성하기 때문에 각 노드 간의 증분 값을 동기화하지 않으면 ID 충돌이 발생할 수 있습니다. 이로 인해 성능 저하나 DB Lock 경쟁이 발생하며 확장성에도 한계가 있습니다.

꼬리질문: auto_increment 방식을 분산 환경에서 어떻게 개선할 수 있을까

  • 다중 마스터 복제
  • 티켓 서버 방식이 가능

하지만 확장성 유연성에는 한계가 있어서 고성능 시스템에서는 다른 전략이 필요할 수도 있습니다.

왜 UUID를 사용하지 않고 스노우플레이크 방식을 본인 플젝에서 사용했나

UUID는 유일성이 뛰어나지만, 길이가 길고 무작위 값이기 때문에 DB 인덱스 성능 저하, 정렬 불가, 사람이 읽기 어려움 등의 단점이 있습니다. 제 프로젝트에서는 시간순 정렬이 가능한 고성능 ID가 필요했고, 스노우플레이크는 64비트 정수 기반이라 정렬이 가능하고, 분산 노드에서도 고유 ID 생성이 가능해 적합하다고 판단했습니다.

꼬리 질문: 그렇다면 UUID를 쓰는 게 더 유리한 상황은 언제인가

정렬될 필요가 없고, 충돌을 최대한 피하고 싶을 경우 UUID가 적합 또한 서버 간 연결 없이 독립적으로 ID 생설할 경우 유용합니다.

스노우플레이크 방식에서 시계가 역행한다면 어떻게 되나

스노우플레이크는 타임스탬프를 ID의 상위 비트에 포함하기 때문에, 시계가 뒤로 가면 이전보다 작은 ID가 생성될 수 있어 충돌 위험이 있습니다. 이 경우 대부분의 구현에서는 에러를 발생시키거나, 시계가 복구될 때까지 대기합니다. 이 문제를 방지하기 위해 모든 서버는 NTP로 정확히 동기화해야 합니다.

꼬리 질문: 만약 서버 시간이 미묘하게 뒤로 갔다면 어떻게 실시간 대응할 것인가

저는 시계가 역행했을 때 경고 로그를 출력하고, 밀리초 단위 offset을 적용하거나, 시퀀스 최대값까지 강제로 소모해서 충돌 없는 ID를 생성하도록 우회 전략도 적용했습니다. 하지만 근본적으로 로그 모니터링과 정밀한 시계 동기화가 필요합니다.

스노우플레이크 방식에서 1ms에 5000개 이상의 요청이 들어온다면 어떻게 대응하시겠나

스노우플레이크는 1ms당 시퀀스 번호 12비트 → 최대 4096개 ID 생성이 가능합니다.

다음 밀리초까지 대기를 시키거나, 이런 요청이 자주오거나 대기를 허용하지 않는 상황이라면 시퀀스 번호를 조정해 동시성을 높이는 방법이 있겠습니다.

꼬리질문: 시퀀스 비트를 늘리는 게 왜 위험할 수 있나요?

시퀀스 비트를 늘린다는건 시퀀스 번호를 줄이거나 서버, 데이터센터 ID 비트를 줄여야 된다는 것입니다.

따라서 각 여파를 잘 고려해서 조정해야합니다.

스노우플레이크 생성기 자체가 다운된다면?

ID 생성기는 중추적인 역할을 합니다. 따라서 고가용성 설계가 필수적입니다.

ID 생성기를 여러개 분산 배치하고, 생성기 서버 ID를 Zookeeper/Redis를 통해 중복 없이 Node ID를 할당해주는 중앙 조정자를 두는 것입니다.

+ Recent posts