기간: 2023.10.05 ~ 2023.10.18
- 토이프로젝트로 2주간, 방문자를 조회하는 URL 트래킹 사이트를 개발해보기로 하였습니다.
개요
- 사람들이 사이트를 얼마나 방문하는지 추적하고, 데이터를 어떻게 잘 저장하는 방법을 생각하는 좋은 주제인 것 같습니다.
구조잡기
- Layer VS Domain
멀티모듈, 핵사고날 선택지는 많은데, 시간대비 유지보수하기 좋게 해볼 구조는 역시 도메인 구조를 잡는 것이 좋은 것 같습니다. - 조회모델을 만드는 것부터해서 개발초기에는 이것저것 해보고 싶은게 많은 것 같습니다.
하지만 요구사항을 빠르게 구현할 수 있는 구조를 우선으로 두었습니다.
어떻게 잘 저장할 수 있을까?
- 프로젝트의 핵심기능이다보니 어떻게하면 주소를 잘 저장하고 불러올 수 있을지 고민하게 됩니다.
가장 쉬운 방법?
- 저장기능 호출시 RDB 테이블의 URL, 카운트, 저장일을 저장을 합니다. 저장하기전 URL로 조회하여
이미 존재하는 URL이라면 카운트를 증가시킵니다. - 저장할때는 현재 날짜를 기준으로 저장한다면 필요한 요구사항을 맞출 수 있을 것입니다.
- 카운트의 정합이 필요하면 락을 사용합니다.
문제점?
- 평범하게 길이가 긴 URL 이 입력된다고 가정하고 대략 2048 chars의 글자가 들어온다고 가정.
- RDB 기준으로 했을때 PK 혹은 대체키로서 URL 카운팅을 하려면 계속적으로 조회를 해야합니다.
인덱스를 걸게되면 인덱스를 기준으로 정렬을 해야하는데 거대한 문자열을 키로 잡는 것은 RDB에서 효율적으로
운영하기 어렵습니다.
다른 대안?
- NoSQL을 사용해보면 좋을 것 같습니다? NoSQL의 경우 조회에 유리하기도 하고 시스템을 확장하기에도 좋기때문입니다.
문자 검색에 유리한 검색엔진을 사용할수도 있을 것 같습니다. - RDB를 메인으로 사용하기로 했기때문에 RDB에서 URL을 효율적으로 저장하려면 어떤 방법이 있을까.?
먼저 떠올린 것은 주소를 인코딩하는 방법입니다.
인코딩?
- 문자를 특정하게 인코딩하여 저장소의 키로 삼으면 되지 않을까?
- 인코딩은 Base62를 이용하기로 했습니다. Base62을 사용한 이유는 다음과 같습니다.
- Base62 를 사용하면 0-9 a-z A-Z를 이용하여 인코딩을 하게 되는데 이제 7자를 잘라서 키로 사용합니다.
필요할 경우 키를 직접사용할 수도 있고 저장의 효율를 위해서 7자를 사용했습니다.
- long url = 2048 -> 2kb
- key = 7 chars - Base62 를 이용하여 7자를 사용하면 62의 7승 만큼 키를 쓸 수 있으니 문제는 없을 것 같습니다.
- 키 인코딩후 주소 검증 및 카운트를 빠르게 응답할 필요가 있기때문에 중간에 Redis를 사용하기로 했습니다.
필요한 경우 주소 캐싱을 사용할 수 도있고 입력제한으로도 활용할 수 있을 것같습니다. - 주소가 늘어날 수록 키 생성을 위해 RDB를 조회하는 것보다 Redis를 사용하면 빠르게 생성하는 장점이 있습니다.
사용자?
- 하루 이용자 1000 명이라 가정하고 10 개 정도 URL을 입력을 하면 = 하루에 만개 정도 사용됩니다.
- 2 kb * 10,000 = 20Mb / day로 생성되는데, 1년 단위로 봤을때도 많은 데이터를 사용하지는 않을 것으로 보입니다.
- 인코딩 도중 키 충돌이 생길 수도 있습니다. Long URL로 조회하게되면 문제가 없겠지만, 인코딩 키로 조회했을때는
키 이슈가 발생할 수도 있습니다. 실제 사용자의 비례해서 키가 중복되는 케이스는 적을 수 것으로 예상되지만,
이 경우 키가 조회된다면 인코드된 키로 조회된 URL과 비교하여 같다면 카운트를 증가하고 아니라면 신규로 키를 만들어서
생성할 수 있을 것 같습니다. 처음부터 최적의 구현을 사용하는 것이 반드시 옳다기 보다는, 데이터가 적을 때 쓸 수 있는
방법들을 현재 조건에 맞게 사용하였습니다.
Redis 활용?
- Redis를 사용함으로서 조회수 정합의 걱정도 줄였습니다.
Redis사용을 통해 동시성 이슈로부터 안전하게 조회수를 갱신할 수 있었습니다. - 기본적으로 오늘 날짜를 기준으로 기록은 Redis에 저장이 되며, 자정이 넘어가는 시간에 스케쥴링을 통해 Redis의 데이터를
RDB로 마이그레이션하고, Redis의 데이터는 비우게 됩니다. 빈번하게 기록되는 내용은 Redis에 오랜기간 보관해야하는
데이터는 RDB로 저장한다고 볼 수 있습니다.
개선사항?
- 당장은 필요하지 않지만 사용자에 따라 조회수를 악의적으로 늘릴 수 있습니다. 이 경우 입력 제한을 사용할 수 있을 것 같습니다.
- 만약 Redis가 작동을 하지 않으면 어떻게 될까요? 사실 이것은 RDB가 작동하지 않아도 같은 걱정 상황이긴합니다. 이 경우
Redis의 작동 유무를 판단하는 서킷 브레이커를 추가적으로 사용하여 Redis가 응답하지 않는다면
RDB로 대체하여 활용할 수 있을 것 같습니다.
'회고 모음 > Project' 카테고리의 다른 글
웹소설 서비스 만들기-5 (0) | 2023.04.30 |
---|---|
웹소설 서비스 만들기-4 (0) | 2023.04.17 |
웹소설 서비스 만들기-3 (0) | 2023.04.17 |
웹소설 서비스 만들기-2 (0) | 2023.04.17 |
웹소설 서비스 만들기-1 (0) | 2023.04.17 |