11. 뉴스 피드 시스템 설계
1. 문제 이해 및 설계 범위 확정
중요한 기능은?
뉴스 피드 페이시에 새로운 스토리 올릴 수 있어야함.
친구들이 올리는 스토리도 볼 수 있어야함
스토리 전시는 단순 시간 흐름 역순
한명의 사용자는 최대 5000명의 친구를 가질 수 있음.
트래픽 규모 : 10million DAU
피드에 이미지, 비디오를 포함할 수 있음.
2. 개략적 설계안 제시 및 동의 구하기
뉴스 피드 API
POST 필드 발행 API
포스팅 저장 서비스
포스팅 전송 서비스
알림 서비스
GET 피드 읽기 API
뉴스 피드 서비스
3. 상세 설계
웹서버
인증.
처리율 제한.
특정 기간 동안 한 사용자가 올릴 수 있는 포스팅의 수 제한
포스팅 전성 서비스
쓰기 시점 fan out (push model)
쓰기 시점에 팬아웃.
새로운 포스팅이 기록되는 순간, 뉴스 피드를 갱신
포스팅이 완료되면 해당 사용자의 캐시에 해당 포스팅을 기록
장점 :
새 포스팅이 기록되는 순간 뉴스피드가 이미 갱신 (실시간)
친구 목록에 있는 사용자에게 즉시 전송
단점 :
친구가 많은 사용자의 경우, 친구 목록을 가져오고 그 목록에 있는 모든 사용자의 뉴스피드를 갱신하는데 까지 많은 소요될 수 있음 (핫키 )
서비스를 자주 이용하지 않은 사용자의 피드까지 갱신해야하므로 낭비
읽기 시점 fan out
on demand (pull model)
사용자가 본인 홈페이지나 타임라인을 로딩하는 시점에 새로운 포스트를 가져오게됨
장점 :
비활성화 사용자, 서비스에 거의 로그인하지 않는 사용자의 경우, 이 모델이 유리
핫키 문제도 발생 x
단점 :
뉴스 피드를 읽는 데 많은 시간이 소요될 수 있음.
결정
대부분의 유저는 push model (쓰기 시점 fan out)
그렇지만 친구나 팔로어가 아주 많은 사용자의 경우, pull model (읽기 시점 fan out)
안정 해시 를 통해 요청과 데이터를 고르가 분산하여, 핫키 문제를 줄여본다.
어떻게?
대규모 분산 시스템에서 데이터 파이셔닝 할 때, 서버의 추가/삭제가 발생해도 데이터의 이동을 최소화하고, 부하를 균등하게 나누기 위함.
4. 마무리
피드 발행 모델 (Fan-out Model)
Push 모델 (Fan-out on Write): 글을 쓸 때 팔로워들의 피드 큐(Queue)에 미리 넣어두는 방식 (읽기 속도 빠름, 쓰기 부하 큼)
Pull 모델 (Fan-out on Read): 피드를 읽을 때 팔로우한 사람들의 글을 가져와 합치는 방식 (쓰기 부하 적음, 읽기 속도 느림
하이브리드: 일반 유저는 Push, 연예인 같은 인플루언서는 Pull 방식을 섞어서 사용
데이터 저장소 및 스키마 설계
어떻게 저장할 것인가?
RDBMS (MySQL/PostgreSQL): 유저 프로필, 설정 등 정합성이 중요한 메타데이터
NoSQL (Cassandra/DynamoDB): 피드 데이터
이유: 엄청난 쓰기 작업량, 높은 가용성 필요, 복잡한 Join 불필요
Graph DB (Neo4j) : 복잡한 친구 추천이나 관계도 탐색이 필요할 때 사용 (선택적)
샤딩키?
User ID 기준 샤딩: 특정 유저의 피드 데이터를 한 샤드에 몰아넣음. 읽기 효율 좋음.
Hot User 문제 발생 가능
캐시를 통해 해결?
핫키 해결을 위한 전략
복제 (Read Replica / Copy)
키에 난 수 붙이기 (Write 분산 유도)
IU_post라는 키 하나를 IU_post_1, IU_post_2... 로 쪼개서 저장 읽을 때 합쳐서 읽음
Local Cache (Caffeine, Ehcache) -- L1 캐시
Last updated