Skip to content

Design Cloud Storage Service

  • 파일 업로드 / 다운로드 / 동기화, 알림 기능 지원
  • 모바일 웹 / 앱 지원
  • 파일 암호화 지원
  • 파일 크기 10GB 제한
  • 높은 가용성 / 규모 확장성 / 안정성
  • 빠른 동기화 속도
  • 불필요한 네트워크 대역폭 사용 최소화
  • 전체 이용자 5,000만명 / DAU 1,000만명
  • 모든 사용자에게 10GB의 저장 공간 제공
  • 매일 각 사용자 평균 500kb 파일 2개 업로드
  • 읽기 쓰기 비율 1:1

클라우드 저장소 서비스를 구현하기 위해 위와 같은 요구사항을 만족해야할 때, 아래와 같이 추정할 수 있다.

  • 필요한 저장공간 총량: 5,000만명 * 10GB = 50PB
  • 업로드 API QPS = 1,000만명 * 2회 업로드 / 24 / 3600 = 231
  • 최대 QPS = 231 * 2(부하를 고려하여) = 460

클라우드 저장소 서비스를 구현하기 위한 기능을 API 단위로 나누어 정의하면 다음과 같다.

  1. 파일 업로드: 사용자가 파일을 업로드할 수 있는 API
    • /files/upload
    • 인자: {uploadType: 'normal' | 'resumable', data: File}(normal: 단순 업로드, resumable: 이어 올리기)
  2. 파일 다운로드: 사용자가 파일을 다운로드할 수 있는 API
    • /files/download
    • 인자: {path: 'path/to/file'}
  3. 파일 갱신 히스토리 API: 파일 갱신 히스토리를 조회할 수 있는 API
    • /files/list_revisions
    • 인자: {path: 'path/to/file', limit: 10}(limit: 히스토리 길이 최대치)

클라우드 저장소를 하나의 서버로 구현하게 되면, 결국 금방 용량이 부족해지고, 서버에 장애가 발생하면 서비스 전체가 중단될 수 있기 때문에 다른 방법을 고려해야 한다.

  • 데이터 샤딩: 용량 문제는 해결할 수 있지만, 데이터 유실 문제에 대한 대책 필요
  • AWS S3: 클라우드 서비스를 이용하면 용량 문제와 데이터 유실 문제를 해결할 수 있지만, 비용 발생

S3를 이용하면 비용이 발생하는 단점이 존재하지만, 아래와 같은 장점을 제공해주고 이미 많은 기업에서 사용하고 있기 때문에 S3를 이용하는 것이 좋다.

  • 확장성
  • 가용성
  • 보안

클라우드 저장소 서비스를 구현하기 위해 위에 언급된 데이터 저장소를 포함한 시스템을 설계하면 다음과 같다.

Cloud Store System

  • 블록 저장소 서버: 여러 블록으로 나뉜 파일을 클라우드 저장소에 업로드하는 서버
    • 각 블록에는 고유한 해시값이 할당되어 해시값을 메타데이터 데이터베이스에 저장
    • 각 블록은 독립적인 객체로 취급되어 클라우드 저장소에 저장
  • 클라우드 저장소: 블록 단위로 나뉜 파일을 저장하는 저장소(=S3)
  • 아카이빙 저장소: 오랫동안 사용되지 않은 비활성 파일을 저장하는 저장소
  • 로드밸런서: 네트워크 트래픽 분산 및 장애 발생 시 서버 우회
  • API 서버: 파일 업로드 외 다른 요청 처리(사용자 인증 / 파일 메타데이터 갱신 등)
  • 메타데이터 데이터베이스: 사용자 / 파일 / 블록 / 버전 등의 메타데이터 정보 관리
  • 알림 서비스: 특정 이벤트 발생 시 사용자에게 알림 전송(파일 추가 / 편집 / 삭제 등)
  • 오프라인 사용자 백업 큐: 최신 상태를 확인할 수 없는 오프라인 사용자의 파일을 넣어 접속 시 동기화 가능하도록 함

블록 저장소 서버 - 네트워크 대역폭 최적화

Section titled “블록 저장소 서버 - 네트워크 대역폭 최적화”

갱신되는 파일들이 업데이트 될 때마다 전체 파일을 서버로 보내게 되면 불필요한 네트워크 대역폭을 사용하게 되므로, 아래 두 가지 방법을 생각해볼 수 있다.

  • 델타 동기화 전략: 파일 수정 발생 시 전체 파일 대신 수정이 일어난 블록만 동기화
  • 압축 알고리즘: 블록 단위로 압축해 두어 데이터 크기를 줄임

클라우드 저장소 서비스는 사용자에 따라 다르게 보이면 안되는 강한 일관성을 보장해야 하기 때문에 메타데이터 캐시와 데이터베이스 계층에도 같이 강한 일관성 원칙이 적용되어야 한다.

  • 메모리 캐시: 보통 최종 일관성 모델을 지원하기 때문에 추가적으로 아래 사항 보장 필요
    • 캐시에 보관된 사본과 데이터베이스 원본 일치
    • 데이터베이스에 보관된 원본 변경 발생 시 캐시에 있는 사본 무효화
  • 데이터베이스: 강한 일관성을 보장하기 쉬운 관계형 데이터베이스 사용

메타데이터 베이스의 스키마를 간략히 나타내면 다음과 같다.

Metadata Database Schema

  • user: 사용자 기본 정보
  • device: 단말 정보
  • namespace: 사용자의 루트 디렉토리 정보
  • file: 파일의 최신 정보
  • file_version: 파일의 갱신 이력, 갱신 이력 훼손을 방지하기 모든 레코드를 읽기 전용으로 관리
  • block: 파일 블록에 대한 정보

파일 업로드 요청을 하게 되면 파일 메타데이터 추가와 파일을 클라우드에 저장소에 업로드하는 두 가지 요청이 병렬적으로 진행된다.

  • 파일 메타데이터 추가
    1. 새 파일 메타데이터 추가 요청
    2. 새 파일의 메타데이터를 데이터베이스에 저장하고 업로드 상태를 대기로 변경
    3. 새 파일이 추가되었음을 알림 서비스에 전송
    4. 다른 관련된 클라이언트에게 파일이 추가되었음을 알림
  • 파일 클라우드 저장소 업로드
    1. 블록 저장소 서버에 업로드 요청
    2. 블록 저장소 서버는 파일을 블록 단위로 쪼갠 뒤 압축 및 암호화하여 클라우드 저장소에 전송
    3. 클라우드 저장소에서 업로드 완료 후 완료 콜백을 API 서버로 전송
    4. API 서버에서 메타데이터 데이터베이스를 완료 상태로 갱신
    5. 알림 서비스는 다른 관련된 클라이언트에게 파일이 업로드되었음을 알림

수정 및 삭제도 위와 같은 방법으로 진행된다.

파일 다운로드는 파일이 새로 추가되거나 수정되면 자동으로 시작되는데, 수정 및 추가 감지는 아래 두 가지 방법으로 진행된다.

  • 접속 중인 경우: 알림 서비스가 클라이언트에게 직접 알림
  • 접속 중이 아닌 경우: 알림 서비스가 오프라인 사용자 백업 큐에 추가

클라이언트가 파일 다운로드가 필요함을 인지하면, 아래 절차로 진행된다.

  1. 알림을 확인한 클라이언트는 API 서버에 새로운 메타데이터 요청
  2. API 서버에서 메타데이터 데이터베이스에서 새 파일 메타데이터를 조회하여 클라이언트에게 반환
  3. 클라이언트는 블록 저장소 서버에 블록 다운로드 요청
  4. 블록 저장소 서버는 클라우드 저장소에서 블록을 다운로드하여 클라이언트에게 반환
  5. 클라이언트는 블록을 조합하여 파일을 재구성

파일 추가 및 수정에 대한 감지 및 알림을 위해 알림 서비스를 이용하는데, 알림 전송 방법으론 두 가지 정도를 고려해볼 수 있다.

  • 롱 폴링: 클라이언트가 서버에 연결을 유지하고 있지만, 서버가 응답을 보내거나 타임아웃이 발생할 때까지 연결을 유지하는 방식
  • 웹 소켓: 지속적인 통신 채널을 제공하여 양방향 통신 가능

양방향 통신이 필요하지 않고, 알림을 보낼 일이 빈번하지 않기 때문에 롱 폴링 방법을 채택하여도 무방하다.

파일 갱신 이력을 보존하고 안정성을 보장하기 위해선 파일의 여러 버전을 여러 데이터센터에 보관해야하는데, 그렇게 되면 저장용량을 많이 차지하게 된다.
이를 해결하기 위해 아래 보통 아래 세 가지 방법을 사용한다.

  • 중복 제거(de-dupe): 해시 값을 비교하여 중복된 파일 블록을 계정 차원에서 제거하는 방법
  • 지능적 백업 전략 도입: 보관해야하는 파일 버전 개수 상한 제한 / 업데이트 될 때마다 모든 버전을 저장하는 것이 아닌 특정 시점의 버전만 저장
  • 아카이빙 저장소: 오랫동안 사용되지 않은 파일을 아카이빙 저장소로 이관
  • 로드밸런서 장애: 부 로드밸런서를 구축하여 로드 밸런서끼리 상태 모니터링
  • 블록 저장소 서버 장애: 다른 블록 저장소 서버에서 미완료 혹은 대기 상태 작업을 가져와 처리
  • 클라우드 저장소 장애: 여러 지역에 다중화 시켜놓아 장애 발생 시 다른 지역에서 파일 조회
  • API 서버 장애: API 서버 다중화
  • 메타데이터 캐시 장애: 캐시 서버 다중화
  • 메타데이터 데이터베이스 장애
    • 주 데이터 서버 장애: 부 데이터베이스 서버 중 하나를 주 데이터베이스 서버로 승격
    • 부 데이터베이스 서버 장애: 다른 부 데이터베이스 서버로 조회
  • 알림 서비스 장애: 유지됐던 롱 폴링을 다른 서버로 전환 시 동시에 롱 폴링 시도하지 않도록 설정
  • 오프라인 사용자 백업 큐 장애: 백업 큐 다중화

Last updated:

Large-Scale System