MoQ
블로그 구출작전 이후 첫 포스트 👏
MoQ: Refactoring the Internet's real-time media stack
미디어 프로토콜의 진화
RTMP
- 거의 처음으로 상용화된 영상 스트리밍 프로토콜!
- 당시엔 혁신적이였던 5초 이내의 레이턴시! 물론 기술이 발전하면서 이거보다 짧은 프로토콜이 세상에 많이 나왔다
- 현재는 거의 데이터 수집 용도로 사용됨
- TCP 종특) HoLB 때문에 레이턴시 상당함
- connection을 계속 유지해줘야 하는 stateful함. CDN이나 스케일링이 복잡하다
HLS
과거 정리해두었던 포스트 → HLS
- 비디오를 여러 세그먼트로 나누어 http를 통해 전달하는, 애플 형님들이 만든 프로토콜
- cdn도 타고 + 스케일링도 가능!
- 다만 레이턴시가 와장창 늘어날 수밖에 없는 구조. 버퍼링까지 고려하면 최소한 세그먼트 3개 분량의 레이턴시가 발생한다
WebRTC
- P2P를 사용해서 서버에 가해지는 부하를 우회하고 레이턴시도 줄이고
- 근데 mash 구조에서 늘어날 때마다 커넥션 수가 n^2 단위로 증가
- 본질적으로 얘도 stateful한 커넥션이라 cdn 안되고 스케일링이 어렵다
- SFU나 MCU같은걸 끼얹으면 된다고 하는 데 쉽지 않다 Cloudflare Calls: millions of cascading trees all the way down
MOQ
- 설계 레벨부터 이런 문제를 한번에 해결하기 위한 방법이 고려되었다고 한다
- 일단 QUIC 쓴다. QUIC 자체가 미디어에 되게 적합한 프로토콜이라고 함
- HoLB 없다
- Connection Migration이라는 기술을 통해, wifi → 셀룰러 → wifi 핸드오프가 뚝딱 된다
- 0-RTT라던가 TLS라던가 quic에 있는 장점들
아키텍처
- QUIC / Webtransport: 플레인 QUIC을 쓰거나, 브라우저 위에서는 WebTransport를 사용할 수도 있음
- MoQT Layer: pub/sub 구조를 정의하는 계층. ANNOUNCE, SUBSCRIBE 등등 컨트롤메세지
- 스트리밍 포맷: 실제로 미디어 패킷 받아서 처리하는 로직. 제일 유명한 게 WARP인가봄
pub/sub 모델
- CDN 스케일의 실시간 미디어를 위해 디자인되었다고 함
- 계층 구조
- track: 이름이 지정된 미디어 스트림 (ex. video-1080p), subscriber는 이름을 지정하여 특정 track을 요청
- group: track의 독립적으로 디코딩 가능한 덩어리. hls의 세그먼트와 비슷한 개념인듯
- object: 네트워크를 통해 전송되는 실제 패킷으로, 각 object는 track의 group 안에서 특정한 위치를 가짐
- publisher: track 이름을 announce하고 object 전송
- subscriber: 이름에 따라 특정 track을 요청
- relay: object를 파싱하거나 트랜스코딩하지 않고(immutable) publisher와 subscriber 연결
- upstream에서 트랙을 수신하는 subscriber이면서, 다운스트림에 뿌려주는 publisher임
- 이런 구조 때문에 cdn 통해서 캐싱하는 게 용이함
- 물론 개념적으로는 connection based라서 http처럼 단순히 response 캐싱하는 것보다는 복잡한 일이겠지만, 단순한 pub/sub 모델이므로 복잡하게 상태관리할 필요가 없다
- object는 immutable하다는 가정을 하기에 메모리에 넣어놨다가 냅다 뿌리면 된다
시퀀스
- 연결 수립 과정을 나타낸 시퀀스 다이어그램인데, 사실 특별할 건 없다
- 위에 언급이 없었던 control plane이란 녀석이 등장함
- 어느 relay에서 어느 track이 돌고 있는 지 이런 거 알고 있음 (다이어그램에 화살표가 반대로 되어 있다ㅋㅋ)
- 그냥 DB라 생각해도 무관. cloudflare에선 sql 기반의 durable-objects라는 걸 쓴 듯
subscriber 없이 일단 relay에 publish하는 방식도 있다는 듯 하다

Flow Control
- subgroup이란 것을 통해 우선순위를 지정할 수 있는 듯 하다
- 붙은 번호가 낮을 수록 우선순위 높음
- subgroup 0 : 기본 비디오 레이어(360p) - 반드시 제공해야 함
- subgroup 1 : 720p로 향상 - 대역폭이 허용하는 경우 제공
- subgroup 2 : 1080p로 향상 - 혼잡으로 인해 가장 먼저 중단됨
- 이렇게 두면 2로 하다가 문제 생기면 0부터 재시도하는 방식으로 QoS를 맞춤
후기
생각보다 애매할지도..?
- WebRTC 대체한다고는 적혀 있지만 실제로 완전 WebRTC 대체하려고 만든 건 아닌 듯 함 🤔
얜 본질적으로 서버-클라구조이다 보니 WebRTC의 P2P에서 오는 장점까지 대체하기는 어려울 듯
부분적인 케이스(스케일이 커지고 커넥션 수가 많아질 때 WebRTC가 힘들어하는 문제)를 대체하고 싶은 게 아니었을까
- HLS도 아묻따무지성캐싱을 태울 수 있다는 장점이 워낙 커서 완전 대체는 어려울 듯..?
레이턴시가 크게 중요하지 않은 유즈케이스에서는 그냥 HLS 쓸 것 같음
- 클라우드 프로바이더에서 이걸 사용할 수 있는 인터페이스를 어떻게 만들어주느냐가 관건일 듯 한데 쉽지 않아 보였다