본문 바로가기
카테고리 없음

230403 TIL(Redis에 담을 주문 Logic 설계)

by hbIncoding 2023. 4. 4.

0.  만들고자 하는 기능

  • 책 주문 log 를 Redis에 넣는다.
  • 매일 2:00am에 어떤 책이 얼마나 팔렸는지 세어서 ranking을 메긴다.
    • 하루 단위 일지 한 주 단위 일지는 바뀔 수  있음, 일단 구현이 잘 되었는지 확인하기 위해 하루 단위로 설계
  • 매일 2:00am에 Redis에 저장되어 있던 주문들을 DB의 jumoon table로 넣어준다.
  • 재고량이 부족한 책들은 다시 재고량을 채워준다.
  • 이 작업이 완료되면 Redis를 초기화 시키고 많이 팔린 책 1위부터 8위 까지 Ranking 만 남긴다.
  • 이 과정을 batch와 scheduler를 이용해 반복시킨다.

1.  Redis에 주문을 어떻게 담을 것인가?

 1) 주문에 필요한 정보들

  • 책 id : Long
  • 멤버 id : Long
  • 주문 수량 quantity : int
  • 주문 요청 시간 createAt : LocalDateTime.now();

 2) Redis에 담는 방법

  • Redis는 key : value 형태로 저장된다. 따라서 key를 무엇으로 가져갈지에 따라 서비스의 성능과 코드 복잡도가 달라질 것이다. 
  • value 안에 map을 넣어 변수를 명확히 구분해줄 수 도 있지만, 불필요한 변수가 많아짐으로 String으로 만든뒤 분리하도록 하겠다.

 2-1)메인 키를 bookid로 하는 경우

  • 괄호는 어떤 숫자 인지 알려주기 위한 것으로 실제로는 쓰지 않을 것이다.
"(bookid)2":{
	"(inventory)5",
	"(memberid)2,(quantity)1,(createAt)2023-03-29 22:56:29.159372",
    	"(memberid)4,(quantity)2,(createAt)2023-03-29 09:24:10.001737"
	}
  • 이 형태에서는 주문을 저장하고 책 id 별로 얼마아 팔렸는지 빠르게 계산이 가능하다.
  • 하지만 해당 멤버가 어떤 책을 주문했는지 알려면 Redis의 모든 key에 따른 데이터를 일일이 확인해주어야 한다는 치명적인 단점이 존재한다.

 2-2)메인 키를 memberid로 하는 경우

  • 괄호는 어떤 숫자 인지 알려주기 위한 것으로 실제로는 쓰지 않을 것이다.
"(memberid)2":{
	"(jumoonid)10000001,(bookid)2,(quantity)1,(createAt)2023-03-29 22:56:29.159372",
    	"(jumoonid)10000002,(bookid)4,(quantity)2,(createAt)2023-03-29 09:24:10.001737"
	}
    
"b2" : (총주문량)4,(재고량)6 
"b4" : (총주문량)3,(재고량)7
  • 어떤 멤버가 어떤 책들을 오늘 구매했는지 빠르게 파악이 가능하다.
  • 책들에 대해 얼마나 팔렸는지 또는 얼마나 남았는지를 별도의 key와 value로 저장해야한다.
    • 현재 프로젝트는  일정량의 재고량을 두고 차감하는 방식이고 매일 2am에 일정 량으로 채워진다.
    • 그렇다면 "b{bookid}" 라는 key에 팔린 책들만 남은 재고량 or 팔린 권수 를 저장한다.
    • 오늘 팔린 이력이 없다면 DB에서 재고량만 읽어와서 2am에 반영해주면 된다. (사실 반영 안해도 된다 어짜피 채워지기 때문에 하지만 실제 서비스에서는 잘 고려해줘야한다)
  • 어떤 책이 얼마나 팔렸는지 빠르게 파악이 가능하여 랭킹을 분석하는데 b로 시작하는 key만 긁어오면 된다.
  • 어짜피 주문 테이블로 데이터를 옮길때 다 긁어야하는건 변함이 없다.
  • 어쩌면 Redis 서버를 2개 만드는 것도 나쁘진 않을 수도?

2.  바꿀 코드

 1) 클라이언트 > 레디스

  • 책 주문 할 시 주문이 Redis로 넘어간다.
    • 앞서 언급한대로 주문은 "주문id":"주문데이터" 형식으로 들어간다.
    • 책 재고량은 "b책id":주문량 으로 넣거나 "b책id":"남은 재고량" 으로 넣어야한다.
    • 또는 "b책id":"재고량,주문량" 과 같이 스트링으로 나누어 넣어줘보자.
  • 주문을 취소 할 시 주문 Redis에 가서 주문을 취소한다.

 2) Redis>Redis , Redis > DB

  • 책 주문들을 확인해서 Ranking 을 확인한다.
  • 책 주문들을 확인하며 DB에 주문 기록을 넘긴다
  • 주문을 DB로 넘기고 부족한 재고량을 다시 채워준다.

 3) DB,Redis > 클라이언트

  • DB에서 이전 주문 기록과 Redis에서 오늘 주문 기록을 조회해서 보여준다.