가상 면접 사례로 배우는 대규모 시스템 설계 기초 Study [14장] 유튜브 설계
Contents
Note
팀 내에서 진행하는 Study 정리 입니다.
함께 논의하고 싶은 주제
느낀점
- 모바일 인터넷 트래픽 중 37% 가 유튜브라는 사실이 놀랍습니다.
- 비디오를 트랜스코딩 시 DAG 모델이 어떻게 쓰이는지 와닿지 않아서 조금 이해가 가지 않았습니다. 객체지향 언어에서처럼 각 작업을 인터페이스나 추상메서드로 정의해두면 클라이언트는 해당 작업을 클라이언트 OS에 맞게 구현하는 것 이라고 이해했는데 맞을까요?
1. 문제 이해 및 설계 범위 확정
요구사항
- 빠른 비디오 업로드
- 원활한 비디오 재생
- 재생 품질 선택
- 낮은 인프라 비용
- 높은 가용성과 규모 확장성 그리고 안정성
- 지원 클라이언트 : 모바일 앱, 웹브라우저, 스마트TV
개략적 규모 측정
- 일간 능동사용자 : 5백만
- 한 사용자는 하루 평균 5개의 비디오 시청
- 10%의 사용자가 하루에 1 비디오 업로드
- 비디오 평균 크기 300MB
- 비디오 저장을 위해 매일 요구되는 용량 : 5백만 * 10% * 300MB = 150TB
- CDN 비용
- 클라우드 CDN을 통해 서비스할 경우 데이터의 양에 따라 CDN에서 과금
- 아마존 클라우드프론트 기준으로 100% 미국에서 발생 시 1GB 당 0.02 요금 발생
- 따라서 매일 발생하는 요금은 5백만 * 5 비디오 * 0.3GB * $0.02 = $150,000
2. 개략적 설계안 제시 및 동의 구하기
- CDN과 BLOB 스토리지는 클라우드 서비스를 활용
Note
- 시스템 설계 면접은 모든 것을 밑바닥 부터 만드는 것과 관계 없음
- 주어진 시간에 적절한 기술을 골라 설계를 마치고 그 기술이 각각 어떻게 동작하는지 상세히 설명하는 것이 더 중요
- 규모 확장이 쉬운 BLOB 저장소 CDN을 만드는 것은 지극히 복잡하고 비용이 많이 드는 일
- 넷플릭스의 경우 클라우드 서비스를 사용, 페이스북은 아카마이의 CDN을 사용
2.1 비디오 업로드 절차
- 사용자 : 컴퓨터나 모바일 폰, 스마트 TV로 유튜브 시청
- 로드밸런서 : API 서버 각각으로 고르게 요청을 분산
- API 서버 : 비디오 스트리밍을 제외한 모든 요청
- 메타데이터 데이터베이스 : 비디오의 메타데이터를 보관. 샤딩과 다중화 적용하여 성능 및 가용성 요구사항 충족
- 메타데이터 캐시 : 성능을 높이기 위해 비디오 메타데이터와 사용자 객체는 캐시
- 원본 저장소 : 원본 비디오를 보관할 대형 이진 파일 저장소(BLOB: Binary Large Object storage) 시스템
- 트랜스코딩 서버 : 비디오 트랜스코딩(비디오 인코딩)은 비디오의 포맷(MPEG, HLS 등) 변환하는 절차. 단말이나 대역폭 요구사항에 맞는 최적의 비디오 스트림을 제공하기위해 필요
- 트랜스코딩 비디오 저장소 : 트랜스코딩이 완료된 비디오를 저장하는 BLOB 저장소
- CDN : 비디오를 캐시하는 역할. 사용자가 재생 버튼을 누르면 비디오 스트리밍은 CDN을 통해 이루어짐
- 트랜스코딩 완료 큐 : 비디오 트랜스 코딩 완료 이벤트들을 보관할 메시지 큐
- 트랜스코딩 완료 핸들러 : 트랜스코딩 완료 큐에서 이벤트 데이터를 꺼내어 메타데이터와 캐시 데이터베이스를 갱신할 작업 서버
프로세스 a: 비디오 업로드
- 비디오를 원본 저장소에 업로드
- 트랜스 코딩 서버는 원본 저장소에서 해당 비디오를 가져와 트랜스 코딩 시작
- 트랜스 코딩이 완료 (병렬로 처리)
- 3a : 완료된 비디오를 트랜스 코딩 비디오 저장소에 업로드
- 3a.1. 트랜스 코딩이 끝난 비디오를 CDN에 업로드
- 3b : 트랜스코딩 완료 이벤트를 트랜스코딩 완료 큐에 저장
- 3b.1. 완료핸들러가 이벤트 데이터를 큐에서 꺼냄
- 3b.1.a, 3b.1.b : 완료 핸들러가 메타데이터 데이터베이스와 캐시를 갱신
- API 서버가 단말에게 비디오 업로드가 끝나서 스트리밍 준비가 되었음을 알림
프로세스 b: 메타데이터 갱신
- 원본 저장소에 파일이 업로드되는 동안, 단말은 병렬적으로 비디오 메타데이터 갱신 요청 API를 서버에 보낸다
- 메타데이터에는 파일 이름, 크기, 포맷 등의 정보가 들어 있다.
2.2 비디오 스트리밍 절차
- 스트리밍은 장치가 원격지의 비디오로부터 지속적으로 비디오 스트림을 전송받아 영상을 재생하는 것
- 스트리밍 프로토콜 : 비디오 스트리밍을 위해 데이터를 전송할 때 쓰이는 표준화된 통신 방법
- MPEG-DASH, HLS, Microsoft Smooth Streaming, Adobe HTTP Dynamic Streaming(HDS)
- 프로토콜마다 지원하는 비디오 인코딩과 플레이어는 다름 -> 서비스 용례에 따라 선택
- 비디오는 CDN에서 바로 스트리밍 되며 사용자 단말에 가장 가까운 CDN edge server가 비디오 전송을 담당
3. 상세 설계
3.1 비디오 트랜스 코딩
- 다른 단말에서도 순조롭게 재생되려면 다른 단말고 호환되는 비트레이트(bitrate)와 포맷으로 저장
- 비트레이트 : 비디오를 구성하는 비트가 얼마나 빨리 처리되어야 하는지 나타내는 단위. 비트레이트가 높으면 고화질 비디오
- 비트레이트가 높은 비디오 스트림을 정상 재생하려면 높은 성능의 컴퓨팅 파워와 인터넷 회선 속도 필요
비디오 트랜스코딩이 중요한 이유
- 가공되지 않은 원본 비디오(Raw video)는 저장 공간을 많이 차지
- 상당수 단말과 브라우저는 특정 종류의 비디오 포맷만 지원하므로 호환성 문제 해결을 위해 비디오를 여러 포맷으로 인코딩
- 사용자에게 끊김 없는 고화질 비디오 재생을 보장
- 모바일 단말의 경우 네트워크 상황이 수시로 변경 -> 비디오 화질을 자동으로 변경 혹은 수동으로 변경할 수 있어야 한다.
인코딩 포맷
- 컨테이너 : 비디오 파일, 오디오, 메타데이터를 담는 바구니. 컨테이너 포맷은 .avi, .mov, .mp4 같은 확장자로 알 수 있음
- 코덱 : 화질을 보존하고 크기를 줄일 목적으로 고안된 압축 및 압축 해제 알고리즘. H.264, VP9, HEVC 등
3.2 유향 비순환 그래프(DAG) 모델
다른 유형의 비디오 프로세싱 파이프라인을 지원하고 처리과정의 병렬성을 높이기 위해 적절한 추상화를 도입하여 클라이언트 프로그래머로 하여금 실행 작업을 손수 정의 할수 있게 함
- 페이스북 사례 : DAG 모델을 도입하여 유연성과 병렬성을 달성
- 유향 비순환 그래프(Directed Acyclic Graph) 프로그래밍 모델을 도입, 작업을 단계별로 배열하여 해당 작업들이 순차적 혹은 병렬적으로 실행되도록 하고 있음
- 검사(Inspection) : 좋은 품질의 비디오인지 손상은 없는지 확인하는 작업
- 비디오 인코딩(video encoding) : 비디오를 다양한 해상도, 코덱, 비트레이트 조합으로 인코딩
- 섬네일(thumbnail) : 사용자가 업로드한 이미지나 비디오에서 자동 추출된 이미지로 섬네일을 만드는 작업
- 워터마크(watermark) : 비디오에 대한 식별정보를 이미지위에 오버레이 형태로 띄워 표시
3.3 비디오 트랜스코딩 아키텍처
전처리기(Preprocessor)
전처리기가 하는일
- 비디오 분할(video splitting)
- 비디오 스트림을 GOP(Group of Pictures)라고 불리는 단위로 분할.
- GOP는 특정순서로 배열된 프레임 그룹이며 하나의 GOP는 독립적으로 재생가능
- 길이는 보통 몇 초 정도
- 오래된 단말이나 브라우저는 GOP 단위의 비디오 분할을 지원하지 않음 -> 전처리기가 비디오 분할을 대신함
- DAG 생성
- 클라이언트 프로그래머가 작성한 설정 파일에 따라 DAG 생성
- 데이터 캐시
- 전처리기는 분할된 비디오의 캐시이기도 함
- GOP와 메타데이터를 임시 저장소에 보관
- 비디오 인코딩이 실패하면 시스템은 보관된 데이터를 활용해 인코딩을 재개
DAG 스케쥴러
- DAG 스케쥴러는 DAG 그래프를 몇 개 단계(Stage)로 분할한 뒤 각각의 자원 관리자의 작업 큐에 저장
[예시]
- 하나의 DAG 그래프를 2개 작업단계로 쪼갠 사례.
- 첫단계 : 비디오, 오디오, 메타데이터 분리
- 두번째 단계 : 해당 비디오 파일을 인코딩하고 섬네일을 추출, 오디오 파일 또한 인코딩
자원 관리자(resource manager)
- 자원 배분을 효과적으로 수행하는 역할 담당
[예시]
- 작업 큐(task queue) : 실행할 작업이 보관되어 있는 우선순위 큐(priority queue)
- 작업 서버 큐(worker queue) : 작업 서버의 가용 상태 정보가 보관되어 있는 우선순위 큐
- 실행 큐(running queue) : 현재 실행 중인 작업 및 작업 서버 정보가 보관되어있는 큐
- 작업 스케쥴러 : 최적의 작업/서버 조합을 골라 해당 작업 서버가 작업을 수행하도록 지시하는 역할 담당
작업관리자 동작 원리
- 작업 관리자는 큐에서 가장 높은 우선순위 작업을 꺼냄
- 작업 관리자는 해당 작업을 실행하기 전 적합한 작업 서버를 선택
- 작업 스케줄러는 해당 작업 서버에 작업 실행을 지시
- 작업 스케줄러는 해당 작업이 어떤 서버에게 할당되었는지에 관한 정보를 실행 큐에 넣음
- 작업 스케줄러는 작업이 완료ㅗ디면 해당 작업을 해당 큐에 제거
작업 서버
- 작업 서버는 DAG에 정의된 작업을 수행
임시 저장소
- 저장소 시스템 선택에 따라 데이터의 유형, 크기, 이용 빈도, 데이터 유효기간 등이 달라짐
- 메타데이터는 작업 서버가 빈번히 참조하므로 크기가 작은것이 보통 -> 따라서 메모리에 캐시
- 비디오/오디오 데이터는 BLOB 저장소
- 임시 저장소 보관 데이터는 비디오 프로세싱 완료시 삭제
인코딩된 비디오
- 인코딩 된 비디오는 인코딩 파이프라인의 최종 결과물
3.4 시스템 최적화
속도최적화 : 비디오 병렬 업로드
- 비디오 전부를 한 번에 업로드 하는 것은 비효율적
- GOP들로 분할하여 GOP를 병렬적으로 업로드 - 일부 실패시에도 업로드 재개 가능
속도 최적화: 업로드 센터를 사용자 근거리에 지정
- 업로드 센터를 여러 곳에 두고 사용자의 근거리에 있는 CDN 업로드 센터를 이용
속도 최적화: 모든 절차를 병렬화
- 느슨하게 결합된 시스템을 만들어 병렬성을 높인다.
- 메세지 큐 도입 전 인코딩 모듈 : 다운로드 모듈 작업 완료 대기 필요
- 메시지 큐 도입 후 인코딩 모듈 : 다운로드 모듈 완료 대기 필요 없음. 메세지 큐에 보관된 이벤트를 모듈은 병렬적으로 처리 가능
안정성 최적화: 미리 사인된 업로드 URL
- 허가받은 사용자만이 올바른 장소에 비디오 업로드가 가능해야 함
업로드 절차
- 클라이언트는 HTTP 요청을 통해 미리 사인된 URL 응답받음. 해당 URL이 가리키는 객체에 대한 접근 권한이 이미 주어져 있는 상태
- API 서버는 미리 사인된 URL을 리턴
- 클라이언트는 해당 URL이 가리키는 위치에 비디오 업로드
안정성 최적화: 비디오 보호
- 디지털 저작권 관리(DRM: Digital Rights Management) 시스템 도입 : 애플 페어플레이(FairPlay), 구글의 와이드바인(Widevine), MS의 플레이레디(PlayReady) 등
- AES 암호화(encryption) : 비디오를 암호화하고 접근 권한을 설정. 암호화된 비디오는 재생 시 복호화, 허락된 사용자만 암호화된 비디오 시청
- 워터마크(watermark) : 비디오 위에 소유자 정보를 포함하는 이미지를 오버레이 하는 것
비용 최적화
CDN 비용을 낮추는 방법
유튜브 비디오 스트리밍은 롱테일(long-tail) 분포를 따름. 인기 있는 비디오는 빈번히 재성되는 반면 나머지는 거의 보는 사람이 없음
- 인기 비디오는 CDN을 통해 재생하되 다른 비디오는 비디오 서버를 통해 재생
- 인기가 별로 없는 비디오는 인코딩 할 필요가 없을 수도 있음. 짧은 비디오라면 인코딩하여 재생
- CDN을 직접 구축하고 인터넷 서비스 제공자(ISP: Internet Service Provider)와 제휴
모든 최적화는 콘텐츠 인기도, 이용 패턴, 비디오 크기 등 데이터에 근거하게 되며 최적화 시도 전 시청 패턴을 분석하는 것이 중요
오류처리
- 대형시스템에서 시스템 오류는 불가피하며 장애를 아주 잘 감내하는(highly fault tolerant) 시스템을 만들기 위해 오류를 우아하게 처리하고 빠르게 회복해야 한다.
시스템 오류 두 가지 종류
-
회복 가능 오류(recoverable error)
- 특정 비디오 세그먼트를 트랜스코딩 하다 실패하는 경우
- 몇 번의 재시도하면 해결
- 계속 시도시 복구가 어렵다 판단될 경우 클라이언트에게 적절한 오류 코드 반환
-
회복 불가능 오류(non-recoverable error)
- 비디오 포맷이 잘못되어있는 경우 등
- 해당 작업을 중단하고 클라이언트에게 적절한 오류 코드 반환
컴포넌트 별 오류 해결방법
- 업로드 오류 : 몇 회 재시도
- 비디오 분할 오류 : 오래된 버전의 클라이언트가 GOP에 따라 분할하지 못하는 경우 전체 비디오를 서버로 전송하고 서버에서 해당 비디오를 분할처리
- 트랜스 코딩 오류 : 재시도
- 전처리 오류 : DAG 그래프 재생성
- DAG 스케쥴러 오류 : 작업을 다시 스케쥴링
- 자원관리자 큐에 장애 발생: 사본을 이용
- 작업 서버 장애: 다른 서버에 해당 작업 시도
- API 서버 장애: 신규 요청은 다른 API 서버로 우회
- 메타데이터 캐시 서버 장애 : 데이터는 다중화 되어있으므로 다른 노드에서 가져옴. 장애 발생 캐시 서버는 새로운 것으로 교체
- 메타데이터 데이터베이스 서버 장애
- 주 서버가 죽으면 : 부 서버 가운데 하나를 주 서버로 교체
- 부 서버가 죽으면 : 다른 부 서버를 통해 읽기 연산 처리 죽은 서버는 새 서버로 교체
4. 마무리
- API 계층의 규모 확장성 확보 방안
- 데이터베이스 계층의 규모 확장성 확보 방안
- 라이브 스트리밍(live streaming)
- 라이브 스트리밍은 실시간으로 녹화하고 방송하는 절차
- 비디오 업로드, 인코딩, 스트리밍이 필요하다는 점은 비-라이브스트리밍 시스템과 같음
- 응답시간이 좀 더 낮아야 함. 스트리밍 프로토콜 선정에 유의
- 작은 단위의 데이터를 실시간으로 빨리 처리해야하므로 병렬화 필요성은 적음
- 오류 처리 방법을 다르게 적용
- 비디오 삭제(takedown) : 저작권 위반, 선정적, 불법적 행위와 관계된 비디오는 내려야 함. 업로드 과정에서 식별하거나 사용자의 신고 절차를 통해 판별