트위터는 사용자가 트윗을 작성하면, 이를 팔로우 중인 모든 사용자의 홈 타임라인에 전달하는 팬아웃 방식(Fanout-on-write)을 사용한다.
이는 팔로워가 로그아웃 상태여도 즉시 트윗이 전달되며, 팔로우한 사람의 모든 트윗을 가져오는 구조
트위터는 이를 효율적으로 처리하기 위해 Redis 클러스터를 활용한다.
트위터는 사용자의 홈 타임라인을 Redis 클러스터에 미리 저장한다.
사용자가 트위터를 방문하면 Redis 클러스터에서 해당 사용자의 홈 타임라인을 찾아 즉시 제공한다.
예를 들어, 관식이가 트윗을 올리면, 관식이를 팔로우하는 1,000명의 사용자 타임라인에 그 트윗의 ID가 하나씩 추가된다.
ㄴ> Fanout 방식Fanout-on-write(쓰기 시 팬아웃)
다시 말해, Write API로 트윗이 입력되면 Fanout Service가 해당 트윗 ID를 모든 팔로워들의 Redis 기반 타임라인 캐시에 삽입하고, 이후 타임라인 서비스가 이 캐시에서 트윗 ID 목록을 읽어와 실제 트윗 내용을 조회하여 홈 피드를 보여준다.
이로 인해, 데이터를 디스크에 직접 접근하지 않고도 수백만 명의 사용자에게 빠르게 홈 피드를 제공할 수 있다.
대규모 시스템 설계를 배우며 유연성 있게 설계하는 방향을 배웠다.
트위터의 경우 사용자의 읽기 빈도가 쓰기 빈도보다 훨씬 높기 때문에, 쓰기 시 부하를 늘리더라도 읽기 성능을 극대화하여 사용자 경험을 높였다.
또한, 각 사용자 홈 타임라인에는 최대 약 800개의 최신 트윗만 유지하며, 30일 이상 비활성화된 계정의 타임라인 캐시는 삭제하는 등 메모리 최적화가 적용되었다 (관련 자료 주소 -
[Twitter’s Tough Architectural Decision - Denny Sam]( Twitter’s Tough Architectural Decision))그러나 팔로워 규모가 수천만에 달하는 유명 계정에는 이 방식을 그대로 적용하기가 어려운데...
만약 일론머스크같이 수억 명의 팔로워를 가진 유명인이 트윗을 한다고 가정해보자.
짧은 시간 안에 1억 명 이상의 팔로워에게 트윗을 전달해야 하므로, 기존 Fanout 방식으로는 심각한 지연과 문제가 발생할 수 있다.
발생한 대표적인 문제
트위터는 하이브리드 팬아웃 방식(Fanout-on-read)을 도입
이 방식에서는 유명인이 트윗을 올리더라도 아무에게도 미리 팬아웃하지 않고, 일반 사용자가 홈 타임라인을 요청하거나 새로고침할 때만 다음과 같은 절차를 수행
유저 타임라인 : 특정 사용자가 작성한 트윗의 리스트
홈 타임라인 : 내가 팔로우한 사람들의 트윗을 모아 보여주는 피드
사용자가 여러 유명인을 팔로우 중이면, 각 유명인의 트윗을 반복적으로 병합한다.
트윗 병합은 요청 시마다 실시간으로 수행되며, 트위터는 이때 Earlybird라는 실시간 검색 인덱스 시스템을 이용해 최신 트윗을 빠르게 찾고 병합한다.
Earlybird는 트위터의 실시간 검색 인덱스 시스템으로, 타임라인을 빠르게 구성하는 데 핵심적인 역할을 한다.
일반 사용자의 트윗은 기존처럼 Redis 캐시에 미리 저장하고, 유명인의 트윗만 Fanout-on-read로 처리하는 하이브리드 구조로 운영되어, 전체적인 성능과 확장성 문제를 효과적으로 해결했다.
(더 자세한 이야기는 해당 링크로 - High Scalability Home)