ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • NestJS와 ioredis를 이용한 초대링크 만료 시간 설정하기
    Redis 2024. 8. 23. 17:07
    728x90

    개요

    특정 그룹의 초대 링크를 이메일로 전송 했을경우 링크가 만료되지 않는다면 1년이든 5년이든 뒤에도 해당 초대 링크를 이용하여 가입할 수 있을것이다. 그래서 그룹 초대링크 같은 초대 링크가 만료될 수 있는 기능이 필요하다.
    해당 초대링크 만료기간 기능을 추가하기 위해 Redis의 TTL을 이용해보자

     

    Redis의 Cache Expire에 대해 짧게 알아보자

    캐시를 사용 하더라도 관리, 비용 측면에서 데이터를 무기한 저장하지 않습니다.
    키에 타임아웃을 설정합니다. 타임아웃이 만료되면 키가 자동으로 삭제됩니다. 관련 시간 초과가 있는 키를 Redis 용어로는 휘발성이라고 합니다.
    Redis의 경우 이런 만료 시간을 처리하기 위해 Key별 TTL(Time-To-Live)을 설정할 수 있습니다.

     

    만료 기간이 있는 초대 링크 만들기

    • 초대링크를 생성한 후에 key, value를 Redis에 저장하고 TTL 만료 기간을 설정 해준다.
    • 해당 초대링크를 포함하고 있는 메일을 대상에게 전송하거나 링크를 공유 할 수 있게 제공 합니다.
    • 초대받은 대상이 링크를 클릭 한다면 요청받은 코드와 동일한지 확인하고, 동일하지 않다면 예외를 반환
    • Redis의 key를 통해 value값이 존재 하는지 확인하고 존재 한다면 그룹 초대, 만약 없다면 만료 링크이기 때문에 예외를 반환

     

    Redis set 옵션

    - ( https://redis.io/docs/latest/commands/set/ )

    EX seconds 지정된 만료 시간을 초 단위(양의 정수)로 설정합니다.
    PX milliseconds 지정된 만료 시간을 밀리초(양의 정수) 단위로 설정합니다.
    EXAT timestamp-seconds 키가 만료되는 지정된 유닉스 시간을 초 단위(양의 정수)로 설정합니다.
    PXAT timestamp-milliseconds 키가 만료되는 지정한 유닉스 시간을 밀리초(양의 정수) 단위로 설정합니다.
    ... ... ...

     

    해당 groupId에 해당하는 초대링크를 만들어서 EX 옵션은 위에 보듯이 만료 시간을 초 단위(양의 정수)로 설정 하는 역할을 하고
    만료를 원하는 초대 만료 링크를 ttl로 설정 해두었다.
    이제 초대 만료 기간이 존재하는 그룹 초대 링크를 완성하였다. 근데 문제가 하나 있는데 만료 되기전에 해당 링크로 불특정 다수가 아무나 가입이 가능하다는것이다. 100명이든 1000명이든... 그래서 최대 사용 횟수를 설정 할 수 있게 remainingUses를 설정하여 특정 누군가가 가입 하게 되었다면 가입자 수를 제한 하게 만들고 싶었다.
    그러나 이렇게 만들게 된다면 remainingUses -1 한값을 다시 redis.set 해주게 된다면 ttl이 초기화 된다. 그래서 찾아보니 Redis 트랜잭션을 이용하여 ttl을 초기화 되지 않게 유지 하고 업데이트 할 수 있었다.

     

     

    JSON으로 저장하는것과 트랜잭션을 이용하는 방식이 마음에 들지 않는다.

     

     

    hash 자료형 사용

    HSET을 사용했을때 얻을 수 있는 이점은 다음과 같다.
    • HSET을 사용하면 remainingUses와 groupId를 각각 관리할 수 있고, 특정 필드만 업데이트할 수 있다.
    • HSET 명령어는 TTL을 유지하면서 데이터를 업데이트한다.

    - ( https://redis.io/docs/latest/commands/expire/ )

    " hash with HSET are all operations that will leave the timeout untouched."
    2번째 내용은 공식문서에서 찾은 내용이다.

    TTL이 변경되지 않는 케이스를 공식문서에 나와 있는 내용을 짧게 정리 해보자.

    incrementing the value of a key with INCR, pushing a new value into a list with LPUSH, or altering the field value of a hash with HSET are all operations that will leave the timeout untouched.
    INCR로 키 값을 증가시키거나, LPUSH로 새 값을 목록에 밀어 넣거나, HSET로 해시의 필드 값을 변경하는 작업은 모두 타임아웃을 그대로 유지하는 작업입니다.

     

    • INCR
    • LPUSH
    • HSET

     

    이제 그룹 초대 링크를 만드는 메서드는 준비 되었고

     

    Reference

    - ( https://redis.io/docs/latest/commands/expire/ )

    - ( https://yozm.wishket.com/magazine/detail/2296/ )

    - ( https://velog.io/@bdd14club/%EB%91%90%EB%A0%88-Redis-%EB%8F%84%EC%9E%85%EA%B8%B0 )

    - ( https://github.com/redis/ioredis?tab=readme-ov-file )

    728x90
Designed by Tistory.