뉴스 피드(News Feed)는 팔로우하는 사람들의 게시물을 실시간으로 조합해 보여주는 소셜 미디어의 핵심 기능이다. Facebook, Instagram, Twitter가 대표 사례다.
피드 생성 방식
| 방식 | 설명 | 장점 | 단점 |
|---|
| 팬아웃-쓰기 (Push) | 게시시 팔로워 피드 즉시 업데이트 | 읽기 빠름 | 쓰기 비용 높음 (유명인) |
| 팬아웃-읽기 (Pull) | 피드 조회시 실시간 조합 | 쓰기 빠름 | 읽기 느림 |
| 하이브리드 | 일반인=Push, 유명인=Pull | 균형 | 구현 복잡 |
시스템 아키텍처
[게시물 작성]
사용자 → API 서버 → Post DB
→ 팬아웃 서비스
↓
팔로워 ID 조회
↓
피드 캐시 업데이트 (Redis)
feed:{user_id} = [post_id1, post_id2, ...]
[피드 조회]
사용자 → API 서버 → Redis 피드 캐시 → post_id 목록
→ Post 서비스 (상세 정보 조회)
→ 응답 조합 → 반환
python
import redis
import json
r = redis.Redis()
def publish_post(user_id: str, post_id: str):
"""게시물 발행 → 팔로워 피드 업데이트"""
followers = get_followers(user_id) # DB에서 팔로워 조회
pipe = r.pipeline()
for follower_id in followers:
feed_key = f"feed:{follower_id}"
# Sorted Set: score=timestamp, member=post_id
pipe.zadd(feed_key, {post_id: get_timestamp()})
# 피드 최대 500개 유지 (오래된 것 제거)
pipe.zremrangebyrank(feed_key, 0, -501)
pipe.expire(feed_key, 86400 * 7) # 7일 TTL
pipe.execute()
def get_feed(user_id: str, page: int = 0, per_page: int = 20):
"""피드 페이지네이션"""
feed_key = f"feed:{user_id}"
start = page * per_page
end = start + per_page - 1
# 최신순 (score 내림차순)
post_ids = r.zrevrange(feed_key, start, end)
# 게시물 상세 정보 병렬 조회
posts = [get_post(pid.decode()) for pid in post_ids]
return posts
관련 문서