비전공 국비충인데 이전에 프로젝트 했던거 혼자서 리팩터링하고 있음 

조회수랑 조회수 토대로 계산하는 로직 관련해서 내 의식의 흐름대로 개선한다고 했는데 

내가 제대로 생각한게 맞는지, 뭔가 잘못 이해한 개념이 있는지 확신이 안들더라고

지피티한테도 물어봤는데 자꾸 이상한 소리만 해서 별 도움은 안되는 것 같고..

물어볼 곳이 없어서 여기에 물어봄 

어떤 내용이라도 좋으니 조언해주심 감사..


배경
  • 백과사전 서비스
  • 단어를 조회하면 조회수를 1 증가시킴
    • 조회수 검증 로직 없음 (중복 조회수 허용)
    • 많이 찾아본 용어 목록을 제외하면 다른 로직에서 조회수는 사용되지 않음
      • 단순 보여주기용인 경우가 대부분이므로 정확성, 실시간성이 크게 중요하지 않음
  • 많이 찾아본 단어 목록
    • 24시간동안 조회수 증가폭이 큰 단어를 랭킹으로 1등부터 10등까지 목록으로 제공
  • 조회수는 단어 테이블 내부에서 관리
  • 단어의 개수는 많지 않음
  • DB로 mysql 사용
기존 동작
  • 단어 조회 시 업데이트를 통해 원자적으로 조회수 1 증가
  • 읽기 트랜잭션 종료 이전에 쓰기 트랜잭션이 동작하므로 쓰기 트랜잭션이 완료되어야 읽기 트랜잭션이 완료되어 단어를 조회할 수 있음
  1. 단어 단일 조회 요청이 발생한다
  2. 단일 조회를 위해 읽기 트랜잭션을 연다
  3. 조회한 내용을 토대로 조회수 업데이트를 위해 쓰기 트랜잭션을 연다
  4. 쓰기 트랜잭션에서 조회수를 기존의 값에서 1 증가시킨다
  5. 쓰기 트랜잭션을 닫는다
  6. 읽기 트랜잭션을 닫는다
  7. 단어 조회 내용을 반환한다
문제점
  • 많이 찾아본 단어 목록을 여러 곳에서 제공할 것이기 때문에 다른 단어보다 조회 이벤트가 많이 발생할 것이라고 판단
  • 단어 조회 시 update로 조회수를 1 증가시키기 때문에 조회 과정 도중 X-Lock 발생
  • 특정 단어에 조회 이벤트가 많이 발생한다면 로직상 중요하지 않은 조회수를 업데이트하느라 단어 조회가 늦어질 수 있다고 판단
아이디어
  • 조회 시 X-Lock이 필요하므로 발생한 문제라고 판단
  • 조회 시 X-Lock을 최소화하기 위해 조회 수 카운팅을 word 테이블에서 수행하지 않고 별도로 처리하고, 조회 이벤트가 적은 시점인 새벽 시간대에 조회 이벤트가 많이 발생하는 단어의 조회수를 업데이트하는 방향으로 진행
플로우

  • 단어 조회 이벤트 발생
  • 비동기적으로 redis sorted set에 ZINCRBY 명령어로 조회수 카운팅
  • redis에서 해당 단어가 많이 찾아본 단어 목록에 포함되어 있는지 상태를 파악하고, 다음과 같이 DB 조회수 업데이트 수행
    • 많이 찾아본 단어 목록에 포함된 경우 단어 테이블 내에 조회수를 증가시키지 않음
    • 많이 찾아본 단어 목록에 포함되지 않은 경우 단어 테이블 내의 조회수 1 증가 (업데이트)
  • 단어에 상태에 따라 반환할 조회수 처리
    • 많이 찾아본 단어 목록에 포함된 경우 단어 테이블 조회수 + redis sorted set 조회수를 더해서 반환
    • 많이 찾아본 단어 목록에 포함되지 않은 경우 단어 테이블 조회수를 그대로 반환
  • 많이 찾아본 단어 목록 주기가 끝난 경우 후처리 작업 진행
    • 많이 찾아본 단어 목록의 조회수 DB에 최신화
    • 많이 찾아본 단어 목록 랭킹 조회 갱신
    • 만료된 redis 데이터 삭제