[SFU vs MCU] SFU와 MCU는 경쟁 관계가 아니라 선택지다
SFU와 MCU를 비교하면 둘 중 하나를 골라야 할 것처럼 보인다. 나도 처음에는 SFU가 현대적이고 MCU는 예전 방식이라고 단순하게 나눴다. 하지만 실제 제품에서는 그렇게 정리하면 금방 막힌다. SFU는 낮은 지연과 확장에 강하고, MCU는 합성 결과물과 단순한 수신 경험에 강하다. 경쟁이라기보다 서로 다른 위치에 놓는 선택지다. 로그를 다시 펼쳤을 때 눈에 들어온 건 예쁜 성공 화면이 아니라, SFU 주변에서 반복되던 작은 끊김이었다.

SFU에서 먼저 깨진 것
내가 구현 전에 적을 기준은 네 가지다. 라이브와 결과물 경로를 분리한다. 녹화가 제품 약속인지 옵션인지 확인한다. 수신 단말의 최저 사양을 정한다. 지연 목표와 비용 한계를 숫자로 둔다. 이 기준을 먼저 적지 않으면 “일단 미디어 서버를 붙인다”는 식의 결정이 되고, 나중에 기능이 늘 때마다 구조가 흔들린다. 성능 목표를 합의할 때도 단어를 구체적으로 써야 한다.
“빠르게”가 아니라 라이브 지연 목표를 몇 ms로 둘지, 녹화 파일 생성은 세션 종료 후 몇 분 안에 끝낼지, 방송 시청자는 몇 초 지연까지 허용할지 정한다. 목표가 달라야 경로도 달라진다. 라이브 목표를 녹화 job에 적용하면 비용이 과해지고, 녹화 목표를 라이브에 적용하면 대화가 불편해진다. 실시간 실패와 결과물 실패를 같은 회색 오류로 뭉개면 운영자가 원인을 찾기 어렵다. 특히 SFU에서는 재현 조건을 같이 적어야 의미가 있었다.
저성능 단말 지원은 양쪽 모두에서 고민해야 한다. SFU는 낮은 레이어를 보내 수신 부담을 줄일 수 있다. MCU는 아예 합성된 단일 스트림을 보내 클라이언트 일을 줄일 수 있다. 어느 쪽이 나은지는 기능에 따라 다르다. 작은 썸네일만 필요한 사용자는 SFU의 낮은 레이어로 충분할 수 있다. 매우 약한 기기에서 복잡한 화면 구성을 보여줘야 한다면 MCU 결과물이 더 안정적일 수 있다.

처음에 세웠던 가정
보안 검토에서도 두 구조는 다른 질문을 만든다. SFU는 누가 어떤 스트림을 구독할 수 있는지, 방 권한과 토큰이 미디어 서버까지 제대로 전달되는지가 중요하다. MCU는 거기에 더해 원본과 결과물을 누가 열람하고 내려받을 수 있는지, 임시 파일을 언제 삭제하는지가 중요하다. 서버가 미디어를 열어 보는 순간 개인정보와 감사 로그의 무게가 커진다.
비용 상한을 기능별로 두는 것도 중요하다. 실시간 경로는 방이 열려 있는 동안 계속 비용이 난다. 결과물 경로는 job 단위로 비용을 계산할 수 있다. 대규모 방송에서 시청자마다 MCU 합성을 하면 비용이 터지지만, 하나의 합성 결과를 CDN으로 배포하면 다른 모델이 된다. 반대로 소규모 회의 녹화 하나를 위해 약간의 인코딩 비용을 내는 것은 충분히 합리적일 수 있다.
운영 문구도 분리해야 한다. 실시간 경로에서는 “가까운 미디어 서버로 다시 연결하는 중”, “상대방 상태에 맞춰 화질을 낮추는 중” 같은 문장이 필요하다. 결과물 경로에서는 “녹화 파일을 만드는 중”, “화면 공유를 포함해 다시 처리하는 중”, “원본을 보존하고 재시도하는 중” 같은 문장이 맞다. 같은 미디어 서버라도 사용자가 기다리는 이유가 다르면 문장도 달라야 한다.
SFU는 미디어를 선택적으로 전달한다. 서버는 스트림을 받아 필요한 수신자에게 보내고, 가능하면 디코딩과 재인코딩을 피한다. 그래서 지연이 낮고 참여자가 늘 때 업로드 fan-out을 줄이기 좋다. MCU는 미디어를 열어 보고 합성하거나 변환한다. 서버 비용과 지연은 커지지만, 녹화 파일이나 방송 화면처럼 완성된 결과를 만들 수 있다. 두 구조는 같은 문제를 다른 방식으로 푸는 것이 아니라, 애초에 잘하는 일이 조금 다르다.
그래서 설계 문서에는 “SFU 사용” 또는 “MCU 사용”보다 “라이브 참여 경로”, “녹화 생성 경로”, “시청자 배포 경로”를 먼저 쓰는 편이 낫다. 각 경로마다 지연 목표, 비용 상한, 실패 시 보존할 데이터가 다르다. 그 뒤에 SFU와 MCU를 배치하면 선택이 훨씬 덜 감정적이다. 특히 SFU에서는 재현 조건을 같이 적어야 의미가 있었다.

가정을 깨는 반례
핵심만 남기면 SFU와 MCU는 경쟁 관계가 아니다. SFU는 낮은 지연과 선택 전달에 강하고, MCU는 합성 결과물과 단순한 수신 경험에 강하다. 둘을 같이 쓰면 복잡하지만, 경로를 분리하면 오히려 각 기능의 책임이 선명해진다. SFU가 녹화를 전혀 못 하는 것은 아니지만, 최종 레이아웃 합성이나 후처리에는 MCU 성격의 pipeline이 필요할 수 있다. PonsLink에서는 이 구분이 특히 중요할 수 있다.
상담 중 실시간 대화는 끊기면 안 된다. 그러나 상담 기록, 요약 영상, 공유용 결과물은 일관된 출력이 중요하다. PonsWarp에서도 직접 연결, relay, cloud drop을 승패가 아니라 사용자 시간과 데이터 무게에 맞춘 선택지로 보았듯, SFU와 MCU도 기능별 선택지로 봐야 한다. 기술 이름보다 경계가 먼저다. 사용자 지원 문서도 구조 선택의 영향을 받는다. 실시간 연결 문제는 네트워크, 권한, 브라우저 상태를 안내해야 한다.
녹화 지연 문제는 처리 시간과 재시도, 원본 보존 여부를 안내해야 한다. 방송 품질 문제는 시청자 네트워크와 배포 경로를 안내해야 한다. 같은 WebRTC 기반 기능이라도 지원 문장은 다르다. 문서가 다르면 내부 로그도 달라야 한다. 그래서 SFU와 MCU를 공부할 때 마지막 질문은 “어느 쪽이 더 좋은가”가 아니다. “이 기능의 사용자는 지금 무엇을 기다리고 있는가”다.
대화를 기다리면 지연이 우선이고, 파일을 기다리면 완성도가 우선이며, 방송을 기다리면 배포 안정성이 우선이다. 사용자가 기다리는 대상이 정해지면 기술 선택은 훨씬 차분해진다. 나중에 기능이 커질수록 하이브리드 구조가 자연스러워진다. 내부 참여자는 SFU, 녹화는 MCU, 대규모 배포는 CDN이나 별도 streaming pipeline이 맡을 수 있다. 이 구조는 처음 볼 때 복잡하지만, 한 경로에 모든 책임을 밀어 넣는 것보다 오래 간다.
복잡함을 숨기기보다 경계로 관리하는 쪽이 낫다. 기능 출시 순서도 이 구분을 따라가면 덜 위험하다. 먼저 라이브 통화의 안정성을 만들고, 그다음 녹화 구독자를 붙이고, 마지막에 합성 결과물이나 방송용 경로를 확장하는 식이다. 처음부터 모든 기능을 같은 미디어 서버 설정으로 해결하려 하면 문제 원인을 찾기 어렵다. 어떤 기능을 켠 뒤 지연이 늘었는지, 어떤 job이 비용을 키웠는지 알 수 있어야 한다.
SFU를 설명할 때 서버/클라이언트/사용자 중 누구 문장으로 말하는지 먼저 고르면 논쟁이 줄었다.
SFU와 MCU를 선택지로 두기
경로를 나누면 기능 우선순위도 보인다. 상담 중인 화면은 SFU를 타고 낮은 지연으로 전달한다. 동시에 녹화용 구독자가 필요한 스트림을 받아 저장하거나 MCU pipeline으로 넘긴다. 방송 기능이 있다면 내부 참여자는 SFU로 대화하고, 외부 시청자는 합성된 단일 스트림을 받을 수 있다. 이렇게 하면 복잡해 보이지만 각 경로의 목적은 선명해진다. 문제가 생겼을 때도 실시간 경로 문제인지 결과물 경로 문제인지 분리할 수 있다.
실제 설계 회의에서는 “우리도 SFU를 써야 하나요, MCU를 써야 하나요”라는 질문보다 “사용자가 기다리는 것은 라이브 화면인가, 저장된 결과물인가”라는 질문이 더 낫다. 라이브 화면은 늦으면 바로 불편하다. 저장된 결과물은 조금 늦게 나와도 정확한 레이아웃과 안정된 음질이 중요하다. 같은 미디어라도 사용자가 기대하는 시간이 다르면 구조가 달라진다.
팀 간 책임도 달라진다. 프론트엔드는 사용자 상태와 권한 문구를 다루고, 서버는 signaling과 방 정책을 다루며, 미디어 인프라는 SFU와 MCU pipeline을 다룬다. 결과물 기능이 붙으면 저장소와 백그라운드 job도 들어온다. 이때 “미디어 서버 문제”라고 한 덩어리로 부르면 협업이 어려워진다. 각 경로의 소유자와 관측 지표를 정해야 장애 때 헤매지 않는다. 데이터 보존 정책도 선택을 가른다.
라이브 경로는 지나가면 끝나는 데이터일 수 있지만, 녹화와 요약은 나중에 다시 열람된다. 사용자가 결과물을 다운로드하거나 공유한다면 그 파일은 제품의 산출물이다. 산출물에는 버전, 생성 시각, 원본 보존 여부, 재처리 가능성이 붙는다. SFU와 MCU를 비교할 때 미디어 서버 성능만 보면 이 부분을 놓치기 쉽다.
구현과 운영에 남긴 조건
한 구조로 모든 요구를 해결하려고 하면 문제가 생긴다. SFU만 생각하면 녹화와 고정 레이아웃이 뒤늦게 어려워진다. 각 수신자가 보는 화면이 다르기 때문에 “공식 결과물”을 만들려면 별도 처리가 필요하다. MCU만 생각하면 실시간 지연과 서버 비용이 먼저 터진다. 모든 참여자의 미디어를 열고 다시 인코딩하면 서버가 빠르게 무거워진다.
기능마다 우선순위를 나눠야 한다. 실패도 이 기준으로 갈린다. SFU 경로에서 흔한 문제는 수신자별 품질 선택 실패, region 지연, 서버 egress 비용, 특정 참여자의 uplink 부족이다. MCU 경로에서는 인코딩 큐, 합성 지연, 서버 CPU/GPU 부족, 원본 보존 실패가 더 중요하다. 같은 “영상이 늦다”라는 문의라도 원인이 다르면 대응이 완전히 다르다. 실시간 방에서 늦는 것과 녹화 파일 생성이 늦는 것은 같은 장애 이름으로 묶으면 안 된다.
*비교표의 핵심은 우열이 아니라 기준이다. 지연, 비용, 합성, 확장을 따로 보아야 한다. 결국 SFU와 MCU의 비교는 기술 취향 문제가 아니다. 낮은 지연, 낮은 클라이언트 부담, 서버 비용, 결과물 일관성, 복구 가능성 사이에서 무엇을 먼저 둘지 고르는 일이다. 한쪽이 다른 쪽을 대체한다고 생각하면 기능이 커질수록 설명이 꼬인다. 처음부터 경로를 나눠 두면, 나중에 녹화나 방송 같은 요구가 들어와도 “기존 통화 구조를 망치지 않고 어디에 붙일지”를 차분히 판단할 수 있다.
장애 격리도 구조 선택에 영향을 준다. SFU가 죽으면 현재 통화가 흔들린다. MCU job이 실패하면 실시간 통화는 끝났지만 녹화 결과가 늦어질 수 있다. 두 실패는 사용자에게 다르게 알려야 한다. “통화 연결이 불안정합니다”와 “녹화 파일 생성이 지연되고 있습니다”는 완전히 다른 문장이다. 내부적으로도 다른 알람과 다른 재시도 정책을 가져야 한다.
'[SFU vs MCU SFU와 MCU는 경쟁 관계가 아니라 선택지다'을 관통하는 질문은 이 섹션에서도 같았고, 답만 더 구체적이 됐다.
아직 열어 둔 비용
이 선택은 나중에 팀의 운영 습관도 바꾼다. SFU 알람은 현재 사용자의 경험을 바로 흔들 가능성이 높아 빠른 대응이 필요하다. MCU 알람은 결과물 지연이나 재처리 실패로 이어질 수 있어 queue와 저장소 상태를 같이 봐야 한다. 같은 미디어라는 이유로 같은 대시보드에만 묶어 두면 중요한 차이를 놓친다. 아키텍처를 그릴 때는 한 장에 모든 선을 넣으려 하지 않는 편이 좋다.
라이브 참여 경로, 녹화 생성 경로, 외부 시청 경로를 따로 그린 뒤 마지막에 연결점을 표시한다. 한 그림에 모두 넣으면 SFU와 MCU가 서로 경쟁하는 것처럼 보인다. 따로 그리면 각각의 입출력이 다르다는 사실이 드러난다. 라이브 경로의 출력은 현재 화면이고, 녹화 경로의 출력은 파일이며, 방송 경로의 출력은 다수 시청자에게 전달되는 단일 또는 적응형 스트림이다.
나는 이 비교를 라이브 무대와 편집실로 나누면 이해가 쉬웠다. 라이브 무대에서는 관객에게 빠르게 보여 주는 것이 중요하다. 약간의 품질 조정은 감수해도 지연이 커지면 안 된다. 편집실에서는 시간이 조금 더 걸려도 결과물이 일정해야 한다. 자막, 레이아웃, 녹화 품질, 후처리가 중요하다. SFU는 라이브 무대의 교통정리에 가깝고, MCU는 편집실의 제작 과정에 가깝다.
화상회의를 예로 들면 실시간 대화에서는 지연이 가장 민감하다. 상대의 말이 늦게 오면 대화가 끊긴다. 이때는 SFU가 자연스럽다. 참여자별 상태에 맞춰 스트림을 전달하고, 수신자에게 필요한 품질을 고르게 한다. 반대로 회의가 끝난 뒤 저장할 녹화본은 지연보다 결과의 일관성이 중요하다. 누가 언제 크게 보였는지, 화면 공유가 어느 위치에 들어갔는지, 오디오가 어떻게 섞였는지가 더 중요하다.
이때는 MCU 성격의 처리가 필요할 수 있다. 나는 이런 결정을 문서화할 때 표 하나로 끝내지 않고, 기능별 사용자 문장을 같이 적는 편이 좋다고 본다. 라이브에서는 “상대방 네트워크에 맞춰 화질을 조정합니다”가 자연스럽다. 녹화에서는 “세션 종료 뒤 결과 파일을 만들고 있습니다”가 맞다. 방송에서는 “시청자용 화면을 준비하고 있습니다”가 맞다.
문장이 달라지면 내부 경로도 달라져야 한다. 마지막 점검은 “무엇을 쓸까”가 아니라 “어떤 기능에 어떤 경로가 맞는가”를 묻는다.
마치며
*라이브 경로와 결과물 경로를 나눠 그리면 SFU와 MCU의 자리가 더 자연스럽게 보인다. 비용 모델도 다르게 잡아야 한다. SFU는 주로 네트워크 egress와 region 배치가 크게 보인다. MCU는 CPU/GPU와 인코딩 시간이 크게 보인다. 두 비용은 스케일 방식이 다르다. 100명이 보는 세션에서 모든 사람에게 합성 영상을 실시간으로 따로 만들면 비용이 감당하기 어렵다. 반대로 하나의 녹화 파일이 필요한 작업이라면 서버에서 합성하는 비용을 낼 수 있다.
사용자가 어떤 결과를 기대하는지가 비용 판단의 출발점이다. 조합 방식도 한 가지가 아니다. 실시간으로는 SFU를 쓰고, 필요한 스트림만 별도 recorder가 구독해 MCU pipeline으로 넘길 수 있다. 반대로 대규모 방송에서는 내부 회의는 SFU로 유지하되 외부 시청자에게는 합성된 단일 스트림을 줄 수 있다. 이렇게 쓰면 기술 이름 하나로 시스템을 설명하기 어렵지만, 기능 경계는 더 정확해진다.에서 MCU의 비용과 쓸모를 봤다.에서는 미디어 서버 이전에, 브라우저끼리 연결 자체가 왜 어려운지 다시 내려가 본다.