Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

이메일 인증 - Redis Cache Manager 도입하기 #38

Closed
4 tasks done
oyoungsun opened this issue Oct 26, 2023 · 8 comments · May be fixed by #39
Closed
4 tasks done

이메일 인증 - Redis Cache Manager 도입하기 #38

oyoungsun opened this issue Oct 26, 2023 · 8 comments · May be fixed by #39

Comments

@oyoungsun
Copy link
Collaborator

oyoungsun commented Oct 26, 2023

이메일 인증 방법에 있어

  • Redis 사용하는 방법
  • Token DB(mysql)사용하는 방법
    중에 현재는 두번째 방법을 사용했었습니다.
    공부 목적으로 Redis로도 이메일 인증 캐시를 저장해보고 둘의 장단점을 비교해보고자 합니다
  • 레디스 설치 후 redis-server 띄우기
  • cache-manager 세팅
  • 캐시 매니저 구현
  • PostMan Test
oyoungsun added a commit that referenced this issue Oct 26, 2023
npm install [email protected]
npm install [email protected]
npm install [email protected]
세개는 버전 지정후 설치

- 커밋잘못해서 되돌리기 하고 다시 커밋합니다..
oyoungsun added a commit that referenced this issue Oct 26, 2023
@nestjs/common에 cache-manager를 찾지 못하는 문제를 해결했습니다
@oyoungsun
Copy link
Collaborator Author

oyoungsun commented Oct 26, 2023

/api/users/sendVerifyEmail 로 이메일 인증 요청 날린 직후

스크린샷 2023-10-27 075032

ttl=5분 지난 후
image

  • 장점 : DB table을 안써도 된다 (정보를 계속 남기지 않아도 됨)
  • 단점 (인지 장점인지..) : 한 이메일에 대해 여러번 인증 번호를 생성하면 가장 최근에 생성한 한가지만 저장된다. (HashSet 같음)
    • 이때문에 DB쿼리 날릴때 createAt으로 정렬->시간확인(between)>인증번호 검사의 절차가 생략된다

궁금한점 : 둘의 쿼리속도나 메모리 차지 등등에서 제가 인지하지 못한 성능 차이가 있을까요??

@oyoungsun
Copy link
Collaborator Author

궁금한점 추가:
redis로 이메일 인증 할때 인증번호가 일치하지 않으면 throw new NotFoundException('....'); 이런직으로 에러를 던지는 경우가 있던데 이걸 적용해보니 exception을 던지는 것과 @ApiBadRequestResponse 가 똑같이 콘솔/swagger의 response에 출력되고 서버는 계속 실행 됩니다

보통 exception이 일어나면 서버가 종료되지 않나요..?

@oyoungsun
Copy link
Collaborator Author

oyoungsun commented Oct 26, 2023

+) 해결하지 못한 문제..
.env파일에서 포트번호 4자리 숫자를 적어줬는데..
@module 에서 캐시모듈을 import시 env.REDIS_PORT를 사용하면
Type 'string' is not assignable to type 'number'. 에러가 나옵니다
😭😭😭😭😭😭😭(왜,,, ?)
.env에서 읽어올때 문자열로 읽어온다고 알고있는데 숫자로 형변환을 따로 해줘야 하는 걸까요?
image

++) 공식문서에서 Configuration 읽어보니까 port: process.env.DATABASE_PORT || 5432 이런 식으로 쓰는 것 같아요 !! 강의 들었을때도 이렇게 썼던것 같은,,
+++ ) 다시 읽어보니까 port: parseInt(process.env.REDIS_PORT, 10) || 6379, 이렇게 쓰는것 같은...

@oyoungsun oyoungsun reopened this Oct 26, 2023
@oyoungsun oyoungsun linked a pull request Oct 26, 2023 that will close this issue
@oyoungsun
Copy link
Collaborator Author

oyoungsun commented Oct 29, 2023

캐시의 이점

관련해서 블로그를 써보았습니다.

주의 : 이후 서버를 실행시킬때는 redis - server를 먼저 실행시켜야 합니다

...
mysql local로 쿼리 조회하는 경우랑
redis로 쿼리 조회하는 경우 PostMan으로 회원가입 응답시간 측정해보았는데
mysql이 더 빠릅니다
왜,, ?
(자세한내용은 블로그에)

@JaeMyeongSon
Copy link
Owner

궁금한점 추가: redis로 이메일 인증 할때 인증번호가 일치하지 않으면 throw new NotFoundException('....'); 이런직으로 에러를 던지는 경우가 있던데 이걸 적용해보니 exception을 던지는 것과 @ApiBadRequestResponse 가 똑같이 콘솔/swagger의 response에 출력되고 서버는 계속 실행 됩니다

보통 exception이 일어나면 서버가 종료되지 않나요..?

nest.js에서는 exception가 발생되더라도 서버가 종료되지 않습니다.
기본적으로 nest.js에서는 exceptions layer가 존재해서 예외 발생시 해당 계층에서 처리해주고 있습니다.
아래 문서 한번 확인 해보시면 좋을 것 같아요.

Exception filters: https://docs.nestjs.com/exception-filters

@JaeMyeongSon
Copy link
Owner

JaeMyeongSon commented Nov 6, 2023

/api/users/sendVerifyEmail 로 이메일 인증 요청 날린 직후

스크린샷 2023-10-27 075032 ttl=5분 지난 후 image
  • 장점 : DB table을 안써도 된다 (정보를 계속 남기지 않아도 됨)

  • 단점 (인지 장점인지..) : 한 이메일에 대해 여러번 인증 번호를 생성하면 가장 최근에 생성한 한가지만 저장된다. (HashSet 같음)

    • 이때문에 DB쿼리 날릴때 createAt으로 정렬->시간확인(between)>인증번호 검사의 절차가 생략된다

궁금한점 : 둘의 쿼리속도나 메모리 차지 등등에서 제가 인지하지 못한 성능 차이가 있을까요??

질문 내용이 정확하게 이해가 되진 않지만,
mysql에 인증번호를 저장하고 가져오는 로직을 Redis로 변경하였을때의 이점이 궁금하신거 같아요.

우선 앞서 설명해주신 것처럼 복잡한 쿼리 과정 없이 TTL로 간편하게 관리할 수 있다는 이점이 있고
redis는 mysql과 다르게 disk에 데이터가 저장되는 방식이 아니고
in-memory 방식이여서 데이터를 읽어오거나 쓰는데 훨씬 더 속도가 빠릅니다.

대부분의 경우에는 문제가 없겠지만,
규모가 커지는 경우에는 mysql 트랜잭션의 작업이 길어지고 많아져서 커넥션들이 락을 잡게되면
이후의 커넥션들이 대기를 하게됩니다 그러면 자연스럽게 커넥션 수가 부족해지면서 DB 쿼리가 느려지고 서비스 전체에 영향을 끼칠 수 있어요.

redis 같은 경우에는 커넥션 대기 상황이 없어지기 때문에 mysql만 사용했을때의 문제점들을 어느정도 완화해줄 수 있어요.

시간 여유 있으실때 Redis 동작원리 한번 찾아보시면 좋을것 같아요.

@JaeMyeongSon
Copy link
Owner

캐시의 이점

관련해서 블로그를 써보았습니다.

주의 : 이후 서버를 실행시킬때는 redis - server를 먼저 실행시켜야 합니다

... mysql local로 쿼리 조회하는 경우랑 redis로 쿼리 조회하는 경우 PostMan으로 회원가입 응답시간 측정해보았는데 mysql이 더 빠릅니다 왜,, ? (자세한내용은 블로그에)

mysql과 redis는 애초에 처리방식 자체가 다릅니다.
mysql은 디스크에 데이터를 저장하고 처리하는 반면에 redis는 메모리단에서 처리하기 때문에
db내에서 데이터 처리 속도는 redis가 훨씬 빠릅니다.

API 응답시간의 문제는 아마도 로직적인 문제거나 혹은 mysql은 local에 있고 redis는 cloud에 둔 상황이였다면 네트워크 통신 시간이 추가 되었을 수 있을 것 같아요

@oyoungsun
Copy link
Collaborator Author

알려주셔서 너무 감사합니다!! 큰 공부 되었습니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants