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 알아보기