[WIL] 항해99 11주차 - 실전프로젝트(3)

Doyeon·2023년 4월 2일
1
post-thumbnail
post-custom-banner

어느덧 실전 프로젝트 3주차에 접어들었다.
매일 아침 해야할 일들을 정리하고 저녁 회의 때 진행사항을 확인하는데, 팀원들이 각자 맡은 부분을 잘 만들어줘서 서로 결과를 공유하는 시간이 기대된다.
주차장 예약과 입차 프로세스에 대한 코어 알고리즘을 구현하여 예약 안정성, 주차장 운영 효율성을 모두 잡을 수 있도록 남은 시간 열심히 또 해볼 것이다!
WIL에는 이번주 프로젝트 진행상황과 멘토링 피드백을 정리해서 기록해본다.


이번주 한 일

데이터 저장

  • 주차장 정보 크롤링 완료
  • 전국 주차장 정보 저장 완료 (약 78,000건)
  • 예약정보, 주차현황정보 저장 완료 (약 220만건)

예약 알고리즘

  • 1차 개선 예약 알고리즘 구현
  • 2차 개선 예약 알고리즘 구상

주차장 검색 및 조회

  • 주차장 검색 성능 개선
    • 주차장 검색 키워드 유사도 적용
  • 주차장 조회 성능 테스트
    • 인덱스 설정 쿼리 속도 측정
  • 레디스 캐시 공부
  • QueryDSL 적용

동시성 제어

  • 입차시 Redis 스핀락 적용(추후 변경 예정)

테스트코드

  • 입차 로직 테스트코드 작성

기타

  • https 적용
  • Chat GPT 코드리뷰 Workflow 추가

기술 공부 & 정리

  • QueryDSL
  • 인덱스

피드백 정리

레디스 캐시 적용

  • Hit rate : 캐시에서 요청된 데이터 중 캐시에 이미 저장되어 있는 데이터의 비율
    • (캐시에서 찾은 데이터 수 / 전체 요청 수) * 100
    • 보통 Redis 캐시에서 hit rate가 90% 이상인 경우, 캐시가 효율적으로 작동한다고 본다.
  • Cache hit : 캐시에 해당 데이터가 이미 저장되어 있는 경우
  • Cache miss : 캐시에 해당 데이터가 저장되어 있지 않은 경우
  • Key가 계속 달라지고 조건에 따라 달라지는 결과가 많을수록 Hit rate가 떨어진다.
  • 모든 주차장의 모든 시간대의 주차 가능 대수를 캐시에 넣는 것은 비효율적
  • 캐시를 적용할만한 부분이 무엇이 있을지는 좀 더 고민해볼 것

예약 알고리즘 - version 2

기본 설정

  • 기존 일반구획, 예약구획, 공통구획을 없앤다.
  • 일반차량이 입차할 때 즉시 예약처리한다. → 주차장에 들어오는 모든 차들은 예약차량이다.
    • 예약하지 않은 차량은 입차할 때 언제 나갈 것인지 시간을 입력 받는다. (1시간, 2시간, …)
    • 예약여부는 입차할 때 사용자가 입력한다고 가정한다. (입차 request에 예약여부 포함하여, 예약차량이 아닌 경우에만 언제 나갈 것인지 시간을 입력한다.)
  • (15분 전에 주차장 자리가 부족하면 예약자에게 알림을 보낸다. + 보너스)
  • (예약종료시간을 지키지 않았을 경우 페널티를 부과한다.)
  • (초기주차요금과 최종주차요금을 보여준다.)

테이블 설계

사전예약 로직

  1. 예약시간을 입력하면 다음 정보를 보여준다.

    • 선택시간 사이에 예약불가한 시간이 있다면 → 예약불가 시간대 출력
    • 선택시간 사이에 운영을 안한다면 → 운영시간 출력
    • init_charge 출력

    1-1. 선택시간 사이 예약불가 시간대 구하기

    • park_booking_by_hour에서 선택 시간대별 available 값이 있는지 확인
      • ex) 2023-04-02 10:00 ~ 13:00 시간을 입력했다면, park_booking_by_hour 에서 {date = 2023-04-02, time = 10}, {date = 2023-04-02, time = 11}, {date = 2023-04-02, time = 12}인 데이터를 찾는다.
      • 조건에 맞는 데이터가 없다면 → 해당 주차장에 예약자가 없으므로 해당 시간대는 예약이 가능하다.
      • 조건에 맞는 데이터가 있고 available > 0 이라면 → 해당 시간대에 예약 가능하다.
      • 조건에 맞는 데이터가 있고 available ≤ 0 이라면 → 해당 시간대는 예약이 불가하다.

    1-2. 선택시간 사이 운영시간 확인

    • 선택시간 사이에 운영하지 않는 시간이 있다면 isOperation = false 리턴

    1-3. 선택시간 사이 요금 계산 후 리턴

  2. 예약을 진행한다.

    1) park_booking_info 에 예약 데이터 생성

    • park_info_id, users_id, car_num, start_time, end_time 입력

    2) park_booking_by_hour , park_booking_slot 에 데이터 생성

    • park_booking_by_hour 에 start_time ~ end_time 사이 시간대별 데이터가 있는지 확인
      • ex) 2023-04-02 10:00 ~ 13:00 시간을 입력했다면, park_booking_by_hour 에서 {date = 2023-04-02, time = 10}, {date = 2023-04-02, time = 11}, {date = 2023-04-02, time = 12}인 데이터를 찾는다.
      • 해당하는 데이터가 없으면 park_info_id, date, time, available 새로 생성하여 저장 후, park_booking_slot 에 park_booking_by_hour_id, park_booking_info_id를 저장
      • 해당하는 데이터가 있으면 availbale 에서 1을 빼고, park_booking_slot 에 park_bookin_by_hour_id, park_booking_info_id를 저장

즉시예약 로직

예약하지 않고 주차장에 입차하려는 차량은 즉시예약 로직을 사용한다. 즉시예약은 비회원으로 예약된다.

  1. 출차시간을 입력한다. (ex. 1시간, 2시간 등 시간단위)

    • 선택시간 사이에 예약불가한 시간이 있다면 → 예약불가 시간대 출력
    • 선택시간은 예약이 가능하다면 → 예약 진행

    1-1. 선택시간 사이 예약불가 시간대 구하기

    • park_booking_by_hour에서 선택 시간대별 available 값이 있는지 확인
      • available이 null이라면 → 기존 예약자가 없으므로 해당 시간대는 예약이 가능하다.
      • available의 값이 있다면 → 값이 0 이하이면 해당 시간대는 예약이 불가하다.
  2. 즉시예약을 진행한다.

    1) park_booking_info 에 예약 데이터 생성

    • park_info_id, users_id, car_num, start_time(현재시간), end_time 입력

    2) park_booking_by_hour , park_booking_slot 에 데이터 생성

    • park_booking_by_hour 에 start_time ~ end_time 사이 시간대별 데이터가 있는지 확인
      • 해당하는 데이터가 없으면 park_info_id, date, time, available 새로 생성하여 저장 후, park_booking_slot 에 park_booking_by_hour_id, park_booking_info_id를 저장
      • 해당하는 데이터가 있으면 availbale 에서 1을 빼고, park_booking_slot 에 park_bookin_by_hour_id, park_booking_info_id를 저장

주의할 점

  • 동시성제어를 완벽하게 할 수 있어야 한다.

입차 알고리즘

입차 요청시 parkInfoId, carNum, parkingTime 을 입력받는다.

parkingTime 은 입차 후 몇시간을 사용할지 시간을 입력받는다.

사전예약차량이 parkingTime을 입력한 건은 무시된다.

사전예약 차량 입차 로직

  1. park_booking_info 에서 입차하려는 차량의 예약 ID를 찾는다.
  2. 입차하려는 시간에 주차중인 차량의 대수를 구한다.
    • park_mgt_info 에서 exit_time = null 인 수를 구하거나,
    • park_booking_slot 에서 카운트한다.
  3. 주차중인 차량 대수 < 총 구획 수 일때만 입차한다.

즉시예약 차량 입차 로직

  1. isBooking = false, parkingTime = 2 요청이 들어온대로 즉시예약을 진행한다.
  2. park_booking_info 에서 입차하려는 차량의 예약 ID를 찾는다.
  3. 입차하려는 시간에 주차중인 차량의 대수를 구한다.
    • park_mgt_info 에서 exit_time = null 인 수를 구하거나,
    • park_booking_slot 에서 카운트한다.
  4. 주차중인 차량 대수 < 총 구획 수 일때만 입차한다.
profile
🔥
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 4월 2일

화잇팅 =D

답글 달기