LawDigest / Lawbag

LawDigest repo
1 stars 1 forks source link

[BE] Redis 필요성 #179

Closed GotPrgmer closed 6 months ago

GotPrgmer commented 6 months ago

1. 내용

1.TTL 때문에 레디스 써야한다는 말 -> (수정) 리프레시토큰을 만료시에 Null을 시키지 않아도 됨.(TTL 사용이 보안과 관련이 없음) -> 만료 후에 재발급 요청이 들어오게 되면 어차피 만료 유무를 체크하기 때문에 리프레시토큰을 초기화시키거나 삭제하지 않아도 된다고 생각.

  1. 조회 속도 리프레시 토큰 재발급 api는 일반 api요청시에 들어가는 프로세스이기에 빠르면 빠를수록 좋다고 생각. (인가를 빠르게 해줘야 사용자가 답답하지않다!)
  2. 병목현상 현재 조회수에 대한 동시성 이슈를 레디스로 해결하면 더 유리할것으로 생각함.

2. 의논 사항 및 기타

수정 사항 -> 현재 사용자별 리프레시토큰이 하나씩만 저장되는데 사용환경에 따라 토큰은 달라지므로 리프레시토큰을 여러개 받도록 해야함 고로 RDB로 새롭게 테이블을 만들던 레디스로 해야하던 하는데 이슈 토큰을 작성하는 현재 시점에서는 레디스로 구현하는게 좋을 듯 싶다.

ganjisriver commented 6 months ago
  1. 재발급 요청이 들어오게 될 때, 만료 유무를 체크하게 되는데, DB에 넣으면 안되는지 궁금합니다.

  2. 조회 속도는 당연히 빠르면 좋은데, 자주 사용하는 API 또는 추천 법안 기능을 만들게 되었을 때, 그것보다 우선순위가 높을지 고민이 되네요. 당연히 Redis를 쓰면 속도가 빠르지만, 한정된 메모리 자원에서 게다가 저희는 프리티어라 메모리가 1MB밖에 안되는 상황에서 모든 회원의 리프레시 토큰을 메모리에 저장하는 것은 비효율적이라고 생각합니다.

  3. 동시성 이슈와 병목현상은 자주 사용하는 API에 대한 정보를 Redis에 올려놓는 것은 일리가 있어 보입니다.

정리

결과적으로는 레디스를 사용하려는 주 이유가 리프레시토큰인데, 프리티어 EC2특성상 메모리가 매우 부족한 상황에서 리프레시토큰을 사용하는 근거가 부족하다고 생각합니다. 자주 조회가 될 다른 API 정보(예를 들어 최큰 조회수가 높은 법안, 의원 등에 대한 정보 등)가 우선순위가 높다고 생각하고, Refresh Token을 레디스에 넣는 것은 애매하다고 생각합니다.

GotPrgmer commented 6 months ago
  1. DB넣어도 되긴합니다 다만 그렇게 할 경우 디비쪽에서 트리거로 만료된 토큰들을 지워줘야할거같습니다.
  2. 프리티어 메모리 요량이 1GB라고 합니다.
  3. 리프레시토큰뿐 아니라 후에 동시성 문제 해결하려면 분산락을 많이 사용하는거 같더라구요. 그래서 도입하는게 좋지 않을까 싶습니다. 또한 레디스의 맥시멈 메모리용량을 조절할수도 있구요.
  4. 지금 리프레시토큰이 얼추 140바이트 정도 되는데 이는 1mb당 대략 7개의 리프레시토큰입니다. 인당 기기가 보통 2-3개정도 된다고치면 2-3명 정도가 사용할수있는데 500mb정도면 1500명이라서 괜찮지 않을까도 싶네요. <- 이 수치도 지금 얼마나 EC2의 메모리를 사용하는지 모르기때문에 측정해봐야알거같습니다.

정리

레디스 사용안하게 되면 장점

  1. 레디스만큼의 메모리 확보 단점 1.DB에서 리프레시토큰을 저장시 만료되는 토큰을 주기적으로 지워주는 트리거 생성 필요 2.api요청이 조금씩 느려짐과 동시성의 문제 해결수단이 한가지 사라짐

추가로 자주 사용하는 API의 정보를 리프레시토큰 대신에 레디스에 넣는것도 괜찮을거같습니다. 그렇게 해서 메모리 사용량을 측정해서 메모리가 조금 남는다 싶으면 리프레시로 들어가도 될것도 같구요.

GotPrgmer commented 6 months ago

추가로 ElastiCache사용하게 되면 EC2메모리 잡아먹진 않을거같긴합니다.

ganjisriver commented 6 months ago
  1. 만료된 리프레시토큰을 굳이 트리거로 지워줘야 하는지는 모르겠습니다. 리프레시토큰이 필요할 때, 리프레시토큰을 확인 해서, 만료되었으면 재로그인을 시키면 되는 형태의 로직이 나을 것 같다는 생각이 듭니다.
  2. 현재 젠킨스조차 돌릴 용량이 안되는 것이 1GB의 메모리 용량이라 스왑영역까지 할당한 상태입니다. 그래서 메모리를 아껴야 된다고 생각합니다.
  3. 분산락과 비슷한 기능은 DB에서도 충분히 가능한 것으로 알고있습니다. 동시성 문제를 해결하기 위한 방법으로 Redis를 사용하는 것이 아닌 Redis를 사용하면서 발생하는 동시성 문제를 해결하기 위한 것이 분산락이기 때문에, 인과관계가 다르다고 생각합니다.
  4. 가장 걱정되는 부분을 말씀해주셨습니다. 1500명의 회원 수가 단순히 회원 가입을 하면 이미 무려 저희 메모리의 절반인 500MB를 사용하는데, 이 회원들이 활성회원이 아니라 그냥 단순히 회원 가입을 하여 로그인을 하면, 리프레시토큰을 레디스에 저장하게 된다는 것이 걱정입니다. 주기적으로 유령회원을 정리한다는 방법이 있을 수 있지만, 이것이 리프레시 토큰을 레디스에 저장하는 이유로는 부족하다고 생각합니다.

정리

  1. 저는 레디스 사용을 반대하는 것이 아닌 리프레시 토큰을 위해 레디스를 사용하는 것에 반대입니다.

1-1. 1번에서 언급하였습니다. 1-2리프레시토큰을 DB에 저장한다고 하여 매 요청마다 리프레시 토큰을 확인하는 것이 아니기 때문에, api요청이 느려지는 효과는 없다고 봅니다.

중요한 것은 마지막에 언급하셨다싶이, 현재 트래픽에 따른 CPU, 메모리 사용률에 대한 측정을 하는 것이 중요한 부분으로 작용할 것 같습니다.


추가로 ElasticCahce에 대해 말씀해주셨는데, 찾아 보니, 프리티어로 포함이 되는 부분이네요. 좋은 의견인 것 같습니다. EC2 외부의 메모리를 사용해서 더 많은 메모리를 사용할 수 있게 되는 것인지, 외부노드라 네트워크 비용으로 시간이 오히려 더 걸리지는 않는지 등 생각해보면 좋을 것 같습니다.

GotPrgmer commented 6 months ago

정훈님이 정리하신 넘버링에 따른 답변입니다.

  1. 사용자는 하나의 리프레시토큰만을 사용하는게 아니라 브라우저별로 기기별로 리프레시토큰을 사용하게 됩니다. 따라서 한 사용자가 브라우저로 접속하고 핸드폰으로 또 접속하게 되면 리프레시토큰은 두개가 되는거죠. 그래서 만료된 토큰은 사용자가 로그인한 시도만큼 리프레시토큰이 생성되어야 합니다. 그러다보면 리프레시토큰이 많이 쌓이게 될거같아서 만료 토큰을 지워주자는 거였습니다.
  2. 아하 github action에서 이미 써버렸군요. 아하 그럼 더더욱 조심해야겠네요.
  3. 그렇군요. 동시성문제 해결 좀더 찾아볼게요.
  4. 현재 상태에서 자원사용률을 측정하고 ElastiCache를 생각해봐도 좋을거같네요.
ganjisriver commented 6 months ago

1.액세스토큰은 기기별로 엑세스토큰을 들고있는게 맞는데, 리프레시토큰을 서버 DB에서 관리하게 되면 굳이 여러개를 만들 필요가 없지 않나요? 어느 기기에서 접속하던 DB에 있는 리프레시토큰을 업데이트하는 로직으로 가면 되는 거 아닌가 생각을 합니다.

  1. github action이 먹는게 아니라 CI/CD 툴인 젠킨스만 돌려도 메모리 1GB 상태에서 돌릴 때, 서버가 맛이 갈정도로 메모리 1GB는 적은 용량임을 말씀드리고 싶었던 거였습니다.
  2. 자원 사용률이랑 부하 테스트도 이슈로 등록하면 좋을 것 같네요.
GotPrgmer commented 6 months ago
  1. 기기중 하나가 리프레시토큰 갱신하게 되면 나머지 기기에서 로그아웃되지 않나요? 쿠키로 리프레시토큰을 기기별로 주니까요. 그 리프레시토큰이랑 서버의 리프레시토큰이 매칭되어야 갱신되게 되어있어요 지금. 2.그렇군요 4.좋네요
GotPrgmer commented 6 months ago

Fix/refresh tokens #182 와 연관된 이슈