미국에 100Gbps WebRTC 서버를 열어보기

웹 환경에서 실시간 영상을 영상 스트리밍을 하는 방법에는 여러가지가 있다. 가장 많이 사용되는 HLS, 지연 시간을 단축한 버전인 LL-HLS, 다른 여러 방법으로 영상을 받아오고 처리하는 MediaSource Extension (Managed Media Source), 그리고 이번 글에서 다룰 WebRTC 까지 여러 방법이 있다.

WebRTC가 가지는 강점은 “초 저지연” 이다. LL-HLS등을 사용해도 3초 딜레이가 발생한다. 0.5초의 청크를 써도 1.5초 정도의 지연이 발생한다. 하지만 WebRTC는 0.4초 정도의 지연으로 영상을 송출 할 수 있다.

WebRTC는 지연시간이 짧다

스트리밍은 네트워크 대역폭을 얼마나 가졌는지가 핵심

일반적으로 SD급의 영상은 1Mbps, HD급의 영상은 3Mbps 정도의 비트레이트를 사용한다. HD 환경에서 뷰어 하나에 3Mbps를 점유하게 된다는 말이다. 30명만 달라 붙어도 100Mbps가 필요하게 된다. 그렇기에, 스트리밍 회사는 대역폭을 얼마나 가지고 있는지가 중요해진다. 1Gbps를 가져도 330명 정도밖에 버틸수 없다.

Retransmission등을 고려했을때 20%의 대역폭 여유를 가지는게 좋다.

국내에서 IDC용 10Gbps 망은 3,100만원 ~ 4,000만원이 정가로 여겨진다. 100Gbps까지 가면 할인을 받아도 월 고정비가 거진 3억이 된다.

최근 1주일중 대역폭을 많이 쓴 날 캡쳐

금액의 문제 때문에 10k(1만명 접속자 수용)에 진입하기가 불가능하다. 10k를 받으려면 40Gbps 정도의 망을 확보해야 하는데, 저렴하게 구해도 망 비용만 1.3억 정도가 발생한다. 그러므로, 스트리밍 서비스는 결국 대역폭을 얼마나 많이 가졌는지가 체급을 결정하는 핵심 포인트가 된다.

해외로 가면?

국내의 망 비용은 유난히 비싼 편이다. 일본만 가도 망 비용이 꽤 낮아진다. 미국으로 가면 더더욱 낮아진다. 서버 비용을 포함해서 1.3천만원이면 100Gbps 망을 구할 수 있다. AMD EPYC 9xxx 서버 4대의 가격이 포함된 금액이기에 결코 아주 비싸다 할 수 없다.

문제는 해외망이라는 점이다. IX를 고려해서 호스팅 회사를 골랐음에도, 핵심 피크 타임 (저녁 18~19시, 21시~23시)에는 약 1%의 패킷로스가 관측됐다. 해당 시간대는 대부분의 사람이 퇴근해서 영상을 시청하는 핵심 시간이다. 이때 영상 끊김이나 지연이 발생하면 사용자가 불쾌함을 느낄 수 밖에 없다.

우리는 뷰어 측에서 패킷 로스가 발생하면 모니터링 서버에 보고하는 수집서버도 운영했었다. 실제 수치는 말하기 힘들지만, 1% ~ 5%의 패킷 로스가 발생한 것은 자료에 근거한 사실이다

최근 4일간의 전체 시청자의 packet loss 데이터이다.

우리는 100Gbps의 대역폭이 요구사항이었다. 만약 서비스가 원활하게 된다면 200Gbps 까지도 늘릴 계획이 있었다. 그렇기에 현실적으로 국내에서 서비스를 하는것은 불가능했다.

망 사용 용도를 밝히니 국내 IDC 모두 traffic 대신 Bandwidth commitment가 필요하다고 했다.

패킷 로스를 대비하자

상술했던것 처럼, 국내에서는 현실적으로 서비스를 할 수 없다. 100Gbps에 싸게 불러도 3억인데 이걸 어떻게 버티냐… 해서, 우리는 조금의 지연시간을 포기하는 대신 패킷 로스를 버티게 준비했다.

WebRTC의 NACK

WebRTC에는 NACK라는 개념이 있다. 아마 이 글을 읽는 독자들이라면 TCP의 ACK에 대해 들어봤을 것이다. TCP는 모든 패킷에 대해서 “수신 완료”를 상대에게 보낸다. (편의를 위해 window는 고려하지 않는다.) 만약 상대에게 패킷을 보냈으나 ACK가 돌아오지 않는다면 발신측에서 재전송 한다.

WebRTC는 “수신하지 않았음”을 상대에게 보낸다. 그래서 UDP 패킷 로스가 발생해도 WebRTC 레이어에서 패킷 재전송을 수행한다. 이것을 위해 모든 패킷에 번호를 붙여서 상대에게 보낸다. [1, 2, 3, ... 10, 12] 와 같이 번호를 붙여 보냈다고 하자. 11이 수신되지 않았음을 판단하고, 상대에게 11번째 패킷이 수신 되지 않았음을 알린다. 이 기술을 사용하면 패킷 로스가 간헐적으로 발생해도 버틸 수 있다.

브라우저에선 비디오에서만 NACK를 쓴다. 오디오쪽은 FEC를 사용한다.

오디오는 FEC

오디오는 NACK가 없다. 개념상으로는 RTP단에 존재하지만, 실제로 브라우저는 NACK를 쓰지 않는다. 대신, 여기는 FEC라는 개념을 사용한다. 지금 패킷 (샘플)을 N이라고 하면, N+1 패킷에 보정용 데이터를 실어 나르는 방식이다.

WebRTC에서 음성은 Opus를 사용하게 될 것이다. 여FEC를 쓰려면 useinbandfec 파라메터를 SDP 교환시 전달 해 줘야 한다.

이것 덕분에 일부 패킷이 손실 되더라도 Opus 디코더가 복원 작업을 할 수 있다. 대신 FEC를 쓰면 하나의 프레임만큼의 지연이 생길 수 있다. 일반적으로 20ms의 Opus frame을 사용하니까, 총 40ms의 오디오 지연이 생길 수 있다는 뜻이다.

하지만, 후술하는것 처럼 Jitter를 넓게 잡으면 이 문제를 해결 할 수 있다.

오디오의 끊김은 Concealed Event를 통해 수치로서 알 수 있다.

지연시간 대비 (Jitter)

미국 서부에 서버를 개통하면 130ms 정도의 RTT가 발생한다. 즉, 패킷 로스가 발생했다면 요청 후 다시 받는데 130ms가 걸리는 셈이다.

안정적인 상황에서 네트워크 레이턴시는: 한국 OBS -> (70ms) -> 미국 -> (70ms) -> 한국 시청자 가 된다. 패킷 로스가 발생하면 한국 OBS -> (70ms) -> 미국 -> (70ms) -> 한국 시청자 -> (70ms) NACK -> 미국 -> (70ms) -> 한국 시청자가 된다. (물론 실제로는 처리에 시간이 걸리므로 더 발생한다.)

브라우저에는 playoutDelayHint 라는것이 존재한다. 이것을 이용하면 브라우저의 Jitter Buffer를 제어할 수 있다. 예를 들어, playoutDelayHint를 1로 설정하면 브라우저는 패킷이 들어오고 1초간의 영상 데이터를 버퍼에 둔다. 0.1로 설정하면 100ms로 버퍼를 설정한다. 대신 100ms내로 영상이 들어오지 않는다면 사용자는 끊김을 느끼게 된다.

우리가 해야 할 것은 Packet Loss나 끊김을 감지해서 -> playoutDelayHint를 동적으로 제어하는 것이다. 만약 끊김이 발생하지 않는다면 playoutDelayHint를 줄일 필요도 있다.

Playout Delay Hint를 잘 쓰지 못하면 음성이 끊기거나 빨리감기 되는 현상이 나타난다

RTP Stat을 확인하면 패킷 로스나 음성 끊김(concealed event), 프레임 끊김(video frame freeze), 또는 브라우저가 판단하는 필요 Jitter Buffer 크기를 구할 수 있다. 이 데이터를 이용해서 playoutDelayHint를 동적으로 조절하는 것이 좋다

playoutDelayHint를 늘린다고 해서 바로 느려지거나, 줄인다고 해서 바로 빨리감기가 되지 않는다. playoutDelayHint의 증감에 따라 브라우저는 sample을 추가하거나 삭제하면서 ‘보정’을 한다.

PT도 챙겨주기

WebRTC는 영상을 RTP로 전송한다. RTP는 매 패킷에 영상 데이터 종류를 적는다. 예를 들어, 124 PT면 H264이고, 111이면 Opus 이다. 이것을 PT 번호라고 한다. 이 번호는 고정된게 아니라 WebRTC의 SDP를 교환할 때 정해진다. 그래서 SDP 교환시 PT 번호를 항시 체크 해야한다. 일종의 채널 ID라고 생각하면 좋다. (하나의 RTP에서 여러 데이터를 보내려다 보니 multiplexing용 id가 필요하다)

위에서 NACK가 발생하면 재전송을 한다고 했는데, 이 재전송을 RTX라고 한다. RTX는 별도의 PT를 가진다. 즉, NACK가 발생하면 -> 해당 패킷을 찾아서 -> RTX 채널(PT)로 재전송 한다. 더 깊게 들어가면 좀 더 달라지지만 지금은 생략하자.

그러면 미국에 서버를 둬도 괜찮나..?

결과적으로 잘 된다. 대신에 핵심 타임에는 전체 1.2초 정도의 딜레이가 발생한다. 한국 OBS -> 미국으로 보내는 과정에서도 패킷로스가 발생하기 때문이다. 최악의 경우에 한국에서 미국으로 가는곳에서 로스가 나고, 미국에서 한국 시청자에게 송출하는데도 패킷 로스가 발생할 수가 있다.

하지만 1.2초만 해도 상당히 빠른 속도이다. 조금 빡세게 튜닝을 하면 전체 0.8초의 딜레이로도 맞출 수 있다. 이 경우 진정한 sub-second 방송이 실현된다. 이 정도만 해도 타 방송 플랫폼보다 월등히 빠른 속도이다.

번외

의외로 국내에서 홍콩, 싱가폴 쪽의 인지도가 낮다. 필자는 이 쪽이 너무 저평가 됐다고 생각한다. 당장 Cloudflare만 해도 대부분 홍콩으로 보내고 있다. 그만치 망 품질이 괜찮다는 뜻 일 것이다. 실제로 망 테스트를 해봤는데 대역폭을 많이 써도 잘 버틴다. 특히 홍콩쪽이 망이 괜찮다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Blue Captcha Image
Refresh

*

최신 글

목차