데브콘 활동 후기

[Review] 시스템 디자인 스터디 2주차 후기

dev-jonghoonpark 2025. 9. 22. 22:40

안녕하세요!

K-DEVCON (이하 “데브콘”) 그로스 매니저 박종훈입니다🙋🏻‍♂️

 

이 글에서는 9월 18일(목)에 진행된 스터디에서 나눈 이야기를 정리합니다.

이번 시간에는 “분산 시스템을 위한 유일 ID 생성기 설계”“URL 단축기 설계” 이야기를 나눴습니다.

 

 

[1] 유일 ID 생성기

먼저는 각자 일반적으로 어떻게 ID를 생성하고 있는가에 대한 이야기를 나눴습니다.

Auto Increment를 사용하고 있는 경우도 있었고, UUID를 사용하는 경우도 있었고, 업무적인 컬럼을 PK로 사용하는 경우도 있었습니다. 

 

어떻게 ID를 생성하는 것이 좋을지는 상황에 따라서 달라집니다.

일반적인 상황에서는 Auto Increment 가 대부분의 경우 가장 빠른 해결책이 될 수 있습니다.

하지만 분산 환경일 경우에는 어떨까요?

 

책에서는 분산 환경에서 쓸 수 있는 방법으로 아래 내용들을 설명합니다.

  • 다중 마스터 복제
  • UUID
  • 티켓 서버
  • 트위터 스노우플레이크 ID

 

<1> Flickr 의 사례 알아보기 (다중 마스터 복제, 티켓 서버)

책에서 나온 다중 마스터 복제 방식과, 티켓 서버는 참고문헌에 나와있는 Flickr(Ticket Servers: Distributed Unique Primary Keys on the Cheap) 의 사례를 참고하여 적은것으로 보입니다. 재밌는 활용 사례였습니다. 내용을 간단하게 정리해보면 다음과 같습니다.

 

Flickr는 세팅된 MySQL 환경에서 전역적으로 고유한 기본 키를 제공하기 위해 티켓 서버를 운영하였다고 합니다. 중앙화한 전용 데이터베이스에서 Auto Increment 를 활용해 순차적이고 고유한 32·64비트 ID를 발급하였습니다. 이 때 단일 장애 지점을 피하기 위해 두 개의 서버를 운영하며, 각각 홀수/짝수 ID를 생성하도록 설정하여 고가용성을 확보하였습니다.

 

이러한 운영 환경에서 양 쪽 서버의 데이터가 몇십만 개 정도 차이가 나게 되었다고 하는데, 이게 운영에 있어서 크게 문제는 없었다는 부분도 실제로 운영해 보았을 때만 알 수 있는 재밌는 부분인 것 같습니다.

 

<2> UUID

UUID는 유일성이 보장되는 ID를 간단하게 만들 수 있는 방법 중 하나입니다.

하지만 “UUID는 성능이 좋지 않다.” 라는 인식이 있습니다. 왜 그런 인식이 있을까요?

 

이는 UUID를 사용할 경우 ID가 순차적으로 증가하지 않기 때문입니다.
이로인해 데이터베이스에서 PK(Primary Key)로 UUID를 사용하면 인덱스가 비효율적으로 구성되고, 결국 성능이 저하될 수 있습니다.


진짜일까요?

 

현재 UUID를 쓰고 있다면, 어떤 버전을 사용하고 있나요? 잘 모르시겠다면 이번 기회에 한 번 확인해보시면 좋을 것 같습니다. 각 버전에 따라 특성이 다르기 때문입니다.

버전 특성 인덱스 효율
v1 시간 + MAC 기반, 순차적이지 않음 낮음
v4 랜덤 기반, 가장 널리 사용됨 낮음
v6 v1 개선, 시간 순서 보장 높음
v7 Unix time 기반, 단순 구조 높음
(번외) ULID 시간 + 랜덤, Base32 인코딩 높음

 

기존에 많이 사용되었던 UUID v1, UUID v4 의 경우 ID가 순차적으로 오르지 않습니다. 따라서 이 경우에는 PK로 사용되었을 경우, 좋은 인덱스 성능이 나오지 못하게 됩니다.

 

이를 어떻게 해결할 수 있을까요?

  • UUID v1에서 비트 순서를 바꾸어 순차적으로 만드는 방법도 있습니다.
  • 비교적 최근에 나온 UUID v6, UUID v7 의 경우 순차적으로 오르지 않는 문제를 보완하였기 때문에, 이를 활용하는 것도 방법입니다.
  • ULID 도 최근 언급되는 방식 중 하나입니다.

그러면 UUID v4를 사용하는 것은 무조건 나쁜 것일까요? 그렇지는 않습니다. 강력한 랜덤성을 가지고 있기 때문에, 악의적인 접근을 방어하는데는 좋은 방식입니다. (모든 것은 Trade-off가 있습니다)

 

UUID의 장점을 가져가기 위해서 하이브리드 방식으로 사용하는 사례도 있습니다.

내부적으로는 순차적으로 오르는 ID를, 외부에 공개하는 용도로는 랜덤 ID를 사용하는 방식입니다.

 

추가적으로 UUID는 16바이트를 차지하므로, 8바이트 정수형 PK와 비교한다면 인덱스 비용이 더 들기도 합니다. 하지만 이는 데이터의 양이 매우 많을 경우에는 문제가 되겠지만, 대부분의 경우에는 큰 문제가 되지 않을 것입니다.

 

<3> Snowflake ID

이번 장의 핵심 주제입니다.

 

Snowflake ID(스노우플레이크 ID)는 트위터에서 공개한 ID 생성 기법입니다.

분산 환경에서 효율적으로 데이터를 저장하기 위한 구조를 가지고 있습니다. 여러 서버에서 동시에 ID를 생성할 수 있으며, 시간 기반으로 정렬 가능한 것이 특징입니다.

 

 

설명만 들어보면 좋아 보이지만, 실제 분산 환경에서 운영 시에는 주의가 필요합니다.

실제로 Snowflake ID를 사용하여 서비스를 운영한다면 어떨까요? 아래와 같은 부분은 주의가 필요할 것으로 생각됩니다.

  • 데이터 센터 ID와 서버 ID를 서버 운영시 주입해줘야 하므로, 이 부분은 운영시에 주의가 필요할 것입니다.
  • Timestamp가 뒤로가지 않아야 합니다. 이는 ID 충돌을 발생시킬 수 있습니다.
  • 한 서버 내에서의 이벤트 순서는 알 수 있지만, 글로벌한 순서는 알 수 없습니다.

 

실제로 주변에 스노우 플레이크를 쓴 케이스가 있는지 찾아보니 다음과 같은 사례가 있다고 합니다. (출처: Wikipedia)

  • Twitter
  • Discord
  • Instagram
  • Mastodon

SNS 와 관련된 분야에서 많이 활용되는 것으로 보입니다. SNS 는 엄밀한 순서가 보장되지 않아도 큰 문제가 되지 않습니다.

 

만약 엄밀한 순서 보장이 필요한 도메인(ex. 금융거래)이라면, Snowflake ID의 사용은 어렵지 않을까 생각됩니다.

 

<번외>  Snowflake ID 에서 1 bit 을 남겨둔 이유

다들 궁금한게 비슷했는지, 공통적으로 궁금해 하였던 내용입니다.

 

스터디에서 논의할 때에는 reserved 가 아닐까 생각하였지만, 후기 글을 작성하면서 관련 내용을 좀 더 찾아보니 아래와 같은 글을 찾아볼 수 있었습니다.(관련 글: One bit not used)

 

정리하자면, JVM에서 unsigned를 지원하지 않기 때문에 1bit를 남겨두었다고 합니다.

 

<번외> 시계가 뒤로 돌아간다니 그게 무슨말이야?

서버의 시스템 시간은 항상 앞으로만 흐르지는 않습니다.

시간 동기화 과정이나 수동 설정 과정에서간이 뒤로 조정될 수 있기 때문입니다. 

 

이를 방지하기 위해 NTP는 Slew 기능을 제공합니다. 이는 시간을 바로 맞추는 대신 서서히 조정하여 보정하는 방식입니다. 

 

보다 깊은 내용은 NTP 관련 문서나 Google Spanner의 TrueTime 관련 논문을 참고해보시길 바랍니다.

 

[2] URL 단축기

URL 단축기는 대부분의 개발자가 한 번쯤 고민해봤을 주제입니다.

책에 기본적인 내용은 잘 정리되어 있으므로, 이 글에서는 운영과 보안 관점에서 나눈 이야기에 대해서만 정리합니다.

 

아래와 같은 내용을 함께 나눠보았습니다.

  • URL이 짧을 때 얻을 수 있는 이점은 무엇일까?
    • 사용 편의성 향상: 긴 URL보다 복사/전송, 공유가 쉬워 사용자가 접근하기 편리합니다.
    • SMS/메시지 비용 절감: URL이 짧으면 SMS 한 건에 전체 링크를 담을 수 있어 비용을 절약할 수 있었습니다.
  • 누군가 랜덤으로 주소를 입력하여 들어오면 어떻게 할 것인가
    • 순차적 URL 방지: 순차적으로 증가하는 URL은 쉽게 예측 가능하므로, 보안상 위험이 있습니다.
      • Salt 처리: URL에 랜덤 문자열이나 해시를 추가하여 추측 공격을 어렵게 합니다.
    • 인증/권한 관리: 일부 URL은 특정 사용자만 접근 가능하도록 권한을 체크합니다. (ex. google drive)
  • URL을 계속 열어둬도 될까?
    • URL 만료 기간 설정: 오래된 링크는 자동으로 비활성화하여 보안을 강화합니다.

함께 공부할 때 얻는 시너지

오늘은 위와같은 이야기를 함께 나누어보았습니다. 사실 더 많은 이야기를 나눴지만, 여기에 다 기록하지 못해 아쉽습니다🥲

 

혼자 책을 읽을 때는 쉽게 넘겼을 부분도 스터디에서 같이 토론하다 보면 다른 관점에서 보게되기도 하고, 생각하지 못하고 넘어갔던 부분도 다시 한 번 짚어 볼 수 있었습니다.

 

“과연 이 기술이 우리 서비스에 필요한가?” 같은 질문을 던지며 이야기를 나누다 보니, 단순히 개념 습득을 넘어 실제 상황에서 어떻게 활용할지를 고민할 수 있었습니다.

 

남은 스터디도 더 좋을 시간이 될 수 있기를 기대합니다.


 

 직접 스터디를 개설해보고 싶은 분이 계시다면, K-DEVCON에서 운영을  도와드리겠습니다.

데브콘의 '랩짱'에 도전하여 커뮤니티 성장을 함께 이끌어주세요! 슬랙을 통해 운영진에게 DM 부탁드리겠습니다😉