15 구글 드라이브 설계
문제 이해 및 설계 범위 확정
기능적 요구사항
- 파일 업로드, 다운로드, 파일 동기화, 알림
- APP, WEB
- 파일 암호화
- 파일 크기 10GB제한
- 가입자 5000만, DAU 1000만
- 파일 갱신 이력 조회
- 파일 공유
가정
- 모든 사용자에게 10GB 무료 저장공간 할당
- 매일 사용자가 2개의 파일을 업로드한다고 가정, 각 파일은 500KB
- 읽기 쓰기 비율은 1:1
추정
- 필요한 저장공간 총량 = 5000만 * 10GB = 500PB
- 업로드 API QPS = 1000만 * 2회 / 24*3600 = 240
- 최대 QPS = 240 * 2 = 480
비 기능적 요구사항
- 안정성 : 데이터 손실 없어야함.
- 빠른 동기화 속도
- 네트워크 대역폭 : 네트워크를 지나치게 많이 사용해서는 안된다.
- 규모 확장성
- 높은 가뇽성 : 일부서버 장애발생시에도 서비스는 사용가능해야한다.
개략적 설계안 제시 및 동의 구하기
API
- 파일 업로드
- 단순 업로드 : 파일 크기가 작을때
- 이어올리기(resumable upload) : 파일 사이즈가 크고 네트워크문제로 업로드가 중단될 가능성이 높을때
- 이어올리기 URL을 받기위한 최초 전송 -> 데이터 업로드 및 업로드상태 모니터링 -> 장애발생시 지점부터 업로드 재시작
- 파일 다운로드
- 파일 갱신 히스토리 API
한 대 서버의 제약 극복
- 이어올리기 URL을 받기위한 최초 전송 -> 데이터 업로드 및 업로드상태 모니터링 -> 장애발생시 지점부터 업로드 재시작
- 서버 장애시 안정성 및 가용성이 떨어지므로, 동일지역 혹은 지역성을 기반으로 파일시스템 다중화를 한다.
- 책에서는 AWS S3 사용
- 로드 밸런서 : 트래픽 분산, 장애서버 우회
- 웹서버 : 로드밸런서가 있으면 쉽게 확장 가능.
- 메타데이터 DB : 파일저장 서버와 분리하여 SPOF를 방지.
- 파일 저장소 : 데이터 다중화
동기화 충돌
- 사용자들이 한개의 파일을 업데이트하려고할때,
- 먼저 처리되는 변경은 성공, 나중에 처리되는 변경은 충돌. 첨부 참고
개략적 설계안
- 그림 15-10
- 블록저장소 서버 : 클라우드 환경에서 데이터 파일을 저장하는 기술, 파일을 여러 블록에 나누어서 저장하며, 각 블록에는 고유한 해시값이 할당된다.
- 해시값은 메타데이터 db에 저장된다.
- 각 블록은 독립적인 객체로 취급되며 클라우드 저장소 시스템에 보관된다. (예시에서는 S3)
- 재구성 하려면 블록을 원래순서대로 합쳐야한다.
- 드롭박스를 참고하여 한블록은 4MB로 한정한다.
- 아카이빙 저장소 : 오랫동안 사용되지않은 비활성 데이터를 저장하기 위한 컴퓨터 시스템
- 오프라인 사용자 백업큐 : 클라이언트가 미접속일때 파일의 최신상태를 큐에 두어 접속시 동기화되도록 한다.
상세 설계
블록 저장소 서버
- 큰 파일들은 업데이트가 일어날때마다 전체파일을 서버로 보내면 네트워크 대역폭을 많이 사용한다.
- 최적화
- 델타 동기화 : 수정이 일어난 블록만 동기화하는 방식
수정된 블록을 알아내는 방법은 ? 해시? 블룸필터?
- 압축 : 블록단위로 압축.
- 델타 동기화 : 수정이 일어난 블록만 동기화하는 방식
- 암호화 클라우드 저장소로 보내기 전에 암호화한다.
높은 일관성 요구사항
- 캐시에 보관된 사본과 db원본이 일치해야한다.
- db 원본에 변경사항 발생시 캐시가 모두 무효화된다.
- NoSQL은 ACID를 기본으로 지원하지않으므로, 지원되는 RDB를 사용하자.
메타데이터 데이터베이스
- 스키마 책 참고
업로드 절차
- 플로우 15-14 참고
다운로드 절치
- 플로우 15-15 참고
알림 서비스
- 롱폴링 : 단방향, 이벤트가 자주 발생하지 않으며, 적은양의 데이터가 오가므로 (드롭박스의 채택)
- websocket : 양방향,
저장소 공간 절약
- 중복 제거 : 두 블록이 같은 블록인지 해시값을 비교하여 판단한다.
- 지능적 백업 전략
- 보관해야하는 파일 버전 갯수에 상한.
- 중요한 버전만 보관
- 자주쓰이지 않는 데이터는 아카이빙 저장소로 옮긴다. (S3 glacier 는 S3보다 훨씬 저렴하다.)
장애처리
- 로드밸런서 장애 : 로드밸런서끼리 heartbeat를 주고받으며 상태를 모니터링하다가, 장애발생시 부 로드밸런서가 이어받아야한다.
- 블록 저장소 서버장애 : 다른서버가 미완료, 대기상태를 이어받아야한다.
- 클라우드 저장소 장애 : db를 다중화하여 다른 db에서 조회하도록한다.
- API 서버장애 : 무상태이므로, 로드밸런서에서만 떼어낸다.
- 알림 서비스 장애 : 드롭박스의 알림 서비스 서버가 관리하는 연결수는 1백만개가 넘는다.
- 다른 서버가 롱폴링을 한번애 100만개를 동시에 시작할수는 없으므로, 롱폴링 연결 복구는 상대적으로 느릴수있다.
- 오프라인 사용자 백업큐 장애 : 백업큐를 두자.
마무리
- 면접마다 요구되는 제약조건이 달라질테니, 그에맞는 설계를 진행하고, 결정과 선택한 기술들의 이면에 어떤 생각이 있었는지 잘 설명하자.
- 만약 클라이언트에서 클라우드 저장소로 바로 업로드한다면
-
분할/압축/암호화 로직이 클라이언트로 들어가야하는데, 클라이언트 해킹가능성도있고, 플랫폼별로(WEB/APP) 구현되어야한다.
-
- google drive resumable upload
308 Resume Incomplete
응답의Range : bytes=0-42
헤더가 어디까지 업로드되었는지 정보를 가지고있음.- 업로드 재시도 요청시 byte정보를 가지고 재요청.
503 Service Unavailable
이면 그냥 처음부터 재요청인듯?
- block/file/object storeage