포스팅에 사용된 그림은 책에서 제공하는 그림들 입니다.
요구사항 도출
개략적 추정
클라이언트가 서버가 제공하는 API 엔드포인트를 통해 서버와 통신한다. 우리는 이 엔드포인트를 REST 스타일로 설계해볼 것이다.
POST /api/v1/data/shorten
GET /api/v1/shortUrl
아래 그림은 단축 URL을 입력하면 어떤 일이 발생하는지 보여준다.
축 URL을 받은 서버는 그 URL을 원래 바꿔서 301 응답의 Location헤더에 넣어 반환한다.
아래 그림은 클라이언트와 서버 사이의 통신 절차를 좀 더 자세히 보여준다.
여기서의 차이는 301이냐 아니면 302이냐의 차이다.
이 두 방법은 각기 다른 장단점을 갖고 있다. 서버 부하를 줄이는 것이 중요하다면 301를 사용하는 것이 좋은데 첫 번째 요청만 단축 URL 서버로 전송될 것이기 때문이다. 하지만 트래픽 분석이 중요할 때는 302를 사용하는 것이 클릭 발생률이나 발생 위치를 추적하는 데 좀 더 좋을 것이다.
URL 리디렉션을 구현하는 가장 직관적이 방법은 해시 테이블을 사용하는 것이다. 해시 테이블에 <단축 URL, 원래 URL>의 쌍을 저장한다면 URL 리디렉션은 다음과 같이 구현될 수 있다.
아래 그림을 보면
결국 중요한 것은 긴 URl을 해시 값으로 대응시킬 수 있는 fx이다.
해시 함수는 다음과 같은 요구사항을 만족해야 한다.
데이터 모델, 해시 함수, URL 단축 및 리디렉션에 관한 구체적인 설계안을 만들어보자.
그동안은 모든 것을 해시 테이블에 저장했는데, 이는 초기 전략으론 괜찮지만 실제 서비스에 쓰기에는 곤란하다. 메모리는 유한한 데다 비싸기 때문. 더 나은 방법은 <단축 URL, 원래 URL>의 순서쌍을 관계형 데이터베이스에 저장하는 것이다. 아래 그림은 테이블의 간단한 설계 사례다.
해시 함수는 원래 URL을 단축 URL로 변환하는 데 쓰인다. 편의상 해시 함수가 계산하는 단축 URL 값을 hashValue라고 지칭하겠다.
hashValue는 요구사항에서 [0-9, a-z, A-Z]의 문자들로 구성하므로, 사용할 수 있는 문자의 개수는 10+10+26=62개다. hashValue의 길이는 62의n승>3650억인 n의 최솟값을 찾아야 한다.
아래 표는 hashValue의 길이와 해시 함수가 만들 수 있는 URL의 개수 사이의 관계다.
n=7이면 3.5조개의 URL을 만들 수 있다. 요구사항을 만족시키기 충분한 값이다. 따라서 hashValue는 7개로 하겠다.
해시 함수 구현에 쓰일 기술로는 두 가지 방법을 살펴보자.
긴 URL을 줄이면 원래 URL을 7글자 문자열로 줄이는 해시 함수가 필요하다. 손쉬운 방법은 CRC32, MD5, SHA-1같이 잘 알려진 해시 함수를 이용하는 것이다.
근데 표를 보면 가장 짧은 길이를 가진 CRC32 해시값조차도 길이가 7을 넘는다. 어떻게 줄일 수 있을까?
이 문제를 해결하려면 계산된 해시 값에서 처음 7개 글자만 이용하는 것이다. 하지만이렇게 하면 해시 결과가 서로 충돌할 확률이 높아진다. 충돌이 실제로 발생하면, 미리 정한 문자열을 해시값에 덧붙인다.
이 방법을 쓰면 충돌은 해소할 수 있지만 단축 URL을 생성할 때 한 번 이상 DB질의가 필요하므로 오버헤드가 크다. DB대신 블룸 필터를 사용하면 성능을 높일 수 있다. 블룸 필터는 어떤 집합에 특정 원소가 있는지 검사할 수 있도록 하는, 확률론에 기초한 공간 효율이 좋은 기술이다.
진법 변환은 URL 단축기를 구현할 때 흔히 사용되는 접근법 중 하나다. 이 기법은 수의 표현 방식이 다른 두 시스템이 같은 수를 공유하여야 하는 경우에 유용하다. 62진법을 쓰는 이유는 hashValue에 사용할 수 있는 문자 개수가 62개이기 때문이다. 그럼 지금부터 base-62 변환이 어떻게 이루어지는지 살펴보자. ex)11157 → 62진수
URL 단축기는 시스템의 핵심 컴포넌트이므로, 그 처리 흐름이 논리적으로는 단순해야 하고 기능적으로는 언제나 동작하는 상태로 유지되어야 한다.
아래 그림은 리디렉션 메커니즘의 상세한 설계를 그리고 있다. 쓰기보다 읽기를 더 자주 하는 시스템이라, <단축 URL, 원래 URL>의 쌍을 캐시에 저장하여 성능을 높였다.
로드밸런서의 동작 흐름은 다음과 같이 요약할 수 있다.
URL 단축기의 API, 데이터 모델, 해시 함수, URL 단축 및 리디렉션 절차를 설계해 보았다.
그리고, 아래와 같은 것들도 고려해볼 수 있다.