타임라인을 만드는 메커니즘이 두 서비스가 정 반대로 달라서 유명해.

프갤러들도 본인들이 직접 구현해본다고 생각하고 따라읽어도 재미있을 듯.

모바일 앱 이런거 다 빼놓고 만약에 모든 사용자가 웹으로만 서비스에 접근한다고 가정하고.

사용자A와 사용자B가 서로 친구 상태여서
사용자A가 글을 쓰면 사용자B의 타임라인에 그 글이 떠야한다고 요구사항을 정해보면,

프갤러들은 이거 어떤 방식으로 구현할것같아?

이걸 구현하는 방식은 크게 두가지로 나뉘어. push 방식이랑 pull 방식.

먼저 pull 방식부터 설명하자면 얘는 타임라인이 "내 친구들로만 필터링된 게시판"이라고 보는거야. 그래서 쿼리로 표현하자면 전체 게시물이 들어있는 테이블에 쿼리를 던지되 where 조건에 내 친구 목록을 붙이는거지.

페이스북이 이런 방식으로 구현이 되어있다고 알고 있어.

이 방식의 단점은 읽기 시점에 엄청 느리다는거. 사용자가 단순히 수십명이고 게시물이 몇백개 수준이다 하면 검색이 빠르게 되겠지만 사용자가 몇만 수준이고, 게시물이 몇백만, 몇천만 수준이라면? DB서버 한대로 운영한다면 얼마 못가서 터지겠지.
그래서 샤딩이란걸 해. DB 서버를 여러개 두고 나눠서 저장하는거지. 이렇게 분산환경으로 구성하면 DB서버 한대당 받는 부하는 줄겠지만 쿼리하기 이전 시점에 내 친구의 게시물의 어느 샤드에 있는지도 알아야 한다는 문제점이 있어. 그리고 이렇게 해도 성능이 잘 안나와서 DB서버 앞단에 캐시를 붙여서 자주 쿼리되는 데이터는 캐시에 싣어놔야겠지.

전에 듣기론 페이스북 같은 경우에 이런 용도로 mysql 새드랑 memcached가 몇천대 수준이라고 들었는데 지금은 어쩐지 모르겠다.

아무튼 이게 pull 방식이었고 push 방식은,

게시판같은 구조가 아니라 사용자 각각의 우편함이 있어서 사용자의 친구가 글을 올리면 그 사용지의 우편함에 꽃아주는 거야. 그 우편함을 열어서 데이터를 나열한게 타임라인이 되는거고.

트위터가 이런 방식으로 구현되어 있다고 알고 있어.

이 방식의 장점은 페이스북처럼 읽기 시점에 DB 부하가 크게 걸리지 않는다는 거지. 내 친구인지 where 조건을 걸어서 하나하나 질의를 하지 않고 그냥 내 우편함만 열어서 안에 있는 데이터를 그대로 들고 오면 되니까.

대신 단점은 공간복잡도를 엄청 잡아먹는다는 거지. 사용자가 글을 쓰면 딱 한번만 insert를 하면 되는게 아니라 자기 친구수만큼 insert를 하게 되니까. 그리고 그만큼 딜레이도 걸릴테고.
공간복잡도를 조금이나마 절약하기 위해서 글을 통째로 친구들 우편함에 넣지 않고 글은 따로 어디다 저장해놓은다음에 해당 글의 unique id를 친구들 우편함에 넣어주는 방법을 쓸 수 있는데 그래서 페이스북 방식보다는 느리겠지

친구의 수가 많으면 많을수록 느려지는데,
예전에 듣기로 미투데이 였나 이게 push 방식으로 되어 있었는데 친구수가 많은 경우에 글을 한번 쓰고 그 글이 모든 우편함에 다 넣어지는데 5분이 넘게 걸리는 케이스도 있었다고 해.
물론 이 모든 작업들은 비동기로 이루어지기 때문에 사용자가 글 등록 버튼일 누르고 5분을 기다리지는 않았지만 실시간성은 떨어진다는 단점이 잇지.

그리고 이 방식은 일반 관계형 데이터베이스에 적합한 방식은 아니야. 구현 할려면 어떻게 하겠지만 효율이 떨어지기 때문에 보통은 key-value 방식의 nosql을 많이 쓰게 되는데 mysql처럼 샤딩되고 분산환경에서 안정적으로 처리할 수 있는 nosql 구성하는 것도 어려운 부분 중에 하나일테고. 아무래도 nosql들이 rdb 보다는 안정성이나 확장성 면에서 떨어지니까.



프갤러들이라면 이 타임라인 기능을 어떻게 구현할 것 같아?

- dc official App