사실 조회수 올리는 건 매우 간단하다.
Database 에서 Select 하기 전 , + 1 을 사용한 후 , 다시 저장 시키면 끝이다.
이렇게 하면 게시물을 조회할때마다 계속 연산을 하게 되므로 Database 에 부하를 주게 된다.
그래서 , 주로 In-Memory Database 에 조회수를 저장시키고 Cron Tab 을 사용하여 사용량이 낮은 시간대에 갱신하게 된다.
=> 하지만 , "게시물이 무수히 늘어나는 경우에 Redis 를 계속 사용하는게 괜찮을까?" 이에 대해서 고찰하는 글이다.
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 씩 증가
- 0.04K~0.07K 사이 , 0.06K 라고 가정
- Memory의 30~40% 까지 사용한다고 가정
( GPT : 16GB 메모리를 가진 서버에서 Redis를 운영한다고 가정하면, 12GB에서 14GB 사이의 Redis 데이터셋을 유지하는 것이 일반적으로 좋은 성능을 제공 )
- 16GB , 30% , 0.06K => ( 1638.4*3 ) / 0.06K ≈ 81920
- 64GB , 20% , 0.06K => ( 1638.4*3 ) / 0.06K ≈ 218453
=> 일반적인 프로젝트에는 상관없으나 , 대규모 사용자가 사용시 부족함.
- Redis 와 Memcached 지원
- Redis 가 좀 더 지원적인 기능이 많음.
- 2023.05.21 기준 요금 + Seoul Region 으로 Cost 계산함
- cache.m6g.2xlarge ( 8cpu , 26.04GiB , 10GB/bps ) - 23G 까지 가정
=> 23040.4kB / 0.06K ≈ 384006
0.726 USD/H => 522.72 USD/M
=> 38만 개의 게시글 조회수를 유지하기 위해선 68만원 대의 금액 발생!
- 조회수를 새로고침(F5)마다 증가시키는 건 매우 비효율적
- IP 또는 userId를 저장해서 구분!
- IP ( 121.131.128.53 ) 는 64 byte
- UUID ( 704a6ae2-9e94-4a48-b032-60f05b3a7ed3 ) 는 86 byte
=> 구현 시 , 매우 많은 memory 차지
- 우선 레딧은 couting 을 어떻게 하는지에 대한 글이다.
https://www.redditinc.com/blog/view-counting-at-reddit/- 네 가지 요구 사항 고려
1. 실시간 카운팅 ( 하루 or 시간 단위 집계 X )
- 각 사용자는 짧은 시간 동안 한 번만 세어야 함
- 표시된 수는 실제 집계와 몇 퍼센트 내외 일치
- 시스템은 Production 규모 실행 , 이벤트는 몇 초 안에 처리해야함
- 두 가지 방법 존재
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 요청 수행 )
- Memory 는 매우 비싼 자원!
- Redis 에 모든 정보를 넣기에는 효율이 너무 떨어짐.
- redis 에 들어있는 정보를 적절하게 갱신 , 교체해줘야함.
- Redis 는 HyperLogLog 를 지원
=> 따라서 , 나는 HyperLogLog 를 사용할 것이다.
HyperLogLog 에 대한 정보와 사용 Code에 대해서는 다음 내용에서 설명하겠다.