피드 발행 API
피드 읽기 API: 뉴스 피드 서비스가 캐시에서 뉴스 피드 ID를 가져와서 랜더링
팬아웃: 어떤 사용자의 새 포스팅을 그 사용자의 친구들에게 전달하는 과정
push 모델: 포스팅 기록시 캐시에 바로 기록
pull 모델: 피드를 읽는 시점에서 캐시에 기록
- 장점: 비활성화 된 사용자, 서비스에 로그인하지 않는 사용자의 경우엔 해당 모델이 유리, 데이터를 친구 각각에 push 하는 작업 필요 X → hotkey 문제 발생 X
- 단점: 읽기 시간 증가
두 모델을 적절히 결합 → 대부분의 사용자에 대해서는 push 모델 사용(읽기 시간 감소는 매우 중요), 친구가 매우 많은 사용자는 pull 모델 사용, 안정 해시를 통해 요청과 데이터를 고르게 분산하여 hotkey 문제 감소
팬아웃 서비스 동작 과정
채팅 시스템의 데이터는 아래 두가지로 나뉨
일반 데이터는 데이터 안정성을 보장하는 RDBMS에 보관
채팅이력은 읽기/쓰기 연산 패턴을 이해해야함
- 채팅 이력 데이터는 매우 거대, 대부분 최근 메시지가 조회됨
- 이전 메시지로 점프, 메시지 검색 등 이전 데이터 접근도 가능해야함
- 1:1 채팅은 읽기 쓰기 비율이 1:1
→ 키-값 저장소
수평적 규모 확장이 용이
데이터 접근 지연시간이 낮음
RDBMS는 long tail에 해당하는 부분을 잘 처리하지 못함(index가 커지면 access 비용 증가)
대표적으로는 HBase, 카산드라 등이 사용됨
서비스 탐색 기능의 역할로는 클라이언트에게 가장 적합한 채팅 서버를 추천하는 것
이때 사용자의 위치, 서버의 용량 등이 고려됨
→ Apache Zookeeper를 주로 사용
A가 보낸 메시지가 사용자 B와 C의 메시지 동기화 큐에 복사
그룹이 크기 않으면 메시지를 수신자별로 복사해서 큐에 넣는 작업의 비용이 크기 않음
한 사용자는 여러 사용자로부터 온 메시지를 받아야 하므로, 동기화 큐는 여러 사용자로부터 오는 메시지를 받을 수 있어야 함
사용자 로그인: 로그인 시 접속상태 서버와 웹소켓 연결을 맺고, 저장소에 A의 상태를 online 으로 변경 및 최근 활동 시간 값 보관
로그인: 저장소에 A의 상태를 ofline으로 변경
접속 장애
- 간단한 방법은 연결이 끊어지면 ofline 상태로 표시하고 복구 시 online으로 변경하는 것
- 하지만, 짧은 시간 인터넷 연결이 끊어졌다 연결되는 모든 상황에서 상태 변경은 별로임
- heartbeat 검사를 통해 문제 해결 → 주기적으로 heartbeat event를 접속상태 서버로 보내고, 마지막 이벤트를 받은 지 x초 이내에 또 다른 heartbeat event를 받으면 온라인 유지
접속 상태 정보의 전송
접속상태 서버는 publish - subscribe 모델
이는 그룹의 크기가 작을 때 효과적, 동일 이벤트가 친구 수만큼 발생
그룹이 클 경우 사용자가 그룹 채팅에 입장하는 순간에만 상태정보를 읽거나 사용자가 친구의 접속상태를 수동으로 갱신하는 방식을 사용