0. NestJS에서의 Redis 초기세팅
1. 랭킹조회(zset)하기 위한 레디스 명령어 (zadd, zrange)
2. 페이지네이션을 통해 레디스로부터 랭킹 가져오기
3. NestJS Cronjob
NestJS에서의 Redis 초기세팅 (ioredis + liaoliaots/nestjs-redis 사용하는 이유)
- 기본 redis 는 redis 클라이언트 내부에서 사용하는 instruction(zadd, zrange) 을 사용하는게 불가함
- 또한, 안정성이 기존의 이미지보다 높다고 이야기 한다. (기존 이미지보다 안정성이 높다는건 의외인데 이부분은 더 알아봐야할것같다)
랭킹조회(zset)하기 위한 레디스 명령어 (zadd, zrange)
- 실시간 리더보드를 구현하기 위한 레디스의 Sorted Set을 사용한다.
- 기본적으로 Sorted Set은 중복을 허용하지 않고, score 값을 기준으로 member을 정렬하여 결과값을 가져온다.
zadd?
key: Sorted Set의 이름, score: 멤버의 점수, member: 추가할 멤버의 값 순서로 이루어져 있다. 아래는 초기화하는 예시이다.
- redis cli : ZADD myzset 1 "one"
- NestJS: await redis.zadd(key, score, member);
하나 말고도 여러개를 받을 때에는 다음과 같이 적어줄 수 있다.
- redis cli : ZADD myzset 2 "two" 3 "three"
- NestJS: await redis.zadd('user_scores', 100, 'user1', 200, 'user2');
(user1의 점수를 100으로, user2의 점수를 200으로 설정)
zrange?
zadd해서 정렬된 세트에서 특정 멤버의 원소들을 가지고 온다. 랭킹 pagination을 구현해주어야 했기 때문에 zrange은 필수였다.
- redis cli : ZRANGE myzset 0 -1 WITHSCORES (WITHSCORES 은 스코어까지 불러오는지 여부를 설정해주는 옵션)
페이지네이션을 통해 레디스로부터 랭킹 가져오기
app.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRedis } from '@liaoliaots/nestjs-redis';
import { Redis } from 'ioredis';
import { Logger } from '@nestjs/common';
@Injectable()
export class AppService {
constructor(@InjectRedis() private readonly redis: Redis) {}
// push data to redis using zadd
async updateRanking(score: number, id: number) {
Logger.log(`Redis updateRanking: ${score}, ${id}`)
await this.redis.zadd('rankings', score, id);
}
}
- redis 에 랭킹데이터를 넣는 updateRanking 메소드는 score과 id를 인자로 받아온다.
- redis 내부에서는 score을 기준으로 랭킹이 정렬된다.
ranks.service.ts
const userRanking = await this.redis.zrange(
'rankings',
(page - 1) * 10,
page * 10 - 1,
);
- 페이지네이션을 위해 zrange 로 page 파라미터에 따라 몇개를 자르고 올지 결정해 주었다.
- 가령, 1페이지를 가지고 올 때 redis로 부터 0(1위)부터 9(10위)까지 가져올 수 있도록 구성해주는 것이다.
ranks.service.ts
@Post('/test/signin') {
...
Logger.log(`updateRanking(ladderScore, id): ${user.ladderScore}, ${user.id}`);
await this.AppService.updateRanking(user.ladderScore, user.id);
return res.send(userSigninResponseDto);
}
- 테스트 유저를 생성해 줄 때마다 위에서 정의해준 app.service.ts 의 updateRanking을 불러다가 초기화 시켜준다.
NestJS Cronjob
- CronExpression 에서 테스트를 위해 매분마다 handleCron() 들어가도록 Cron annotation으로 설정해주었다.
- 모든 유저를 updateRanking 할 수 있도록 유저 목록을 순회해서 레디스 내부에 업데이트 시켜주는 과정이다.
- logger으로 확인한다면 아래와 같이 매 분마다 유저정보가 업데이트가 되는것을 확인해볼 수 있다.
정리하자면..
- 처음 계정생성할 때 레디스에 초기화 시켜준다. (zadd 로 내부에서 알아서 정렬됨)
- 페이지네이션 된 정보를 ladderscore 가 높은순으로 가져와야 하기 때문에 zrevrange 로 10개씩 불러온다.
- Cron으로 1분마다 db에서 redis로 정보를 넣어주기 위한 Cronjob을 설정해준다.
https://tech.socarcorp.kr/dev/2023/06/27/handling-authentication-token-traffic-01.html
'NestJS' 카테고리의 다른 글
[NestJS] TypeORM Tips1 (Part 1: Don't use save()) (0) | 2024.02.07 |
---|---|
[NestJS] bcrypt로 패스워드 해시화 하기 (0) | 2024.02.06 |
[NestJS] 요즘 MZ들은 NGINX 대신 mkcert 쓴다. (1) | 2024.02.05 |
[NestJS] NestJS 에서 Swagger을 사용해보자 (0) | 2024.02.04 |
[NestJS] PostgreSQL 에서의 SQL Injection 방어 (0) | 2024.02.02 |