들어가기 전에...
동영상 스트리밍 시스템을 설계하다 보면, 대부분의 사람은 이렇게 말하고 싶어 합니다.
그냥 영상 URL 하나만 다른 기기에 넘겨주면 안 되나요?
겉으로 보면 그럴 듯하다. 재생 가능한 URL 하나만 알면, 어디서든 그 주소로 접속해서 영상을 볼 수 있을 것 같지만 실제 스트리밍 세계를 조금만 들여다보면 이 단순한 상상은 금방 깨지게 됩니다.
그 이유는 스트리밍은 ‘파일 1개’가 아니라 ‘세그먼트 수십~수백 개’의 행렬이기 때문이죠.
그래서 이번 포스팅에서는 스트리밍을 세그먼트라는 단위에서 다시 바라보고, 그 관점으로 클라이언트 앱 - 프록시 - 플레이어 디바이스 구조를 어떻게 설계할 수 있는지 이야기해보도록 하겠습니다.
우리가 보지 못하는 것, 세그먼트의 행렬
일반 사용자가 보는 플레이어 화면에는 재생 버튼과 타임라인만 보이지만 그 뒤에서는 이런 일들이 벌어집니다.
- 플레이어는 먼저 플레이리스트(예: m3u8 등) 를 요청합니다.
- 그 리스트 안에는 짧게 쪼개진 세그먼트(segment) 들의 URL이 들어 있죠.
- 플레이어는 이 세그먼트들을 하나씩, 또는 여러 개씩 병렬로 요청해 버퍼를 채워줍니다.
- 재생 중에 네트워크가 나빠지면 더 낮은 화질의 세그먼트 목록으로 갈아탑니다.
잠깐 정리하면 사용자가 보는 영상 1편은 시스템 입장에선 이렇게 보이게 됩니다.
세그먼트 N개에 대한 HTTP 요청 집합
그래서 스트리밍을 설계할 때 중요한 질문은 사실 이런 쪽입니다.
- 이 사용자는 몇 번째 세그먼트까지 정상적으로 받아갈 수 있는가?
- 세그먼트 요청이 어느 경로를 통해 나가고 있는가?
- 세그먼트마다 동일한 보안/인증 컨텍스트가 유지되고 있는가?
세그먼트 관점에서 다시 그려본 3계층 구조
세그먼트를 중심에 두고 아키텍처를 그려보면 자연스럽게 아래와 같은 세 가지 역할이 나오게 됩니다.
- 클라이언트 앱
- 프록시/게이트웨이
- 플레이어 디바이스
이 세 역할이 협업해서 사용자가 볼 수 있는 세그먼트만 안정적으로 전달하도록 만든다고 생각하면 됩니다.
이제 각 요소가 어떤것들인지 자세히 살펴보죠!
클라이언트 앱 - 이 사용자가 볼 수 있는 세그먼트를 정의하는 곳
클라이언트 앱의 핵심 역할은 사용자 컨텍스트를 만드는 것입니다.
- 이 사용자는 누구인가? (로그인 정보)
- 이 사용자는 이 영상을 볼 권한이 있는가? (권한/결제 여부)
- 어느 시간까지, 어떤 화질까지 허용할 것인가? (정책, 제한)
앱은 이 정보를 바탕으로 백엔드와 통신해 토큰, 쿠키, 세션 정보 등을 획득합니다. 하지만 중요한 점은 여기서 끝이 아니라는 것인데 앱이 하는 일은 동영상 주소를 가져오는 것이 아니라 어떤 세그먼트를 허용할지에 대한 컨텍스트를 만드는 것에 가깝습니다.
실제 세그먼트 요청은 다른 주체(프록시 혹은 플레이어 디바이스)가 수행할 수 있기 때문에 앱은 그들이 참고할 수 있는 컨텍스트 ID, 세션 ID, 토큰을 준비해 넘겨줘야 합니다.
프록시/게이트웨이 - 세그먼트의 문을 지키는 문지기
프록시/게이트웨이는 세그먼트 관점에서 보면 이런 역할을 합니다.
- 세션 ID ↔ 실제 인증 정보(토큰/쿠키) 매핑
- 세그먼트 요청을 대신 받아서 원본 서버/CDN으로 전달
- 응답을 다시 되돌려주는 중계자
이렇게 얘기하면 조금 어렵죠? 그럼 조금 더 풀어 보겠습니다.
자 먼저 클라이언트 앱은 이 사용자의 세션을 프록시에 등록하게 됩니다. 예를 들면 세션 ID 123 ↔ (사용자 A의 토큰/쿠키/정책) 이런 형태죠.
그러면 플레이어 디바이스는 세그먼트를 직접 CDN에 달리는 대신 https://proxy.example.com/session/123/segment/0001.ts 같은 형식으로 프록시를 향해 요청을 보내게 됩니다.
그 후에 프록시는 세션 ID 123에 담긴 인증 정보를 꺼내서 원본 서버/CDN에 세그먼트를 요청하고, 응답을 받아 다시 플레이어에게 전달하게 되는 것이죠.
이 구조를 사용하면, 세그먼트에 대한 보안·인증·비즈니스 로직을 프록시 한 곳에 모을 수 있습니다.
추가로 프록시에서 할 수 있는 것들로는 아래와 같은 것들이 있습니다.
- 세그먼트 단위 캐시 (인기 있는 구간만 빠르게 제공)
- 세그먼트 요청 로깅/모니터링
- 사용자별/세션별 레이트 리밋(rate limit)
- 실시간 통계 (몇 번째 세그먼트에서 이탈이 많은지 등)
플레이어 디바이스 - 가능한 한 단순하게
마지막으로 플레이어 디바이스는 이렇게 두는 게 이상적입니다.
세그먼트를 받아서 재생하는 단순 소비자
여기서 말하는 플레이어 디바이스는 TV 앱일 수도 있고, 외부 기기일 수도 있고, 브라우저 기반 플레이어일 수도 있습니다.
그래서 플레이어가 해야 할 일은 주어진 URL에서 플레이리스트를 가져오고, 거기에 적힌 세그먼트 주소를 따라가며, 적절한 버퍼링과 재생 제어를 하는 것입니다.
반대로, 플레이어에 너무 많은 역할을 집어넣으면 이런 문제가 생기게 됩니다.
- 디바이스마다 인증 로직을 다르게 구현해야 함
- 토큰/쿠키를 안전하게 보관하기 어려움
- 정책이 바뀔 때마다 여러 플랫폼을 동시에 업데이트해야 함.
그래서 세그먼트 기반 설계에서는 플레이어는 가능한 얇게, 세그먼트 소비에만 집중하게 그리고 인증/비즈니스 로직은 프록시 쪽으로 밀어내는 것이 깔끔합니다.
세그먼트 중심 설계의 장점
자 이제 왜 굳이 이렇게까지 구조를 나누는지 정리해 보겠습니다.
보안 정책을 세그먼트 레벨까지 내릴 수 있다
단순히 이 사용자는 이 영상을 볼 수 있다/없다가 아니라, 특정 시점 이후 세그먼트는 더 이상 제공하지 않습니다.
그리고 특정 트래픽 이상 요청하면 세그먼트 응답 속도를 조절하며, DRM, 워터마크 등 추가 정책을 세그먼트 단위로 적용하게 됩니다.
그래서 같은 로직을 모두 프록시에서 중앙집중적으로 제어할 수 있게 되는 것이죠
몇 번째 세그먼트에서 끊겼는 지 장애 분석이 쉬워진다.
문제가 생겼을 때 로그를 세그먼트 기준으로 보면
- 플레이리스트는 잘 내려갔는지
- N번째 세그먼트부터 4xx/5xx가 발생하는지
- 특정 구간에서만 응답이 느려지는지
를 명확하게 볼 수 있습니다.
이건 영상 URL 하나가 안 된다는 거친 정보보다 훨씬 더 정확하게 문제 지점을 좁혀 주게 되죠.
캐시와 트래픽 최적화 포인트가 선명해진다
세그먼트 단위로 보면 아래와 같은 최적화 아이디어가 자연스럽게 떠오르게 됩니다.
- 자주 재생되는 앞부분 세그먼트는 더 적극적으로 캐시
- 뒤쪽 세그먼트는 상대적으로 느슨한 정책 적용
- 구간 반복/프리뷰 같은 기능을 세그먼트 기준으로 구현
결국 영상 단위가 아니라 세그먼트 단위로 트래픽과 비용을 바라보게 되는 것이 큰 변화인 것이죠.
멀티 디바이스 환경에 강하다
만약 한 사용자가 모바일 앱에서 콘텐츠를 선택하고, TV나 외부 기기로 재생을 넘기고, 또 다른 기기에서 이어보기를 할 수도 있다고 가정해보겠습니다.
이때 클라이언트 앱과 플레이어 디바이스는 계속 바뀌지만 프록시와 세그먼트 컨텍스트는 그대로 유지될 수 있죠.
이걸 다른 말로 얘기하자면 사용자가 어떤 기기를 쓰든 세그먼트는 항상 같은 규칙 아래에서 제공된다는 상태를 만들 수 있다는 뜻이 됩니다.
마무리
지금까지 내용을 정리해보면 아래와 같겠네요!
- 스트리밍은 결국 세그먼트 요청 N개의 집합이고 우리는 그 위에 영상 1편이라는 추상화를 올려서 보고 있다.
- 하지만 아키텍처를 설계할 때는 오히려 세그먼트를 기준으로 역할을 나누는 편이 더 자연스럽다.
그래서 이렇게 생각해볼 수 있게 됩니다.
- 클라이언트 앱은 이 사용자가 어떤 세그먼트를 볼 수 있는지를 정의하고
- 프록시/게이트웨이는 그 세그먼트들의 문을 지키는 문지기가 되고
- 플레이어 디바이스는 세그먼트를 받아 조용히 재생하는 단순 소비자가 된다.
그리고 이 관점은 단순히 이론적인 정리가 아니라, 실제로 설계를 바꾸는 기준이 되기도 합니다.
새로운 기능을 추가하거나 장애가 났을 때, '이 URL이 왜 안 될까?”보다 먼저 “어떤 세그먼트가, 어떤 컨텍스트로 요청되고 있을까?”를 떠올리게 만들기 때문입니다.
세그먼트를 기준으로 역할을 나눠두면 보안 정책을 어디에 두어야 할지, 로그와 메트릭을 어디에 얼마나 쌓아야 할지, 비용 최적화와 캐시 전략을 어디에서 조절해야 할지 같은 고민에 대해서도 자연스럽게 답이 나옵니다.
그래서 결국 세그먼트 중심 아키텍처라는 건 특정 프로토콜이나 기술 스택에 묶인 패턴이 아니라,
동영상 한 편을 세그먼트들의 흐름으로 바라보는 사고방식에 가깝습니다.
이 관점이 한 번 몸에 배고 나면 새로운 스트리밍 시스템을 설계할 때도 URL 하나를 넘기는 구조가 아니라 세그먼트가 안전하고 일관되게 흘러가는 구조를 먼저 떠올리게 될 것입니다.
'Networking' 카테고리의 다른 글
| [바미] OSI 7계층에 대해 (0) | 2024.05.28 |
|---|---|
| [바미] HTTP status code (0) | 2023.01.05 |
| [바미] 쿠키, 세션이란? (0) | 2022.12.26 |
| [바미] 3 - Way Handshake 와 4 - Way Handshake를 알아봅시다. (2) | 2022.11.08 |
| [바미] RTMP(Real Time Messge Protocol)란? (0) | 2022.10.30 |