조회수 증가하기 - With Redis -1-

영슈·2023년 5월 22일
0
post-thumbnail

사실 조회수 올리는 건 매우 간단하다.
Database 에서 Select 하기 전 , + 1 을 사용한 후 , 다시 저장 시키면 끝이다.
이렇게 하면 게시물을 조회할때마다 계속 연산을 하게 되므로 Database 에 부하를 주게 된다.
그래서 , 주로 In-Memory Database 에 조회수를 저장시키고 Cron Tab 을 사용하여 사용량이 낮은 시간대에 갱신하게 된다.
=> 하지만 , "게시물이 무수히 늘어나는 경우에 Redis 를 계속 사용하는게 괜찮을까?" 이에 대해서 고찰하는 글이다.

Redis Data Structure

Redis 구조에 대해 전부 살펴보진 않았고 , 프로젝트에 핵심적으로 사용되는 부분만 Redis-cli 를 활용해 확인했다.

  • Redis 에서 0부터 9999 까지는 공유 상수로 사용된다.
    => server.h 에서 OBJ_SHARED_INTEGERS 10000 로 설정 되어있음
    ( 메모리를 사용하지 않고 공유하여 사용해 메모리 낭비 방지 )
  • 64bit 기준 long 인 9223372036854775807 를 넘지 않을시 int형
    => 사실상 넘기 불가능
  • memory usage 로 확인시 , 48 byte 사용
  • used_memory_human 확인시 하나당 0.04K ~ 0.07K 씩 증가

Assumption

  • 0.04K~0.07K 사이 , 0.06K 라고 가정
  • Memory의 30~40% 까지 사용한다고 가정
    ( GPT : 16GB 메모리를 가진 서버에서 Redis를 운영한다고 가정하면, 12GB에서 14GB 사이의 Redis 데이터셋을 유지하는 것이 일반적으로 좋은 성능을 제공 )
  1. 16GB , 30% , 0.06K => ( 1638.4*3 ) / 0.06K ≈ 81920
  2. 64GB , 20% , 0.06K => ( 1638.4*3 ) / 0.06K ≈ 218453
    => 일반적인 프로젝트에는 상관없으나 , 대규모 사용자가 사용시 부족함.

AWS ElastiCache Redis

  • Redis 와 Memcached 지원
  • Redis 가 좀 더 지원적인 기능이 많음.
  • 2023.05.21 기준 요금 + Seoul Region 으로 Cost 계산함
  1. cache.m6g.2xlarge ( 8cpu , 26.04GiB , 10GB/bps ) - 23G 까지 가정
    => 23040.4kB / 0.06K ≈ 384006
    0.726 USD/H => 522.72 USD/M
    => 38만 개의 게시글 조회수를 유지하기 위해선 68만원 대의 금액 발생!

Distinction

  • 조회수를 새로고침(F5)마다 증가시키는 건 매우 비효율적
  • IP 또는 userId를 저장해서 구분!
  • IP ( 121.131.128.53 ) 는 64 byte
  • UUID ( 704a6ae2-9e94-4a48-b032-60f05b3a7ed3 ) 는 86 byte
    => 구현 시 , 매우 많은 memory 차지

View Counting at Reddit

  • 우선 레딧은 couting 을 어떻게 하는지에 대한 글이다.
    https://www.redditinc.com/blog/view-counting-at-reddit/
  • 네 가지 요구 사항 고려
    1. 실시간 카운팅 ( 하루 or 시간 단위 집계 X )
    1. 각 사용자는 짧은 시간 동안 한 번만 세어야 함
    2. 표시된 수는 실제 집계와 몇 퍼센트 내외 일치
    3. 시스템은 Production 규모 실행 , 이벤트는 몇 초 안에 처리해야함
  • 두 가지 방법 존재
    1. 선형 확률론적 카운
    => 카운트 대상 지합 커질수록 선형적으로 커짐
    1. HyperLogLog(HLL) 기반 카운팅
      => 집합 크기 비례해 선형적 성장하지만 , 정확도는 떨어짐
  • Reddit 은 Redis 기반 HLL 을 사용
  • Reddit 의 Logic
    Kafka => Nazar => Kafka => Abacus => cassandra Database
    1. Nazar : Event 를 읽은후 Couting 되어야 하는지 여부 결정 위해 만든 규칙 집합 거친 후 , Bool Flag 전달
    2. Abacus : 실제 조회수 Couting , Client에게 표시할 Count 생성
    ( 게시글 존재시 , PFADD 요청 수행 <->
    존재하지 않을시 , HLL 카운터 , 원시 카운트 숫자 유지용 Database 사용 & SET 요청 수행 )

Conclusion

  • Memory 는 매우 비싼 자원!
  • Redis 에 모든 정보를 넣기에는 효율이 너무 떨어짐.
  • redis 에 들어있는 정보를 적절하게 갱신 , 교체해줘야함.
  • Redis 는 HyperLogLog 를 지원
    => 따라서 , 나는 HyperLogLog 를 사용할 것이다.

HyperLogLog 에 대한 정보와 사용 Code에 대해서는 다음 내용에서 설명하겠다.

profile
https://youngsu5582.life/ 로 블로그 이동중입니다~

0개의 댓글