nest.js-redis(hgetall/hmset 등 등 ...)

이얏호·2023년 8월 23일
0

팀 작업 중이었는데,
우선 제한 사항부터 기술해보자면,
팀원 분이 버전 호환 이슈로 redis를 3.1.2버전을 설치하였다.

그 상태에서 작업을 진행하던 중,
배열 상태로 통째로 redis에 set을 할 일이 생겼다.

for문을 돌리면 너무 비효율적일 것 같아서 방법을 찾아봤는데
mset()이라는 메서드가 존재했다.

사용을 해보려고 했으나, 현재 사용된 캐시매니저와 레디스 구버전 등등의 이유로 사용이 불가했다...

그래서 레디스 자체 메서드 중 3.2.1버전에서 사용가능한 방법을 찾다보니
hmset()이 존재했다.

hmset('해시이름',['필드','밸류','필드2','밸류2])의 형식으로 사용이 가능하며,
최종적으로는 해시 이름으로 묶인 채 내부에 필드명 / 벨류 형식으로 저장이 된다.

구현하고자 했던 기능이 누적 판매량 관련 저장 부분이었어서 사용하는데에 지장이 없었는데,
문제는 불러올 때 있었다.

hmget / hget / mget / get ... 등등의 없어지거나 새로 생긴 메서드들을 사용해봤으나 제대로 작동하지 않았고,

hgetall()이라는 메서드가 작동은 했는데 도무지 반환 값이 받아지지 않았다.

const rank = await redisClient.hgetall('rank');

다음과 같은 형식으로 rank에 할당해주면 rank는 true값을 반환한다.
내부 값을 받는 방법으로

let data;
console.log(1)
await redisClient.hgetall('rank', function((err, obj) => {
	data = obj
    console.log(obj)
}));
console.log(data)

위와 같이 구성을 하고 돌려보면,
내부에 있는 console.log(obj)는 정상적으로 redis에 저장된 값이 로그로 남지만
console.log(data)에서는 obj값이 찍히지 않는다.

처음부터 해본건 아니지만 위와 같이 구성하고 로그를 살펴보았을 때,
1 -> obj > data 순서로 찍히는게 아니라
1 -> data -> obj의 순서로 찍히는 것을 확인했다.

해결 방법으로 오버라이딩을 사용했다.
redisService를 만들어서 내부에 hgetall을 만들어주기로 했다.

import { BadRequestException, Injectable } from '@nestjs/common';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const redis = require('redis');
const client = redis.createClient();

@Injectable()
export class RedisService {
  async hgetall(key: string): Promise<{ [key: string]: string }> {
    return new Promise<{ [key: string]: string }>((resolve, reject) => {
      client.hgetall(key, (err, reply) => {
        if (err) {
          console.error(err);
          throw new BadRequestException();
        }
        resolve(reply);
      });
    });
  }
 }

이렇게 hgetall을 promise로 선언해주고, 실제 client.hgetall의 값을 resolve에 담아주어서 값을 반환받는데에 성공했다.

아래는 예시

const rank = await this.redisService.hgetall('rank');

이렇게 하면 rank 변수에 redis의 값이 정상적으로 할당된다.

구버전 redis로 고생받는 사람이 없었으면 좋겠다...

profile
열심히 신나게 화이팅!

0개의 댓글