유튜브 설계

코딩하는스님·2022년 2월 23일
1
  • 유튜브 시스템은 언뜻 보기에는 간단해보인다. 컨텐츠 창작자가 비디오를 올리고 시청자는 재생한다. 하지만 이면에는 다양한 기술들이 집약되어 있다.
  • 유튜브에 대한 놀라운 통계 지표
    • DAU: 20B
    • 매일 재생되는 비디오 수 : 50B
    • 미국 성인 가운데 73% 이용중
    • 50M의 창작자
    • 유튜브 광고 수입은 19년도 기준 $15.1B이며, 18년 대비 36퍼센트 증가
    • 모바일 인터넷 트래픽의 37%를 점유
    • 80개 언어로 이용 가능

문제 이해 및 설계 범위 확정

  • 유튜브는 다양한 기능들이 있다.
    • 댓글
    • 비디오 공유
    • 좋아요
    • 재생목록에 추가
    • 채널 구독

이 모든 기능들을 짧은 면접에서 설계할 수 없기 때문에 적절한 질문을 던지는 게 중요하다.

질문

  • 어떤 기능이 가장 중요한가? 비디오 업로드, 시청
  • 지원하는 클라이언트? 모바일 앱, 웹 브라우저, 스마트TV
  • DAU? 5M
  • 사용자가 평균 소비하는 시간? 30분
  • 다국어 지원? YES
  • 비디오 해상도? 모든 비디오 종류와 해상도 (이 부분은 뒤에서 다루어지지 않는 듯)
  • 암호화? YES (비디오의 암호화?)
  • 파일 크기 제한? maximum 1GB
  • 클라우드 서비스 이용? 활용하면 좋다. CDN까지 구축하는 건 힘들 수 있다.

빠른 비디오 업로드
원활한 비디오 재생
재생 품질 선택 기능
낮은 인프라 비용
높은 가용성과 규모 확장성, 그리고 안정성
지원 클라이언트: 모바일 앱, 웹브라우저, 그리고 스마트 TV

개략적 규모 추정

  • DAU : 5M
  • 1인당 하루 평균 5개의 비디오 시청
  • 10%의 사용자가 하루에 1비디오 업로드
  • 비디오 평균 크기는 300MB
  • 비디오 저장을 위해 매일 새로 요구되는 저장 용량 = 5M 10% 300MB = 150TB
  • CDN 비용
    • CF의 경우 1GB당 $0.02
    • 따라서 5M 5 video 0.3GB * $0.02 = $150,000

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

  • 설계안에서는 CDN, BLOB storage를 사용한다.
    • 왜 CDN, storage는 설계하지 않나요?
    • 설계하고자하는 것은 유튜브 시스템이지 시스템 구성요소가 아니다.
    • 규모확장이 쉬운 CDN이나 storage를 만드는 것은 설계의 논점 밖이다.

  • 사용자 단말 : 컴퓨터, 모바일 폰, 스마트 TV 등
  • CDN : 비디오는 CDN에 저장한다. 그리고 재생 버튼을 누르면 CDN 서버로부터 스트리밍이 이루어진다.
  • API 서버 : 비디오 스트리밍을 제외한 모든 요청은 API서버가 처리한다.
    • 피드 추천
    • 비디오 업로드 URL 생성 (CDN에 올릴 수 있는 권한이 있는 URL)
    • 메타데이터 데이터베이스와 캐시 갱신
    • 사용자 가입 등

비디오 업로드 절차

  • 사용자 : 컴퓨터나 모바일 폰, 혹은 스마트TV를 이용하여 시청하는 이용자
  • 로드밸런서 : API서버에 부하를 분산하는 역할
  • API서버 : 비디오 스트리밍을 제외한 다른 모든 요청을 처리한다.
  • 메타데이터 데이터베이스 : 비디오의 메타데이터를 보관한다. 샤딩과 다중화를 적용하여 성능 및 가용성 요구사항을 충족한다.
  • 메타데이터 캐시 : 성능을 높이기 위해 빋오 메타데이터와 사용자 객체는 캐시한다.
  • 원본 저장소 : 원본 비디오를 보관한 대형 BLOB시스템 (DB에 비디오를 저장한다?!!!)
  • 트랜스코딩 서버 : 비디오 트랜스코딩은 비디오 인코딩이라 부르기도 하는 절차로, 포맷을 변환하는 절차다. (MPEG, HLS 등). 단말 혹은 대역폭 요구사항에 맞추기 위해 필요한 절차이다.
  • 트랜스코딩 비디오 저장소 : 트랜스코딩이 완료된 비디오를 저장하는 BLOB 저장소
  • CDN : 비디오를 캐시하는 역할을 담당한다. 사용자가 재생버튼을 누르면 비디오 스트리밍을 CDN을 통해 이루어진다.
  • 트랜스코딩 완료 큐 : 비디오 트랜스코딩 완료 이벤트를 보관할 메시지 큐이다. (트랜스 코딩이 오래걸리기 때문에 작업 큐에 넣어서 처리하는 듯)
  • 트랜스코딩 완료 핸들러 : 트랜스코딩 완료 큐에서 이벤트 데이터를 꺼내어 메타데이터 캐시와 데이터베이스를 갱신한 작업 서버

비디오 업로드


1. 비디오를 원본 저장소에 업로드한다. (비디오 URL을 따로 클라이언트에 알려줄듯?)
2. 트랜스코딩 서버는 원본 저장소에서 해당 비디오를 가져와 트랜스코딩을 시작한다.)
3. 트랜스코딩이 완료되면 아래 두 절차가 병렬적으로 수행된다.

3a. 완료된 비디오를 트랜스코딩 비디오 저장소로 업로드한다.
3b. 트랜스코딩 완료 이벤트를 트랜스코딩 완료 큐에 넣는다.
	3a.1. 트랜스코딩이 끝난 비디오를 CDN에 올린다.
    3b.1. 완료 핸들러가 이벤트 데이터를 큐에서 꺼낸다.
    3b.1.a, 3b.1.b. 완료 핸들러가 메타데이터 데이터베이스와 캐시를 갱신한다.
  1. API 서버가 단말에게 비디오 업로드가 끝나서 스트리밍 준비가 되었음을 알린다. (비동기적으로? 푸시?)

비디오 메타데이터 갱신 (비디오 URL, 크기, 해상도, 포맷, 사용자 정보)

원본 저장소에 파일이 업로드되는 동안, 단말은 병렬적으로 비디오 데이터 갱신 요청을 API서버에 보낸다. 이 요청에 포함된 메타데이터에는 파일 이름, 크기, 포맷 등의 정보가 들어있고, 이 정보로 메타데이터 캐시 및 데이터베이를 업데이트한다.

비디오 스트리밍

유튜브에서 재생버튼을 누르면 전체를 다운로드할 때까지 기다리지 않고, 스트리밍이 바로 시작된다.

  • 다운로드는 비디오 전체를 단말에 내려 받는 것을 말한다.
  • 스트리밍은 원격 비디오로부터 지속적으로 비디오 스트림을 받는 것을 말한다.
  • 스트리밍 프로토콜
    • MPEG-DASH
      • Moving Picture Experts Group
        • Dynamic Adaptive Streaming over HTTP
    • Apple HLS
      • HTTP Live Streaming
    • Microsoft Smooth Streaming
    • Adobe HTTP Dynamic Streaming (HDS)
    • 프로토콜을 정확히 이해할 필요는 없지만, 프로토콜마다 비디오 인코딩 및 플레이어가 다르기 때문에 이를 고려해야된다.

비디오는 단말에서 가장 가까운 CDN Edge에서 비디오를 받아온다. CDN이기 때문에 전송지연은 매우 낮다.

상세 설계

개략적 설계에서 다루었던 업로드와 스트리밍 부분의 최적화를 다루어본다.

비디오 트랜스코딩

비디오는 보통 단말에서 특정 포맷으로 저장된다. 이를 다른 단말에서도 순조롭게 재생하기 위해서는 다른 단말과 호환되는 비트레이트와 포맷으로 저장되어야 한다.

  • 비트레이드 : 비디오를 구성하는 비트가 얼마나 빨리 처리가 되어야 하는지를 나타내는 단위이며 높을수록 일반적으로 고화질 비디오이다.

비디오 트랜스코딩의 중요성

  • 가공되지 않은 비디오는 저장공간을 많이 차지한다. (압축 포맷을 사용하여 줄일 수 있다.)
  • 상당수 단말과 브라우저는 특정 비디오 포맷만 지원한다. 호환성을 위해서 여러 포맷으로 저장해 놓는게 좋다.
  • 사용자에서 끊김 없는 서비스를 제공하기 위해서 대역폭이 충분하지 않은 사용자에게는 저화질의, 대역폭이 충분한 사용자에게는 고화질 비디오를 보내는 것이 바람직하다.
  • 모바일 단말에서 네트워크는 수시로 상태가 달라지기 때문에 끊김없는 서비스 제공을 위해 자동으로 화질을 변환해줄 필요가 있다.

인코딩 포맷

  • 컨테이너 : 메타데이터를 저장하는 .avi, .mov, .mp4와 같은 확장자
  • 코덱 : 비디오 화질을 보존하면서 파일 크기를 줄일 목적으로 고안된 압축 알고리즘, H.264, VP9, HEVC등이 있다.

유향 비순환 그래프 (DAG) 모델

비디오를 트랜스코딩하는 것은 컴퓨팅 자원을 많이 사용하는 작업이다. 그리고 창작자들은 각자 자기만의 비디오 프로세싱 요구사항을 갖고있다.

  • 워터마크 작업
  • 썸네일 작업
  • 화질 설정 등

따라서 비디오 프로세싱 파이프라인을 제공하면서 처리 병렬성을 높이기 위해서 추상화를 도입한다. 페이스북에서는 DAG를 도입하여 작업을 단계별로 배열하고, 순차적 혹은 병렬적으로 작업이 실행될 수 있도록 한다.

원본 비디오는 비디오, 오디오, 메타데이터 세부분으로 나뉘어 처리된다.

비디오

  • 검사 : 비디오의 품질을 체크하고, 손상은 없는지 체크한다.
  • 비디오 인코딩 : 비디오를 다양한 해상도, 코덱, 비트레이트 조합으로 인코딩하는 작업
  • 썸네일 : 사용자가 업로드한 이미지나 비디오에서 자동추출된 이미지로 썸네일을 만든다.
  • 워터마크 : 비디오에 대한 식별정보를 이미지 위에 오버레이 형태로 띄워 표시하는 작업

비디오 트랜스코딩 아키텍처


전처리기
1. 비디오 분할 : 비디오 스트림을 GOP로 나눈다.

- GOP : Group of pictures, 특성 순서로 배열된 frame 그룹 각각의 GOP는 재생가능하고, 수 초 정도의 길이를 가진다. 브라우저들이 GOP 단위 분할을 지원하는데 지원하지 않는 브라우저를 위해 전처리기가 비디오를 분할한다.
  1. DAG 생성 : 클라이언트 프로그래머가 작성한 설정에 따라 DAG를 만들어낸다.
- 다운로드 -> 트랜스코딩
  1. 데이터 캐시 : 분할된 비디오의 캐시, 전처리기는 안정성을 위해 GOP와 메타데이터를 임시저장소에 저장한다. 인코딩이 실패하면 임시저장소의 데이터를 활용하여 인코딩을 재개한다.

DAG스케쥴러
DAG 그래프를 단계로 나누어 자원 관리자의 작업 큐에 집어넣는다.

1단계에서는 비디오, 오디오, 메타데이터를 분리한다.
2단계에서는 비디오를 인코딩하고, 썸네일을 추출한다. 그리고 오디오를 인코딩한다.

자원 관리자

  • 작업 큐 : 실행할 작업이 보관되어 있는 PQ
  • 작업 서버 큐 : 작업 서버의 가용 상태 정보가 보관되어 있는 PQ
  • 실행 큐 : 현재 실행 중인 작업 및 작업 서버 정보가 보관되어 있는 큐
  • 작업 스케쥴러 : 최적의 작업/서버 조합을 골라 작업서버가 작업을 수행하도록 지시하는 역할

작업 관리자는 작업 큐에서 높은 우선순위의 작업을 꺼낸다.
해당 작업을 작업하기에 적절한 작업서버작업서버 큐에서 고른다.
작업 스케쥴러는 작업 서버에 작업 실행을 지시한다.
작업 스케쥴러는 어떤 서버에 어떤 작업이 지시되었는지 실행 큐에 넣는다.
작업 스케쥴러는 작업이 완료되면 해당 작업을 실행 큐에서 제거한다.

작업서버
DAG에 정의된 작업을 수행하며, 각 서버들은 역할이 나누어져 있다.

임시저장소
임시저장소에는 무엇을 저장할 것이냐에 따라 시스템이 달라진다. 메타데이터 등은 접근이 빈번하기 때문에 메모리에 저장하는 것이 좋고, 비디오나 오디오 데이터는 BLOB 저장소에 저장하는 것이 바람직하고, 작업이 완료되면 삭제한다.

인코딩된 비디오
최종결과물

시스템 최적화

속도최적화: 비디오 병렬 업로드

비디오를 GOP단위로 분할하여 GOP들을 병렬로 업로드한다. 일부가 실패하더라도 해당 GOP만 다시 업로드하면 된다. 따라서 단말에서 GOP로 분할하는 작업을 수행하면 업로드가 빨라질 수 있다.

전체를 한번에 올려도 속도는 대역폭에 병목이 생기지 않나?
실패가 생기는 경우에 GOP로 업로드하는게 유리한가?

속도최적화: 업로드 센터를 사용자 근거리에 지정

업로드 센터를 여러 곳에 두면 transport 비용이 줄기 때문에 속도가 빨라진다.
CDN을 업로드 센터로 사용하면 각지에 있는 CDN edge를 사용할 수 있기 때문에 좋다.

CDN에 업로드된 비디오는 어떻게 원본 저장소에 가는가?

속도최적화 : 모든 절차를 병렬화

느슨하게 결합된 시스템을 만들어 병렬성을 높일 수 있다.
기존 절차에서 어떤 단계의 결과물은 이전 단계의 결과물로 만들어 진다. 의존성이 있으면 병렬성을 높이기 어렵다.

결합도를 낮추기 위해서 메시지 큐를 도입한다.
메시지 큐를 도입한 후에는 이전 결과물이 나올때까지 기다리는 게 아니라 메시지큐에 보관된 이벤트를 병렬적으로 처리할 수 있다.

안정성 최적화 : 미리 사인된 업로드 URL

허가받은 사용자만 올바른 장소에 비디오를 업로드할 수 있도록 하기 위해 API서버는 사용자에게 signed URL를 보내준다.
1. 클라이언트는 서버에 POST하여 저장소에 접근할 수 있는 URL을 받는다. (인증됨)
2. 클라이언트는 해당 URL을 통해 비디오를 업로드한다.

안정성 최적화 : 비디오 보호

  • DRM : 비디오에 저작권을 표시한다.
    • 애플 FairPlay
    • 구글 Widevine
    • MS PlayReady
  • AES 암호화 : 비디오를 암호화하고 접근 권한을 설정한다. 재생 시에만 복호화하고, 허락된 사용자만 암호화된 비디오를 시청할 수 있다.
  • 워터마크 : 비디오 위에 소유자 정보를 포함하는 이미지를 오버레이하여 올리는 것

비용 최적화

CDN에 비디오를 모두 올리는 것은 비용이 비싸다.

유튜브 비디오는 Long tail 분포를 따른다고 한다.

롱테일
1. 인기 비디오는 CDN을 통해 재생하되 다른 비디오는 비디오 서버를 통해 재생한다.
2. 인기가 별로 없는 비디오는 인코딩할 필요가 없을 수도 있다. 짧은 비디오는 필요할 때 인코딩하여 재생할 수 있다.
3. 특정 지역에서만 인기 있는 비디오는 다른지역으로 옮기 필요가 있다.
4. CDN을 직접 구축하는 것은 대규모 프로젝트이다. 다만 ISP와 제휴하여 비용을 낮출수도 있기 때문에 대규모 스트리밍인 경우 도입하는것도 좋다.

최적화 전에 시청 패턴을 분석하는 것도 중요하다.

오류 처리

  • 회복가능 오류 : 특정 세그먼트를 트랜스코딩하다 실패한 경우. 이 경우는 재시도를 통해 해결할 수 있으나, 계속 실패한다면 사용자에게 오류 코드를 반환해야 한다.
  • 회복불가능 오류 : 비디오 포맷이 잘못되었거나 하는 경우네는 클라이언트에 적절한 오류 코드를 반환하여야 한다.

오류의 전형적인 해결 방법

  • 업로드 오류 : 몇 회 재시도
  • 비디오 분할 오류 : 낡은 클라이언트가 GOP 경계에 따라 비디오를 분할하지 못하는 경우라면 전체 비디오를 서버에 전송하고, 서버가 비디오 분할하도록 처리
  • 트랜스코딩 오류 : 재시도
  • 전처리 오류 : DAG 그래프 재생성
  • DAG 스케쥴러 오류 : 작업을 다시 스케쥴링
  • 자원 관리자 큐에 장애 발생 : replica 이용
  • 작업 서버 장애 : 다른 서버에서 해당 작업 재시도
  • API 서버 장애 : 무상태 서버이기 때문에 다른 서버로 우회
  • 메타데이터 캐시 서버 장애 : 다중화되어 있기 때문에 다른 노드에서 데이터를 들고 온다.
  • 메타데이터 데이터베이스 서버 장애
    • 주 서버가 죽었다면 부 서버 중 하나를 주 서버로 교체한다.
    • 부 서버가 죽었다면 다른 부 서버를 통해 읽기 연산을 처리하고 죽은 서버는 새 것으로 교체한다.

마무리

  • API 계층의 규모 확장성 확보 방안 : horizontal scaling이 가능하다.
  • 데이터베이스 계층의 규모 확장성 확보 방안 : 다중화 + 샤딩
  • 라이브 스트리밍
    • 응답지연 시간이 낮아야하므로 스트리밍 프로토콜 선정에 유의해야 한다.
    • 병렬화의 필요성은 다소 낮다. 작은 단위의 데이터를 실시간으로 빨리 처리하기 때문
    • 오류 처리는 빠르게 적용할 수 있는 방안을 채택한다.
  • 비디오 삭제 : 저작권 위배, 선정적 비디오, 불법 비디오는 업로드 시점에 식별하거나 사용자의 신고로 판별해야 한다.

참조

알렉스 쉬, 가상 면접 사례로 배우는 대규모 시스템 설계 기초, 인사이트, 2021, 247p-275p

profile
👨🏻‍💻👨🏽‍🦲

0개의 댓글