Nestjs

<Nestjs & REDIS> REDIS nestjs 에 붙이기, VM 배포 환경에서 redis 설정방법, nestjs redis TTL not working, nestjs redis not working

Summer-Jin 2025. 6. 16. 12:18

  // 레디스에 저장한 값 갖고오기
  async getRedisValue() {
    const key = 'mykey';
    // console.log(this.cacheManager.stores);
    console.log('레디스에서 값 갖고오기 들어옴 키값: ', key);
    const value = await this.cacheService.get(key);
    console.log('레디스에서 갖고온 값 : ', value);
    if (value === undefined || value === null) {
      console.log('레디스 에서 못갖고옴 ');
    }

    return value;
  }

 

주의! 저처럼 공부하는 도중 에러 및 수정을 위해서 검색해서 들어온 사람들을 위해... 꼭 본인의 cache Manager, redis 와 레디스 스토어 버전을 꼭꼭 확인 후 글을 읽어주세요 

작성일 2025.6 월 기준으로 작성되었습니다.

 

사실 이전 프로젝트때 nestjs에 redis를 붙여서 배포까지 해본적이 있었다. 그래서 공수가 얼마 안들줄 알았고 실제로 코드를 짜는 데도 오래 걸리지 않았다. 분명 로컬에서 잘 작동하는걸 확인했는데 azure VM에 배포하고 나니까 전혀 작동을 안했다. 왜,,,,웨ㅔ에에에에ㅔㅔㅔ!!!!!!

 

사실 희안하게 작동했는데 인증하기를 여러번 요청하면 4번에 1번꼴로 캐시값을 갖고와서 비교해주었다ㅋㅋㅋㅋ

 

우리 로직에서는 이메일 본인 인증에 사용할거라 인증코드를 잠시 저장하는 용도였다.

복잡한 데이터 구조도 아니고 그냥 String 저장했다가 꺼내오는건데 왜 안되는건지 진짜ㅋㅋㅋㅋ 이걸 고친다고 시도를 수십번 한것 같다. 

 

여러 시도를 해본 끝에 고치긴했다. 사실 nestjs 캐시 매니저랑 레디스 스토어 라이브러리들을 진작 뜯어봤으면 해결이 훨씬 더 빠르지 않았을까... 싶다....

 

왜 작동을 안하는건지 답답해서 주변에 질문을 하려고 해도 어떤시도를 해봤고 어떤 부분이 의심되는지 나도 명확하지 않았다.

'제 코드엔 문제가 없는것 같은데 왜 안되는지 모르겠어요'

라고 할 수 는 없으니 일단 내가 확인해 본 것들을 정리해봤다. 왜 안되는 것인지 원인을 모른채로 질문하는 것만큼 바보 같은게 없다고 생각한다.....

 

여튼 다음을 바탕으로  '이것들을 체크해봤는데 안돼서 어떤걸 더 확인해봐야 할까요?' 라고 질문해서 결정적인 힌트를 얻을 수 있었다. 

 

확인해봐야 할 몇 가지 체크사항

1. TTL 확인

처음엔 TTL이 설정이 잘못된줄 알았다. 레디스의 버전에 따라 밀리세컨드, 라이브 타임 인지 확인해봐야한다.

나는 이것 때문인줄 알고 별에별 ttl을 집어넣었었다. gpt한테 물어봐도 예전 버전 공식문서를 바탕으로 대답을 해주는지 ttl을 정수로 넣는걸로 바뀐지 오래인데 이런식으로 집어넣으라고 한다.

{ttl: 600 }

 

당연히 타입 오류가 난다. number 형태의 데이터가 들어와야 하는 자리라고 에러를 뱉는다

 

{ttl : 600} as any

 

이런식으로 지정하라고 하기도 하는데 이게 동작하는지는 모르겠다. 

 

내 캐시매니저와 레디스, 레디스 스토어의 버전은 다음과 같고 TTL의 기준이 라이브 타임이다. 

 "@nestjs/cache-manager": "^3.0.1",
 "cache-manager-ioredis-yet": "^2.1.2",
 "redis": "^3.1.2",

 

 

 

2. 배포 설정파일 확인

일단 나의 경우에는 도커로 배포를 했는데 배포 설정파일에는 문제가 없는 것을 확인했다.

그리고 docker-compose.yml 의 내용과 환경변수도 제대로 입력했는지 확인해야한다.

redis 컨테이너 명과 redis설정하는 곳에서 host 명이 동일한지 제대로 체크해야한다. 

로컬에서 확인할때는 당연히 localhost 여야 한다.

 

3. 캐시 사용하는 곳 코드 확인

그리고 당연하지만 캐시를 사용하는 부분의 코드에서도 문제가 없었다.

캐시를 사용하는곳 modeul.ts 파일에서 import 로 의존성 주입도 잘 해주었다.

나는 app.moduel.ts에서 설정한게 아니라 cache 모듈을 따로 만들어두었기 때문에 필요한 곳에 의존성을 주입해주었다.

 

4. 레디스 서버가 활성화 되어있는지 확인

내 로컬 터미널에서

$ redis-cli ping

 

레디스에 ping을 보내고 pong이 오는지 확인

 

 

도커환경에서도 서버를 킨다음에 레디스 컨테이너가 켜져 있는지 확인

$ docker exec -it <redis_container_name_or_id> redis-cli ping

 

$ docker exec -it my-redis redis-cli ping

 

 

5. 레디스 서버가 켜져있는데도 동작을 안한다면? 레디스에 임의로 값을 저장한 다음 백앤드 서버에서 값을 갖고올 수 있는지 확인

 

만료시간없이 일단 저장한다.

$ SET key value

 

그 다음 레디스에서 갖고올 수 있는지 확인

$ GET key

 

갖고와진다면 테스트 엔드포인트 만들어서 테스트

 

controller.ts

  @Get('from-redis')
  async getRedisValue(){
    return this.authService.getRedisValue();
  }

 

service.ts

  // 레디스에 저장한 값 갖고옥
  async getRedisValue() {
    const key = 'mykey';
    // console.log(this.cacheManager.stores);
    console.log('레디스에서 값 갖고오기 들어옴 키 값: ', key);
    const value = await this.cacheService.get(key);
    console.log('레디스에서 갖고온 값 : ', value);
    if (value === undefined || value === null) {
      console.log('레디스에서 못 갖고 옴');
    }

    return value;
  }

 

 

나는 이 단계에서 문제점을 찾았다. 레디스에서 값을 갖고오지 못한 것이었다..

확인해보니 레디스의 버전이 바뀌면서 store를 지정해줄때의 타입이 변경되었다고 한다..

내 store 를 지정하는 코드가 null | undefined를 뱉어내고 있었다. 레디스를 사용하겠다고 설정해놨으나 redis의 저장소를 제대로 지정해주지 못했고, 제대로 알려주지 못해 인-메모리 캐시를 사용하고 있었던 것...

 

 

이전 코드

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { ConfigModule, ConfigService } from '@nestjs/config';

import { CacheService } from './cache.service';
import { redisStore } from 'cache-manager-ioredis-yet';

@Module({
  imports: [
    CacheModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => ({
        store: redisStore,
        host: config.get('REDIS_HOST', 'redis'),
        port: config.get('REDIS_PORT', 6379),

        ttl: 60000,
      }),
    }),
    ConfigModule,
  ],
  providers: [CacheService],
  exports: [CacheService, CacheModule],
})
export class CacheConfigModule {}

 

 

현재 코드

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { ConfigModule, ConfigService } from '@nestjs/config';

import { CacheService } from './cache.service';
import { RedisCache, redisStore } from 'cache-manager-ioredis-yet';

@Module({
  imports: [
    CacheModule.registerAsync<RedisCache>({
      isGlobal: true, // 혹시몰라 추가했다
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (config: ConfigService) => {
        const store = await redisStore({
          host: config.get('REDIS_HOST', 'redis'),
          port: config.get('REDIS_PORT', 6379),
        });

        return {
          store,
          ttl: 60 * 1000,
        };
      },
    }),
    ConfigModule,
  ],
  providers: [CacheService],
  exports: [CacheService, CacheModule],
})
export class CacheConfigModule {}

 

 

이렇게 수정해서 저장소를 잘 지정해주었고 제대로 작동하는 것을 확인했다ㅠㅠ.....

 

 

 

고치기 까지 정말 많은 삽질을 했는데 인터넷에 뒤져봐도 옛날 글들이라 cache-manager 버전을 낮춰야 한다는 글,  ttl을 옛날 버전으로 바꿔야 한다는 글들이 너무 많아 버전을 낮춰보기도 하고 여러 시도를 해봤는데 결국 잘 안됐다. 

이렇게 글로 정리하니까 엄청 금방 한 것 같은데 고쳐보겠다고 이삼일 새벽을 샜다ㅠㅎㅎㅎ

 

 

어쨌든 고쳐서 속시원하고 매우매우 기쁘다ㅠㅎㅎㅎ

728x90