Redis

yukina1418·2022년 4월 24일
0

TIL

목록 보기
22/35

DB로 장바구니를 한땀한땀 만들고 있을 무렵

어? 장바구니 세션이랑 쿠키로 만들어요

....? 이해가 안되서 멘토님한테 다시 여쭤봤더니
아 장바구니 Redis로 만들어요, 곧 배울거에요

그리고 배우고 난 지금

....? (머리가 쪼개짐)

Redis란?


Redis는 키와 값으로 구성할 수 있는 NoSQL (비관계형 데이터베이스)이며 메모리(램)으로 작동하는 데이터베이스다.


컴공을 다녔거나, 컴퓨터에 조금이라도 지식이 있는 사람들이 모두 들어봤을 이야기 중 하나

램은 휘발성이고, 하드디스크는 비휘발성입니다.
하지만 그렇기에 램은 속도가 빠르며 하드디스크는 속도가 느린 편입니다.

여기서 이야기하는 Redis가 바로 램으로 작동한다.

그렇기에 다양한 데이터베이스 중 제일 빠른 처리 속도를 보여준다.
물론 단점으로는 디비컴퓨터가 죽어버리면 데이터가 다 증발해버리는 최악의 결과도 볼 수 있다(....)

그래서! Reids는 메인 DB가 아닌 Cache를 담아놓는 임시저장소의 느낌으로 많이 활용을 한다.

그리고 활용법은 두가지로 나눠지며, 패턴이라는 식으로 설명을 하는데


첫번째는 Cache-Aside 패턴이다.

만약 어떤 유저가 치킨이 들어간 모든 브랜드를 찾는다고 검색을 했다고 하자.

  1. 유저A가 치킨으로 검색을 한다.
  2. DB에서 치킨이 들어간 모든 데이터를 꺼낸 후 Redis에 저장을 하고 유저에게 반환한다.
  3. 유저B가 치킨을 검색한다.
  4. 2에서 저장해놓은 데이터를 바로 유저에게 반환해준다

이것이 바로 Cache-Aside 패턴이다.
첫번째로 찾는 사용자는 속도가 느릴 수 있겠지만, 두번째부터 사용한 사용자들은 빠르게 반환 값을 얻을 수 있다.

물론 이것이 완벽한 해답이라고 볼 수는 없다.

왜냐하면 Redis에 저장되어있는 값들이 자동으로 삭제되기 전에 (Redis는 정보가 사라지는 것을 시간으로 정할 수 있다.)
새로운 데이터들이 DB에 추가되었으나 Redis에는 반영이 되지 않는다면?

유저는 새로운 정보가 포함되어있는 답을 받지 못하게 될 것이다.
그래서 동기화에 대하여 고민을 해볼 필요가 있다.

(이거때문에 장바구니 코드짜다가 고장났다.....)


두번째는 Write-Back 패턴이다.

이것은 배우지는 않았는데, 어느정도 느낌인지는 알 것 같다. 틀리다면 누군가 바로잡아줬으면 좋겠다

수많은 유저들이 회원가입을 넣었다 라고 가정을 하자

DB는 여러가지 입력을 해결하기 위하여 DB서버를 여러개를 나눠서 작업을 하거나, 다양한 작업을 하지만
그럼에도 감당할 수 없는 정보가 들어온다면 DB가 죽어버릴 것이다.

이 경우 일단! Redis쪽에 캐시로 임시저장을 해놓고 DB쪽으로 저장하는 방식을 이야기한다.

지금 설명한 것은 조금 극단적이라고 생각하는데 찾아보니 비슷하게 사용하는 것 같긴 하다. (위험해서 잘 안쓴다는 것 같긴 한데)

문제는 이것을 구현하는 것이 상당히 어려울 것 같다.
NOSQL을 사용한다면 그나마 괜찮을 것 같은데
SQL을 사용한다면 NOSQL로 저장되어있는 Redis의 정보를 다 분해를 해서 값에 알맞게 저장을 해야하고
이 또한 정보가 일치하지 않을 수도 있다는 위험성이 있어서 쉽게 활용하지는 못할 것 같다.

아무튼 Redis는 캐시를 활용하기 상당히 좋지만, 기술적으로 어렵다는 단점이 존재한다.
그렇지만! 만드는 것이 어렵다는 것이 좋기에 많은 회사에서 사용하고 있는 상태다.


그래서 지금 작업하고 있는 NestJs에서는 어떻게 쓰는지 조금만 적어놓으려고 한다.

자세한 활용법까지는 몰라서 좀 찾아봐야할 것 같다. 좀 재밌는 것 같아서 더 공부를 해볼 예정이다.

일단 깔아야하는 라이브러리다
redis
cache-manager-redis-store
cache-manager

1. appModule에 imports

import * as redisStore from 'cache-manager-redis-store';
import type { RedisClientOptions } from 'redis';
//
CacheModule.register<RedisClientOptions>({
      store: redisStore,
      isGlobal: true, //  이 설정을 넣으면 앱모듈 하단에 있는 모든 곳에서 레디스 사용이 가능해진다.
       socket: {
         host: 'localhost',
         port: 6379,
       },
    }),

2. 사용하고 싶은 위치에서 imports 나같은 경우에는 resolver 에서 사용했다.

import { Cache } from 'cache-manager';
import { CACHE_MANAGER, Inject } from '@nestjs/common';
//
  constructor( 
    @Inject(CACHE_MANAGER)
    private readonly cacheManager: Cache,
  ) {}
//  
  @Mutation(()=> Boards)
  async createBoards(
   @Args('createBoardInput') createBoardInput: CreateBoardsInput,
  ){
  await this.cacheManager.set("작성된 글",createBoardInput,{ttl: 50}) 
  // set을 쓰고 "작성된 글" 이라는 키값에 createBoardInput이 값으로 키:값 형식으로 들어감
  // ttl은 정보가 살아있는 시간이다. 50초를 적으면 50초동안 살아있고 미입력할 경우 끄기 전까지 유지된다.
  const check = await this.cacheManager.get("작성된 글")
  // 불러올때는 키값을 적어주면 된다.
  console.log(check)

이런식으로 활용이 가능하다.
문제는... nest에서는 지원을 안하는건지 이미 저장한 값을 수정하는 기능이 보이지가 않는다.

문서에도 그냥 set만 있고 지금 쓰는게 singlestore같은데 멀티를 쓰면 해결 할 수 있는 것인지는 조금 더 알아봐야하는데
어짜피 캐시인데 굳이 업데이트 하지말고 그냥 짧게 저장하고 새로 저장하는게 어때 라는 생각이 많이 들어서 뭐가 정답인지 모르겠다.

레디스는 충분히 공부해볼만한 가치도 있고 개인적으로 재밌어보여서 시간나는대로 계속 라이브러리라던가 명령어를 공부할 예정이다

profile
데이터를 다루고싶은 주니어 백엔드 개발자의 파란만장 성장 스토리 | 구직중!

0개의 댓글