시스템 디자인
사례 연구 / 실시간 시스템 / Chat System
학습 로드맵

채팅 시스템 설계

연결은 끊기고, 메시지는 재시도되며, 그룹은 갑자기 커집니다. 대화 ID를 순서와 샤딩의 단위로 정하고, 영속 저장·실시간 전달·오프라인 동기화를 분리해 설계합니다.

개념 이해면접 답변운영 관점진도 저장
30초 핵심 요약

웹소켓(WebSocket) 확인 응답(ACK)은 메시지 정본이 아닙니다. 메시지 서비스가 멤버십 버전 확인·멱등 저장·대화별 sequence 부여를 끝내고, 각 기기는 마지막 cursor 뒤 로그를 다시 읽어 ACK 유실과 재접속 누락을 복구합니다.

동시 접속 (설계 가정)100만 연결
일 메시지 (계산 결과)약 4억 건
순서 단위대화별 sequence
DESIGN DECISION · 설계 판단

ACK가 사라져도 여러 기기가 같은 대화 로그로 수렴하게 하려면?

예시 DAU 1,000만 명 설계 가정
예시 동시 연결 100만 계산 결과
예시 메시지 4억 건/일 계산 결과
최종 선택

대화별 durable log + 멱등 message ID + device cursor

게이트웨이는 연결만 유지하고 메시지 서비스가 멤버십 버전 확인·멱등 저장·대화별 sequence 부여를 끝냅니다. 각 기기는 마지막 cursor 뒤 로그를 다시 읽어 ACK 유실을 복구합니다.

선택 이유

  • 게이트웨이 재시작과 ACK 유실이 새 메시지나 새 sequence를 만들지 않습니다.
  • 여러 기기가 서로 다른 접속 시점에도 같은 대화 로그에서 누락 구간을 복구합니다.
  • 오래된 게이트웨이 멤버십 캐시가 떠난 사용자의 메시지를 저장하지 못하게 합니다.
포기한 대안

WebSocket ACK를 최종 전달 정본으로 사용

ACK는 연결 이동과 게이트웨이 재시작 중 사라질 수 있고 오프라인 기기의 누락 범위를 설명하지 못합니다. 영속 로그와 cursor가 복구 기준이어야 합니다.

감수한 단점

  • 멀티 디바이스 cursor와 전달·읽음 상태가 일시적으로 다를 수 있습니다.
  • 대형 그룹은 사용자별 inbox 복제가 쓰기 폭증을 만들 수 있습니다.
  • 대화별 단일 순서 파티션은 hot conversation의 처리량 상한이 됩니다.
01 · REQUIREMENTS

실시간성과 정합성을 분리한다

# 요구사항

발송 완료, 수신 단말 전달, 읽음은 서로 다른 상태입니다. 저장 성공을 먼저 확정하고 전달은 재시도 가능한 비동기 경로로 다룹니다.

F1연결 유지

접속 게이트웨이는 장시간 WebSocket과 heartbeat를 관리합니다.

F2대화별 순서

서버가 conversation마다 증가하는 sequence를 부여합니다.

F3재시도 안전성

같은 idempotency key의 저장은 기존 message_id를 반환합니다.

F4오프라인 복구

연결 이벤트가 아닌 영속 로그로 누락을 메웁니다.

02 · HIGH-LEVEL DESIGN

저장 경로와 전달 경로

# 아키텍처

접속 상태는 짧은 TTL 힌트이고, 메시지 로그가 정본입니다. 팬아웃·푸시·읽음 표시는 저장 결과를 소비하는 별도 경로로 둡니다.

1:1 메시지 전송과 오프라인 동기화 SVG DIAGRAM · 이벤트 전달은 재시도 가능
클라이언트, 접속 게이트웨이, 메시지 로그, 팬아웃과 수신자의 흐름발신 메시지가 연결 게이트웨이와 메시지 로그를 거쳐 온라인 팬아웃과 오프라인 inbox 동기화, 푸시와 수신 확인으로 전달되는 구조다.SenderWebSocketConnection Gatewaypresence · heartbeatMessage Logconversation sequenceFan-outonline eventInbox syncafter_sequencePush · receipts저장 ACK 뒤 전달 이벤트를 처리한다. 연결이 끊겨도 로그의 sequence는 남는다.
03 · MESSAGE FLOW

전송·전달·읽음을 분리한다

# 처리 흐름
1멱등 저장

같은 client-message-uuid는 기존 message_id와 sequence를 돌려줍니다.

2순서 부여

대화 ID 샤드 안에서 append-only 로그 순서로 sequence를 정합니다.

3온라인 팬아웃

presence TTL을 조회해 현재 접속 서버에 이벤트를 보냅니다.

4재접속 동기화

마지막 확인 sequence 이후를 읽어 gap을 메웁니다.

04 · TRADEOFFS

그룹 대화의 팬아웃 선택

# 트레이드오프

수신자가 많을수록 하나의 선택을 모든 대화에 고정하면 비용이나 지연이 급격히 커집니다.

선택
강점
주의점
적용 예
fan-out on write
개인 inbox 읽기가 빠름
대형 그룹에서 쓰기·저장 폭증
소규모 그룹
fan-out on read
쓰기 비용이 참여자 수에 덜 민감
읽을 때 집계 지연
대형 공지 채널
at-least-once
장애 복구·재시도 단순
message_id 중복 제거 필요
일반 채팅
대화별 순서
사용자 맥락 유지
전역 메시지 순서는 제공하지 않음
대화 타임라인
05 · FAILURE MODES

연결이 끊겨도 메시지는 남아야 한다

# 장애 대응
!WebSocket 접속 끊김

실시간 이벤트를 놓친 사용자가 메시지가 사라졌다고 느낍니다.

대응 · 재연결 뒤 after_sequence 동기화와 heartbeat timeout을 사용합니다.
메시지 중복 전달

재시도·ACK 유실로 같은 이벤트가 여러 번 도착합니다.

대응 · 저장과 UI에서 message_id 기준 dedupe합니다.
순서 뒤바뀜

서로 다른 경로의 이벤트가 순서를 바꿔 도착할 수 있습니다.

대응 · conversation sequence로 정렬하고 gap은 로그에서 재조회합니다.
핫 채널

대형 그룹의 fan-out lag가 일반 대화까지 밀어냅니다.

대응 · 대형 그룹 전용 파티션·배치 워커·속도 제한을 둡니다.
06 · OPERATIONS

보안·관측·비용

# 운영
영역
확인할 것
판단 기준
주의점
권한
대화 참여자 검증
API·구독 모두 membership 확인
presence만 믿지 않음
관측
연결 수, 재연결률, fan-out lag
대화·샤드별 p99
평균만으로 핫 채널을 숨기지 않음
비용
연결 메모리, 보관, 첨부파일
원본 약 400GB/일 (예시)
복제·보관 기간은 별도 계산
출처
RFC 6455·RFC 8030
검토일 2026-08-29
프로토콜과 제품 보장을 혼동하지 않음
면접 모드 · 추가 질문05:00
“한 대화의 메시지 순서는 지키면서, 천만 사용자의 연결과 대형 오픈 채널을 어떻게 함께 처리하시겠습니까?”
대화 단위 샤딩재접속 복구그룹 팬아웃
답변 구조 보기 4단계
  1. 1:1과 대형 그룹의 최대 참여자 수를 먼저 묻는다.
  2. 대화 ID를 메시지 순서와 샤딩의 단위로 정한다.
  3. 영속 저장 성공과 실시간 전달 성공을 분리한다.
  4. 재연결, 중복, 순서 gap, 핫 채널을 운영 지표까지 포함해 설명한다. 이번 선택: 대화 로그와 대화별 sequence를 정본으로 두고 연결·presence·inbox는 재생성 가능한 상태로 취급한다. 깨지는 신호: 재연결률, sequence gap, 멱등 키 충돌, 대화별 fan-out lag가 함께 오른다. 다음 검증: ACK 유실·게이트웨이 drain·멤버십 변경을 동시에 주입해 멀티 디바이스 cursor가 같은 로그로 수렴하는지 확인한다.
INTERVIEW ↔ PRACTICE · 면접과 실무의 차이

ACK 유실·재전송·멤버십 변경을 하나의 대화 로그로 수렴시키기

INTERVIEW · 면접

저장 성공, 실시간 전송, 기기별 확인을 서로 다른 상태로 설명합니다.

  • ACK 유실 뒤 같은 멱등 키가 기존 message ID를 반환하는 흐름을 답합니다.
  • 기기별 cursor와 대화 sequence로 누락을 복구합니다.
  • membership version을 저장 경계에서 다시 확인합니다.
PRACTICE · 실무

게이트웨이 drain과 재연결 storm에서 기기별 수렴을 검증합니다.

  • sequence gap·중복 표시·fan-out lag를 대화별로 관측합니다.
  • cursor 429 기기가 430·431을 빠짐없이 받는지 확인합니다.
  • 오래된 membership version 쓰기가 저장되지 않는지 시험합니다.
NEXT CASE STUDY결제 시스템 설계
EDITORIAL NOTES

작성·검토·참고 자료

콘텐츠 원칙
이 문서는 독립적으로 재작성한 한국어 학습 자료입니다. 사실과 학습용 설계 가정을 구분합니다.
작성·기술 검수
프로젝트 운영자가 직접 작성·기술 검토했습니다. 주제별 공식·1차 자료와 명시적인 설계 가정을 확인하며, 독립적인 제3자 검수가 아닙니다. 경력 범위와 검수 원칙 보기
최종 검토
예상 학습 시간
22분

참고 자료

  • RFC 6455: The WebSocket Protocol — 장시간 양방향 연결의 프로토콜 경계를 검토했다.
  • RFC 8030: Generic Event Delivery Using HTTP Push — 오프라인 수신자 알림이 메시지 정본 전달과 다른 경로임을 검토했다.
  • 본 문서의 규모·지연·비용 수치는 설계 가정 또는 계산 결과이며 제품 사실이 아니다.
  • 주제 구성 참고: liquidslr/system-design-notes (독립 재집필, 문장·이미지 미사용)

사실 오류·출처 정정은 문의·정정 페이지로 알려 주세요.