URL Shortener

참치돌고래·2022년 8월 16일
0

자바로 URL Shortener를 제작하면서 겪었던 트러블 슈팅을 기록하고자 합니다.

기존 플로우

  1. long url
  2. encrypt
  3. base62
  4. 8자리 씩 끊어서 DB에 중복된 값이 있는지 확인
  5. 중복되지 않으면 저장

해당 5번까지 DB에 쿼리를 날리면서 짧게 짜른 URL이 DB에 중복된 값이 존재하는지 확인해야 했습니다.
또한, 검색하는 칼럼이 index로 설정되어 있지 않은 문자열이였기 때문에, 검색 성능 역시 효율적이지 못했습니다.

변경된 플로우

  1. long url
  2. unique id (64bit)
  3. base62

그래서 unique id 생성기를 통해 64bit의 id로 생성을 하고, 해당 url을 base62로 인코딩을 하여 DB에 저장하는 방식을 택하였습니다.
그렇게 되면 DB에 저장을 할 때, 8자리씩 짤랐을 때, 중복된 값이 DB에 있는지 확인하지 않아도 되어 조회하는 비용을 줄일 수 있었습니다.
unique id 생성기의 경우 64비트로 생성되게 하여 8자리씩 끊을 필요가 없을 뿐만 아니라, id 칼럼에는 기본적으로 index가 걸려있고 정수이기 때문에, 검색 성능 역시 기존 플로우보다 효율적이었습니다.

unique id generator의 경우에는 twitter의 snowflake를 참조하여 생성했습니다. 싱글톤을 유지하면서, 생성 메소드에서 기존 상수를 참조하는 부분에 락을 걸어 동기화가 되도록 하였습니다.


@Override
    public long generateRandomId() {
        long timeStamp = timeSource.getTick();
        if (timeStamp < 0){
            throw new IllegalTickStateException(ErrorCode.IllegalTickState);
        }

        try {
            lock.lockInterruptibly();

            if (timeStamp < lastTimeStamp) {
                throw new IllegalTimeStampStateException(ErrorCode.IllegalTimestampState);
            }
            log.info("timestamp {} : lastTimeStamp {}", timeStamp, lastTimeStamp);
            if (timeStamp == lastTimeStamp) {
                sequence = (sequenceBits + 1) & sequenceMask;
            } else {
                sequence = 0L;
            }
            lastTimeStamp = timeStamp;
        } catch (InterruptedException e){
            log.error("interrupted Exception ", e);
        } finally {
           lock.unlock();
        }
        return (timeStamp << shiftTime) | (datacenterIdBits << datacenterIdBits) | (generatorId << generatorBits) | sequence;

저장소 : https://github.com/SIOUkoeran/shortUrl

profile
안녕하세요

0개의 댓글