티스토리 뷰

문제 상황 & 접근

  • DB 페이징 쿼리 기반으로 랭킹을 조회하는데 있어 성능이 좋지 못함
오프셋 기반 페이징이라 데이터가 많아질 수록 느려지기에 Redis를 통해 랭킹 시스템을 구축하고자 결정

 

적용

기존 쿼리

  • Pageable 를 통해 데이터베이스의 데이터를 정렬하여 오프셋 기반 페이징을 수행한다.
    • where 절의 조건은 랭킹에 포함할 멤버인지 확인하는 정도의 조건이다.
  • DB에서 순위를 매겨야 하기에 정렬은 불가피 했고, 서비스 요구사항에 의해 페이징도 필요했다.
    (요구사항이 아니더라도 많은 데이터가 있는 경우 페이징이 없다면 전체조회는 위험하다.)

 

 

  • Redis의 자료구조 중 하나인 Sorted Set은 member를 score 기반으로 정렬하여 저장한다.
    • 순위를 매겨 조회해야하는 경우 효과적이다.
    • 페이징과 같이 부분만 조회하는 기능도 제공하며, 그룹별 순위를 매겨 조회하는 기능 또한 가능하여 효과적으로 서비스 요구사항을 만족시키며 구현할 수 있을 것이라 기대했다.

Redis의 Sorted Set 활용

  • redisTemplate의 ZSet에 조회를 수행한다.

 

다른 정보 함께 저장하는 방법에 대한 고민

  • 랭킹 조회시 다른 정보들이 함께 조회되어야 했다.
    • ZSet 에는 여러 정보를 함께 저장하기엔 한정적이었다. 별도의 자료구조에 나머지 정보를 저장하는게 좋을 것이라 판단했다.
    • String 자료구조에 Json 형태로 변환하여 저장하였고, 조회할때 key 값을 통해 읽어오도록 구현하였다.
      • String 자료구조는 get으로 조회시 O(1) 의 시간복잡도로 처리 가능하기에 조회 성능을 기대하고 사용했다.
  • String 자료구조가 아닌 다른 방법은?
    • Hash 자료구조로 항목별로 key-value 형태를 통해 저장하는 방법을 생각해볼 수 있다.
    • Json 변환과정을 거치지 않아도 된다는 장점이 있으며 일부 개별 항목에만 접근할때 효과적이다.
    • 하지만, json을 dto로 변환한 이후 바로 응답 body에 사용하고 개별 항목 접근은 없었기 때문에 굳이 Hash에 요소 하나하나 저장하지 않아도 된다고 판단하여 String에 저장하기로 했다.

결론

  • DB에 5만 건의 row를 삽입한 이후 부하테스트를 통해 평균 Latency를 확인하였다.
  • 기존 랭킹시스템에 비해 4.58배 개선되었다.

(Before) DB Paging Query [120.44ms]

(After) Redis Sorted Set [26.26ms 4.58배 개선]

 

분석

  • 정렬되어 저장되는 자료구조를 사용하여 DB를 통해 매번 정렬하면서 부분만 조회하는 방법보다 더 나은 성능을 보였다.
  • 페이징 자체도 최적화하는 방법이 있다고 알고 있지만 그러한 방법 보다는 정렬하는 작업 또한 고려해 Redis Sorted Set으로 이전하여 성능을 높일 수 있었다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함