Beginner's Guide to Redis and Caching with NodeJS

대략 공부를 해서 어떤 용도로 사용할 수 있는진 파악했으나, 만들어진 결과물을 따라 만들면서 감을 잡기 위해 해당 페이지를 참조했다.

설치

UseCase

Caching

Caching with Redis

import { HttpService, Injectable } from '@nestjs/common';
import { promisify } from 'util';
import * as redis from 'redis';
import * as dotenv from 'dotenv';

dotenv.config();

const redisPort = 6379;

const redisClient = redis.createClient(redisPort);
const getAsyncFromRedis = promisify(redisClient.get).bind(redisClient);
const setAsyncToRedis = promisify(redisClient.setex).bind(redisClient);

const { NAVER_CLIENT, NAVER_SECRET } = process.env;
const baseUrl = '<https://openapi.naver.com/v1/search/news.json>';
const wantToSee = 100;

@Injectable()
export class NaverSearchService {
  constructor(private httpService: HttpService) {}

  async getSearchResult(keyword: string) {
    try {
      const cachedData = await getAsyncFromRedis(keyword);

      // if cached
      if (cachedData) {
        const parsed = JSON.parse(cachedData);
        return parsed;
      }

      // if not cached
      const { data } = await this.httpService
        .request({
          method: 'get',
          headers: {
            'X-Naver-Client-Id': NAVER_CLIENT,
            'X-Naver-Client-Secret': NAVER_SECRET,
          },
          url: baseUrl,
          params: {
            query: keyword,
            display: wantToSee,
          },
        })
        .toPromise();

      await setAsyncToRedis(keyword, 600, JSON.stringify(data));
      return data;
    } catch (e) {
      throw e;
    }
  }
}

service layer 에 redis 를 추가해주었다. 유의할 점은 redis 에서 직접적으로 async-await 을 지원하지 않기에, utli 에 있는 promisefy 라는 method 를 이용해 Promise method 로 바꾸어주었단 점이다.

결과는?

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/fe0dbff9-79ae-42dc-994a-441ec12c15b1/redis-result.png

5ms 가 나온다. 대신 처음에 caching 이 필요하기에, 약 50ms 정도가 더 소요된다는 단점이 있긴 하다.

가장 중요한 건 이건 정말 간단한 useCase 이라는 점이다. 그래서 실제 운용을 할 땐 Redis 에 저장된 값들이 휘발되면 어떻게 할지, in-memory datastructure 이기에 memory 가 부족한 경우는 어떻게 해야하는지 등의 전략을 반드시 세워야 한다.

그럼에도 불구하고, 1/40 으로 결과를 줄여버린 건... 좀 놀랍다.