
실제 면접에서 받았던 URL 단축기 설계 질문을 바탕으로, 책에서 배운 설계 방법과 비교해보려고 한다.
면접 내용. 오래되서 정확히는 기억나지 않지만, 정리해봤습니다.
면접에서 설계하라는 질문을 처음 받아보기도 했고, 자신감도 없어서 그냥 .. 생각나는 대로 대답했다.
나: url 단축기가 뭔지 잘 모르겠습니다.
면접관: 주소를 카톡같은 거로 공유할 때, 주소가 길면 메시지 길이가 엄청 길어지겠죠? 근데, 우리는 짧은 주소로 받아 보잖아요. 주소가 다른데 어떻게 원래 주소로 들어가지는 걸까요?
(지금 생각해보면 정말 친절하게 설명해주셨다.)
나: 해시를 사용해서 주소를 압축하고, 주소는 자주 사용할 테니까 Redis 같은 캐시 저장소에 저장해야 합니다.
면접관: 사용자가 압축된 주소를 공유하고 클릭할 때부터 해당 페이지를 열기까지의 전 과정을 설명해주세요.
나: 사용자가 주소 공유
→ 해당 주소가 redis에 있는지 확인하고, 없으면 해시를 통해 주소를 압축하여 저장합니다.
사용자가 주소 클릭
→ 로드밸런서를 통해서 서버에 전달
→ redis에서 해당 주소를 찾아서 원래 주소로 http 302 응답을 주어 redirect 합니다.
(사실 뭐라고 길게 말했던 것 같은데, 기억이 안 난다.)
면접관: 해시 충돌은 어떻게 하나요?
나: (몰라서 자료구조 공부할 때 배운 선형탐사나 이중해싱 같은 것들 설명함)
원래의 도메인 주소를 축소해서 제공하는 시스템.
e.g.
https://www.example.com/articles/2026/01/20/system-design-url-shortenerhttps://sho.rt/aZ3kP요구사항
- URL 단축: 주어진 긴 URL을 훨씬 짧게 줄임
- URL 리디렉션: 축약된 URL로 HTTP 요청이 오면 원래 URL로 안내
- 높은 가용성과 규모 확장성, 그리고 장애 감내
개략적 추정
- 쓰기 연산: 매일 1억 개의 단축 URL 생성
- 초당 쓰기 연산: 1억 / 24 / 3600 = 1160
- 읽기 연산: 읽기 연산과 쓰기 연산 비율 10:1 가정. 읽기 연산은 초당 11,600회 발생
- URL 단축 서비스를 10년간 운영한다고 가정하면 1억 365 10 = 3650억 개의 레코드 보관해야 함
- 축약 전 URL의 평균 길이는 100이라 가정. 10년 동안 필요한 저장 용량은 3650억 * 100바이트 = 36.5TB
데이터 모델
해시함수
두 접근법 비교
| 해시 후 충돌 해소 전략 | base-62 변환 |
|---|---|
| 단축 URL의 길이 고정됨 | 단축 URL의 길이가 가변적. ID 값이 커지면 같이 길어짐 |
| 유일성이 보장되는 ID 생성기가 필요치 않음 | 유일성 보장 ID 생성기가 필요 |
| 충돌이 가능해서 해소 전략 필요 | ID의 유일성이 보장된 후에야 적용 가능한 전략이라 충돌은 아예 불가능 |
| ID로부터 단축 URL을 계산하는 방식이 아니라서 다음에 쓸 수 있는 URL을 알아내는 것이 불가능 | ID가 1씩 증가하는 값이라고 가정하면 다음에 쓸 수 있는 단축 URL이 무엇인지 쉽게 알아낼 수 있어서 보안상 문제가 될 소지가 있음 |
처리 흐름
긴 URL 입력받기
데이터베이스에 해당 URL이 있는지 검사
있으면 해당 단축 URL을 가져와서 클라이언트에 반환
없으면 유일한 ID 생성하고 데이터베이스의 기본 키로 사용. 62진법 변환을 적용해서 ID를 단축 URL로 만듦
ID, 단축 URL, 원래 URL로 새 데이터베이스 레코드를 만든 후 단축 URL을 클라이언트에 전달
URL 리디렉션: 로드밸런서의 동작 흐름
사용자가 단축 URL 클릭
로드밸런서가 해당 클릭으로 발생한 요청을 웹 서버에 전달
단축 URL이 캐시에 있는 경우에는 원래 URL을 꺼내서 클라이언트에 전달하고, 없으면 데이터베이스에서 꺼내기
데이터베이스에도 없으면 잘못된 단축 URL
데이터베이스에서 꺼낸 URL을 캐시에 넣은 후 사용자에게 반환
찾았다....