issues
search
DevSprout
/
System-Design-Interview-2
가상 면접 사례로 배우는 대규모 시스템 설계 기초 2
3
stars
0
forks
source link
6장 광고 클릭 이벤트 집계
#7
Open
LOG-INFO
opened
3 months ago
HaeUlNam
commented
3 months ago
개략적인 추정
일간 활성자 수: 10억명 (10의 9승)
하루 시간을 초로 환산하면: 60
60
24 = 86400
QPS = 10의 9승 / 하루 10의 5 초 = 10,000
개략적인 추정할 때 실제론 86400초이지만, 올림해서 10의 5승으로 계산한 듯. 이 책처럼 시스템 아키텍처 면접을 보는 경우 하루가 86400초라는 걸 머리 속에 기억해두고 있으면 말하기 편하긴 할 듯
질의 API 설계
요구사항
지난 M분 동안 각 ad_id에 발생한 클릭 수 집계
지난 M분 동안 가장 많은 클릭이 발생한 상위 N개 ad_id 목록 반환
다양한 속성을 기준으로 집계 결과를 필터링하는 기능 지원
데이터 모델
RAW 데이터와 집계 데이터 모두 저장하는 것이 좋음. 원시 데이터는 데이터 양이 많기에 질의 데이터를 질의하는 것이 효율적. 오래된 RAW 데이터는 Cold storage로 옮기면 비용 절감을 할 수 있다.
Cassandra 사용 시 ad_id, timestamp(분 단위 or 시간 단위)를 primary key. 집계 데이터든 RAW 데이터든 이렇게 설정하면 하나의 노드에 쏠리는 핫 스팟을 최대한 피할 수 있지 않을까.
MapReduce(DAG)
Map node: 데이터 출처에서 읽은 데이터를 필터링하고 변환하는 역할을 담당
Reduce node(집계): ad_id별 광고 이벤트 수를 매 분 메모리에서 집계
Reduce node: 최종 결과로 축약. 집계 노드 각각이 광고 100 개를 리듀스 노드로 보낸다. 그럼 최종 리듀스 노드가 그 중 100개를 산출
Kafka Lag이 많이 쌓이지 않게 처리량 조절을 잘해야 할 듯
Spark 같은 거 쓰나?
minkukjo
commented
3 months ago
끄적끄적
광고 클릭 이벤트란?
광고 클릭 수를 추적하는 서비스
데이터의 정확도가 중요하며 온라인 광고가 얼마나 효율적이었는가를 추적하는 지표
지원자는 엣지 케이스에 대한 질문을 하는 것이 중요해보임
일간 능동사용자는 10억명, 여기서 QPS를 계산하려면 하루 10^5를 10^9 이벤트로 나누면 10,000 QPS라는 계산이 나옴
광고 클릭 이벤트는 개당 0.1KB이므로 0.1KB X 10억 => 100GB, 월간 저장 용량은 3TB 수준 (생각보다 적어서 놀라움)
데이터 모델
원시 데이터는 광고 당 Record를 하나씩 가져가는 방식, 저장 공간 효율도가 떨어진다.
집계 데이터를 보관한다면 ad_id를 기반으로 해서 클릭 분을 저장하고 count를 증가시키는 방식을 사용함
가장 좋은 방법은 둘 다 저장하는 것이 베스트
집계 데이터를 보관하는 방식은 같은 데이터에 Count를 올리는 방식을 사용할텐데, 동시성에 대한 얘기가 없는게 조금 의아함 ( 1분동안 누른걸 저장했다가 집계해주는 방식인걸까? )
쓰기 중심의 시스템이기 때문에 카산드라나 InfluxDB와 같은 시계열 DB를 사용하는 것이 바람직 함 (상대적으로 읽기 연산 빈도가 낮음) -> 결국 쓰기 중심의 서비스면 NoSQL은 관계형 데이터베이스보다 나은 대안이 될 수 있다는 것으로 받아들여짐
개인적인 의견이지만 여기선 시계열 DB가 적절한 대안이 될 것으로 보임
Kafka를 사용해서 비동기 방식으로 처리한다는 점이 인상 깊었음
여기서는 원시 데이터와 집계 결과를 프로듀싱하는 과정을 단위 트랜잭션으로 묶어서 발행하는 점이 인상깊었다.
맵리듀스(DAG) 프레임워크를 사용하는 점이 인상깊었는데, 스파크에서 이런 류의 DAG를 지원하나봄
https://medium.com/@ashutoshkumar2048/dag-in-apache-spark-a3fee17f7494
개인적으론 구체적으로 어떤 솔루션을 사용하는지도 나오면 좋았을텐데 그 부분은 조금 추상적이라 아쉬운 부분이었음
시간
이 서비스는 시간이 중요하기 때문에, 이벤트 시각과 처리 시간이 달라질 수 있는 문제가 있음
이를 해결하기 위해 워터마크라는 기술을 사용한다고 함 ( 내가 아는 워터마크는 로고 찍는건데... )
일반적으로 텀블링 윈도우는 윈도우 사이즈를 정해두고 단위 시간 별로 읽어가는 방식인데 이 방식은 누락이 발생할 수 있다.
워터마크는 각 윈도우 마지막에 추가적으로 윈도우 사이즈를 늘려서 집계하게 하는 기능이다. ( 근데 이걸 적절한 수치를 잡는게 가능할까? )
결국 워터마크를 쓰더라도 아주 늦게 들어오는 이벤트는 잡을 수 없음.
워터마크를 사용하면 정확도가 높아지지만 대기 시간이 늘어난다고 한다.
결국은, 텀블링 윈도우를 쓰다가 데이터를 보고 엔지니어들이 워터마크를 추가하는 방식이 되어야할 것으로 보임 ( 휴리스틱? )
전달 보장
정확도있게 보내려면 어떻게 해야하나?
Exactly once는 구현이 어려움.
이벤트가 누락되는 상황을 막기 위해 분산 트랜잭션 같은 것들을 고려해볼 수 있음
카프카를 쓰면 확장성 문제에 있어서 자유로울 수 있음
카산드라는 균등 해시 기법을 사용하므로 확장에 용이함
카프카는 결함 내성이 있어서 모든 메시지를 로그로 남기므로 원점부터 다시 시작시키면 복구가 가능하다.
다만 그렇게 하면 시간이 오래걸리므로, 시스템 상태를 스냅샷으로 저장하고 마지막 저장 상태부터 복구해나가는 방식을 사용한다고 한다.
요런 류의 서비스는 우리나라에서 일반적으로 "데이터 엔지니어"의 영역이긴 한데 굉장히 흥미로운 도메인이라고 생각함 ( 기회가 된다면 한 번 만들어보고 싶음 )
질의 API 설계
요구사항
데이터 모델
MapReduce(DAG)