23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
<대규모 시스템 설계 기초> 스터디 여섯번째 글입니다!
저희 모임은 대략 3개월 간 진행되었고 이번 여섯번째 모임을 마지막으로 스터디가 종료되었습니다.
지난글
3회차 : OpenLab - 대규모 시스템 설계 기초 #3-1, #3-2
1회차
1장 사용자 수에 따른 규모 확장성
2장 개략적인 규모 추정
2회차
4장 처리율 제한 장치의 설계
3회차
5장 안정 해시 설계
6장 키-값 저장소 설계
4회차
7장 분산 시스템을 위한 유일 ID 생성기 설계
8장 URL 단축기 설계
5회차
9장 크롤러 설계
10장 알림 시스템 설계
6회차
11장 뉴스 피드 시스템 설계
12장 채팅 시스템 설계
벌써 마지막 스터디입니다. OpenLab으로 진행된 스터디는 총 6회차 모임으로 이번 스터디가 마지막이었습니다.
참고 도서에는 아직 남은 챕터들이 있었지만 11, 12장을 마지막으로 이번 스터디는 종료합니다.
11장은 "뉴스 피드 시스템 설계"로 우리가 익숙하게 알고 있는 X(구, 트위터), 인스타그램, 페이스북과 같은 서비스를 위한 시스템으로
책에서는 Post를 업로드하는 것과 팔로워들에게 업로드 된 Post를 전파하여 feed로 볼 수 있는 기능들에 대해 다루었습니다.
이때, 신규 Post가 업데이트 된 걸 팔로워들에게 전파하는 게 관건이었는데요. 유명인의 경우 팔로워 수가 매우 많기 때문에
모든 팔로워들에게 신규 Post가 업데이트된 걸 알리는 건 상당한 리소스를 소모하는 일입니다.
책에서는 이를 효율적으로 운영할 수 있는 시스템 구조에 대해 설명합니다.
12장은 “채팅 시스템 설계”에 관한 내용입니다. 학부 시절 흔히 구현해보는 일반 소켓 통신을 이용한 간단한 채팅 프로그램이 아닌, 대규모 채팅 시스템을 설계하는 방법을 다룹니다.
이 장에서는 웹소켓(WebSocket)을 활용해 다수의 서버에 연결된 클라이언트들 간의 메시지 전송을 어떻게 효율적으로 처리할 수 있는지 설명합니다.
한 포스트에 모든 내용을 담기엔 내용이 많아 일부만 정리하도록 하겠습니다.
뉴스 피드는 지속적으로 업데이트 되는 스토리들로, 사용자 상태 정보 업데이트, 사진, 비디오, 링크, 앱 활동 등을 포함
피드 발행 : 사용자가 스토리를 포싙ㅇ하면 해당 데이터를 cache와 DB에 기록, 새 포스팅은 친구의 뉴스 피드에도 전송됨
뉴스 피드 생성 : 뉴스피드는 모든 친구의 포스팅을 시간 흐름 역순으로 모아서 만든다고 가정
클라이언트가 서버와 통신하기 위해 사용하는 수단
HTTP 프로토콜 기반, 상태 정보를 업데이트 하거나 뉴스 피드를 가져오거나, 친구를 추가하는 등의 역할 수행
피드 발행 API
새 스토리를 포스팅하기 위한 API
HTTP POST 요청
POST /v1/me/feed
인자:
body : 포스팅 내용
Authorization header : API 호출 인증을 위해 사용
피드 읽기 API
뉴스 피드를 가져오는 API
GET /v1/me/feed
인자:
Authorization header : API 호출 인증을 위해 사용
사용자 : 모바일 앱 또는 브라우저에서 새 포스팅을 올리는 주체, POST /v1/me/feed API 사용
로드밸런서 : 트래픽을 웹 서버로 분산
웹 서버 : HTTP 요청을 내부 서비스로 중개하는 역할
포스팅 저장 서비스(Post Service) : 새 포스팅을 데이터베이스와 캐시에 저장
포스팅 전송 서비스(Fanout Service) : 새 포스팅을 친구의 뉴시 피드에 푸시, 뉴스 피드 데이터는 캐시에 보관하여 빠르게 읽어갈 수 있도록 함
알림 서비스(Notification Service) : 친구들에게 신규 포스팅이 올라왔음을 알리거나 푸시 알림을 보냄
사용자 : 뉴스 피드를 읽는 주체, GET /v1/me/feed API 사용
뉴스 피드 서비스 : 캐시에서 뉴스 피드를 가져오는 서비스
뉴스 피드 캐시 : 뉴스 피드를 렌더링할 때 필요한 피드 ID 보관
웹서버
클라이언트와 통신
인증이나 처리율 제한 등의 기능 수행
포스팅 전송(팬아웃) 서비스
새 포스팅을 친구 관계에 있는 모든 사용자에게 전달하는 과정
팬아웃은 두 가지 모델 존재
쓰기 시점 팬아웃
새로운 포스팅을 기록하는 시점에 뉴스 피드 갱신
장점
뉴스 피드가 실시간으로 갱신
뉴스 피드를 읽는 데 드는 시간이 짧아짐
단점
친구가 많은 사용자의 경우 친구 모두에게 뉴스 피드를 갱신하는데 많은 시간이 소요죔, 핫키(hotkey) 이슈
서비스를 자주 사용하지 않는 사용자의 피드까지 갱신해야 하므로 불필요한 리소스 낭비
읽기 시점 팬아웃
피드를 읽어야 하는 시점에 뉴스 피드 갱신 -> on-demand 모델
장점
비활성화된 사용자, 또는 서비스를 거의 이용하지 않는 사용자를 위한 리소스 낭비가 없음
핫키 문제도 발생하지 않음
단점
뉴스 피드를 읽는데 많은 시간이 소요됨
Graph DB에서 친구 ID 목록 획득
사용자 정보 캐시에서 친구들의 정보 획득, 사용자 설정에 따라 피드를 보여줄 대상을 필터링
친구 목록과 새 포스팅 ID를 메시지 큐에 넣는다.
팬아웃 작업 서버가 메시지 큐에서 데이터를 꺼내 뉴스 피드 데이터를 뉴스 피드 캐시에 넣는다. 뉴시 피드 캐시는 <포스팅 ID, 사용자 ID>의 순서쌍을 보관하는 매핑 테이블
채팅 시스템의 경우 클라이언트는 모바일 앱이거나 웹 애플리케이션
클라이언트는 서로 직접 통신하지 않는다
채팅 서비스 기능 제공
클라이언트들로 부터 메시지 수신
메시지 수신자(recipient) 결정 및 전달
수신자가 접속(online) 상태가 아닌 경우 접속할 때까지 해당 메시지 보관
채팅을 시작하려는 클라이언트는 네트워크 통신 프로토콜을 사용하여 서비스 접속
채팅 서비스의 경우 어떤 통신 프로토콜을 사용할 것인지 결정해야함
송신 클라이언트는 수신 클라이언트에게 전달할 메시지를 채팅 서비스에 보낼 때 HTTP 프로토콜 사용
채팅 서비스오 접속에는 keep-alive 헤더 사용 시 효율적
TCP 접속 과정에 발생하는 핸드셰이크 횟수를 줄일 수 있음
HTTP는 클라이언트가 연결을 만드는 프로토콜이며, 서버에서 클라이언트로 임의 시점에 메시지를 보내기는 어려움
서버가 연결을 만드는 것처럼 동작시키는 방법은 폴링(polling), 롱 폴링(long polling), 웹소켓(websocket) 등이 있음
폴링
클라이언트에서 주기적으로 서버에게 메시지가 있는 지 확인하는 방법
폴링 비용은 폴링을 자주하면 할수록 올라감
서버 자원이 불필요하게 낭비된다는 문제 있음
롱폴링
클라이언트는 새 메시지가 반환되거나 타임아웃 될 때까지 연결 유지
클라이언트는 새 메시지를 받으면 기존 연결을 종료하고 서버에 새로운 요청을 보내 모든 절차를 다시 시작
문제점
메시지를 보내는 클라이언트와 수신 클라이언트가 같은 채팅 서버에 접속되지 않을 수 있음
서버 입장에서는 클라이언트가 연결을 해제 했는지 알만한 좋은 방법이 없음
여전히 비효율적
웹소켓
서버가 클라이언트에게 비동기(async) 메시지를 보낼 때 널리 사용하는 기술
웹소켓 연결은 클라이언트가 시작
한번 맺어진 연결은 항구적, 양방향
처음에는 HTTP 연결이지만 특정 핸드셰이크 절차 후 웹소켓 연결로 업그레이드
웹소켓은 방화벽 환경에서도 잘 동작, 80, 443 HTTP 또는 HTTPS 프로토콜을 기본 포트로 사용
서버에서 연결을 효율적으로 해야함
회원가입, 로그인, 사용자 프로파일 등은 일반적인 HTTP 상에 구현해도 됨
채팅 시스템은 세 부분으로 정의 될 수 있음
무상태 서비스
상태유지 서비스
제3자 연동
무상태 서비스
로그인, 회원가입, 사용자 프로파일 표시 등을 처리하는 요청/응답 서비스
서비스 탐색 서비스는 클라이언트가 접속할 채팅 서버의 DNS 호스트명을 클라이언트에게 알려주는 역할
상태 유지 서비스
채팅 서비스는 각 클라이언트가 채팅 서버와 독립적인 네트워크 연결을 유지해야하기 때문에 상태 유지 필요
클라이언트는 보통 서버가 살아 있는 한 다른 서버로 연결을 변경하지 않음
제3자 서비스 연동
푸시 알림등을 위해 필요
동시 접속자 1M이라고 가정하고 접속당 10K의 서버 메모리가 필요하다면 10GB 정도의 서버 메모리로 커버됨
하지만 단일 서버로 서비스 제공시 SPOF 등의 이슈가 있기 때문에 서버 한대로 서비스를 하는 것은 위험
채팅 서버 : 클라이언트 사이에 메시지 중개
접속상태 서버 : 사용자의 접속 여부 관리
API 서버 : 로그인, 회원가입, 프로파일 변경 등 처리
알림 서버 : 푸시 알림 전송
키-값 저장소 : 채팅 이력 보관
저장소
채팅 시스템 데이터
사용자 프로파일, 설정, 친구 목록과 같은 데이터는 관계형 데이터베이스에 보관
채팅 이력 데이터는 키-값 저장소 사용
키-값 저장소는 규모확장에 용이함
데이터 접근 시간이 낮다
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.