Skip to content

Latest commit

 

History

History
162 lines (102 loc) · 8.52 KB

15장_구글_드라이브_설계.md

File metadata and controls

162 lines (102 loc) · 8.52 KB

Intro

구글 드라이브 설계

구글 드라이브는 파일 저장 및 동기화 서비스로, 문서, 사진, 비디오, 기타 파일을 클라우드에 보관할 수 있도록 한다. 또한, 보관된 파일들을 컴퓨터, 스마트폰 등의 여러 디바이스에서 사용 가능하고 지인과 손쉽게 공유할 수 있어야 한다.


문제 이해 및 설계 범위 확정

구글 드라이브를 설계하는 것은 큰 프로젝트이기 때문에, 인터뷰를 통해 그 범위를 좁혀야 한다. 다음은 인터뷰를 통한 클라이언트의 요구사항이다.

  • 파일 업로드/다운로드, 동기화, 알람 기능
  • 모바일과 웹 모두 지원
  • 파일의 암호화
  • 10GB 크기제한
  • DAU 천만명

다음과 같은 요구사항을 바탕으로 다음과 같은 기능들에 대해 집중하여 구현하고자 하였다.

  1. 파일추가
  2. 파일 다운로드
  3. 파일 자동 동기화
  4. 파일 갱신 이력 조회
  5. 파일 공유
  6. 알림

기능적 요구사항 이외에 비기능적 요구사항으로는 다음과 같다.

  1. 안정성
  2. 빠른 동기화 속도
  3. 네트워크 대역폭
  4. 규모 확장성
  5. 고가용성

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

한대의 서버로 시작하여 점점 품질을 올리는 방향으로 소개한다. 먼저, 구글드라이브를 서버 한대에서 구현하는데 필요한 것은 다음과 같다.

  1. 업로드/다운로드를 처리하는 웹서버
  2. 데이터베이스
  3. 파일 저장소

파일 저장소

파일저장소의 경우 drive/ 디렉터리를 구성하고, namespace별로 파일을 저장하는 방식을 사용할 수 있다. 하지만 업로드되는 파일이 점점 많아지게 되는 경우, 파일 시스템은 가득차게 된다.

이를 해결하기 위한 방법으로 Sharding을 통한 서버 분산화를 사용할 수 있지만 넷플릭스나 에어비엔비 같은 회사는 아마존의 S3를 사용하여 규모 확장성, 가용성, 보안성을 확보한다고 한다. S3의 경우 같은 리전내 다중화나, 여러 리전에 걸친 다중화를 지원하기 때문에 여러 나라에서 사용하더라도 데이터의 보안성과 속도를 보장할 수 있다.

API

파일 업로드 및 다운로드에 필요한 API는 총 3가지 이다. 파일업로드 API, 다운로드 API, 파일 갱신 히스토리 제공 API 이다. 또한, 보안성을 유지하기 위해 SSL/TLS 소켓을 이용한 HTTPS 통신을 하는 방식으로 서버를 구성한다.

  1. 파일 업로드 API 본 시스템에서는 두가지의 업로드를 지원하는데
    • 단순 업로드 : 파일의 크기가 작은경우 사용된다.
    • 이어 올리기 : 파일의 사이즈가 크고, 네트워크상 문제가 되는 경우 사용된다. 데이터를 업로드하며 업로드 상태를 모니터링하고, 장애가 발생하면 해당 시점부터 업로드를 재시작한다.
  2. 파일 다운로드 API
  3. 파일 갱신 히스토리 API 파일 경로와 limit를 입력으로 받아 리스트를 제공한다.

이외에도, 로드밸런서를 추가한다면 웹이나 모바일에서 들어오는 요청이 분배가 가능해진다.

동기화 문제 해결

구글 드라이브와 같은 대형 저장소 시스템의 경우 때때로 동기화 충돌이 발생할 수 있다. 두명 이상의 사용자가 같은 파일이나 폴더를 동시에 업데이트하려고 하는 경우 충돌이 발생하게 된다. 본 책에서는 이 충돌을 해결하기 위해 먼저 처리되는 요청은 성공으로, 그 이후에 처리되는 요청은 충돌로 판정하여 처리한다.

이 외에도 충돌을 해결하는 방법이 여러개가 있으므로 관심이 있다면 찾아보길 바란다.


개략적 설계안

image

개략적 설계안을 바탕으로 블록 저장소 서버, 메타데이터 데이터베이스, 업로드 절차, 다운로드 절차, 알림서비스, 파일 저장소 공간 및 장애 처리 등에 대해 소개하겠다.


블록 저장소

정기적으로 갱신되는 큰 파일들은 업데이트가 일어날 때 마다 전체 파일을 서버로 보내게 되면 네트워크 대역폭을 많이 차지하게 된다. 이를 최적화 하기위한 방법으로는 크게 두가지가 있는데

  • 델타 동기화 : 파일이 수정되는 부분만 동기화 하는 방법
  • 압축 : 블록 단위로 압축해 두면 데이터 크기를 많이 줄일 수 있다.

해당 시스템에서 블록 저장소 서버가 하는 일은 파일 업로드에 관련한 힘든 일을 처리하는 컴포넌트이다. 파일 업로드가 이루어지면 파일을 블록 단위로 쪼개고, 압축하고, 암호화 하는 과정을 거친 후 S3와 같은 파일저장소에 저장하게 된다.

image

파일의 수정된 부분만 갱신하게 되므로 네트워크 대역폭 사용량을 감소시킬 수 있다.

높은 일관성 요구사항

파일을 분할하는 작업은 높은 일관성 모델을 기본으로 지원해야 한다. 같은 파일이 단말이나 사용자에 따라 다르게 보이면 안된다는 의미이다. 이런 부분은 당연하게 메타 데이터 캐시나 데이터베이스 캐시 계층 역시도 동일하게 적용되어야 한다. NoSQL을 사용할 경우 프로그램 로직안에 강한 동기화를 넣거나, 관계형 데이터 베이스를 사용하면 된다.

RDB를 사용할 경우, 메타데이터 데이터베이스의 스키마는 다음과 같이 설계할 수 있다.

image


업로드 절차

사용자가 파일을 업로드하면, 블록 저장소 서버와 API 서버에 병렬적으로 요청을 하게 된다. 해당 요청의 시퀀스 다이어그램을 살펴보면 다음과 같다.

image

다운로드 절차

파일 다운로드는 파일이 새로 추가되거나 편집되면 자동으로 시작된다. 즉, 클라이언트는 다른 클라이언트가 편집하거나 추가했다 라는 사실을 감지해야 한다. 감지하는 방법은 2가지 방법을 사용한다. 클라이언트가 접속중이라면 알림서비스를 통해 전달하고, 접속중이 아니라면 캐시를 통해 변경을 감지하고 새 버전에 대한 다운로드가 이루어 진다.

아래는 알림서비스를 통해 파일을 다운로드하는 시퀀스 다이어그램을 보여준다. image


알림 서비스

알림 서비스의 방식에는 이전장에서 소개한 것 처럼 롱 폴링방식과 웹소켓 방식 두가지를 사용할 수 있다. 하지만 웹소켓 방식의 경우 채팅서비스와 같이 양방향 서비스를 지원할 때 사용하는 것이 좋기 때문에 서버에서 클라이언트에게 변경에 대한 알림만을 전달하는 본 시스템에는 적합하지 않다. 따라서 본 시스템에서는 롱 폴링 방식의 알림 서비스를 이용하겠다.


저장소 공간 절약

파일의 갱신 이력을 저장하고, 안정성을 보장하기 위해서는 파일의 여러 버전을 여러 데이터 센터에 보관할 필요가 있다. 이 과정에서 모든 버전을 자주 백업하게 되면 저장공간이 빨리 소진 될 가능성이 있다.

이를 절약하기 위한 방법으로 본 책에서는 3가지 방법을 소개하고 있다.

  1. 중복 제거 : 중복된 파일은 계정 차원에서 제거하는 방법이다. 해시함수를 통해 중복여부를 판별한다.
  2. 백업 전략 선정 : 파일을 저장하는 백업의 버전 갯수를 한정짓거나, 자주 변경되는 문서의 경우 중요한 버전만을 저장한다.
  3. 데이터 아카이빙 : 몇달 혹은 수년간 사용되지 않는 데이터의 경우 좀더 요금이 저렴한 서버에 저장하는 방식을 사용할 수 있다.

장애 처리

해당 서비스에서 사용되는 모든 컴포넌트들이 장애가 발생할 가능성이 있다. 이런 부분을 모두 고려하여 각각의 컴포넌트를 분산화하여 사용하고, 장애가 생기는 경우 다른 정상 서버로 보내주는 작업을 수행해야 한다.