Be-Developer

대규모 시스템 설계 기초 2 : 2 주변 친구

2. 주변 친구

1. 문제 이해 및 설계 범위 확정

기능 요구사항

  • 앱에서 주변 친구를 확인할 수 있어야한다.
  • 친구 목록은 n초 단위로 갱신

비기능 요구사항

  • 낮은 지연시간
  • 안정성 : 데이터 유실 허용
  • 결정적 일관성 : 데이터 저장소간 복제지연 n초정도는 허용된다.

개략적 규모 측정

  • DAU 1억
  • 동시 접속자 1억 x 10% = 1천만
  • 사용자는 30초마다 위치를 시스템에 전송
  • 위치정보 갱신 QPS = 1천만 / 30 = 334,000

2. 개략적 설계안 제시 및 동의 구하기

  • 로드밸런서 : 앱에서 바라보는 서버
    • RESTful API 서버 : 사용자 관리, 친구관리 , 인증 ,,
    • Websocket 서버 : (stateful) 각 클라이언트는 서버와 웹소켓 연결되어있다.
      • 유상태 서버 클러스터의 규모를 자동으로 확장하려면 서버 종료/추가시 연결을 조정할 로드밸런서가 있어야한다.
      • Redis 위치정보 캐시 : 사용자의 위치정보 TTL과 함께 저장
      • Redis pub/sub 서버 : 유저별로 채널을 가진다.
        • redis pub/sub은 채널을 만드는 비용이 아주 저렴.
        • pub : A 유저의 위치정보 갱신
        • sub : A 유저 위치정보 구독자 (접속된 친구들)

3. 확장전략

서버 확장

  • Redis 서버 비용 산정 : CPU가 병목이다.
    • 메모리 : 200GB(1억 주변친구 기능을 사용하는 유저수 x 20byte(구독자 한명 추적을 위해 필요한 추정치) x 100명 (유저당 구독자 추정치)) => 100GB 서버 2대
    • CPU : 1400만 / 100,000 (서버 한대가 동시 감당 가능한 구독자 수) = 서버 140대 - 1400만 = 334,000 (초당 위치정보 갱신 요청 추정치) * 40 (400명의 예상 친구중 인근에서 활성상태인 친구 10%) = 1400만건의 pub 이 발생.
  • Redis 분산 서버 사용시 키값 해시링으로 분산하면 서버 확장가능.

기능 확장

  • 친구가 많은 사용자 : 최대 친구수가 제한되어있으며, 단방향 팔로워는 고려하지않는다.
  • 주변에 존재하는 임의의 사용자 (친구아님)
    • 지오해시값별 pub/sub 채널을 두어 지오해시값 변경시 주변사용자들(구독자)에게 알림.

그외 대안

  • 서버비용이 많이드는 Redis 대신 경량 분산 어플리케이션인 Erlang 활용가능.
    • 웹소켓 서비스는 Erlang으로 구현, pub/sub을 Erlang 애플리케이션으로 대체

Erlang 알아보기