[Mesh 딥다이브] Mesh는 왜 사람이 늘수록 급격히 무거워질까
Mesh를 처음 볼 때는 가장 자연스러운 P2P 구조처럼 보였다. 모든 참여자가 서로 직접 연결되어 각자에게 미디어나 데이터를 보내면 중앙 서버는 가벼워진다. 두 명일 때는 설명도 쉽고 구현도 비교적 직관적이다. 문제는 사람이 한 명씩 늘어날 때마다 연결과 업로드 부담이 조용히 곱해진다는 점이다. Mesh는 소규모에서 단순하지만, 규모가 커질수록 각 클라이언트가 작은 서버처럼 일해야 한다. 아래에서는 Mesh을 중심으로, 깨진 가정과 다시 그은 경계를 순서대로 남긴다.

Mesh가 무거워진 지점
파일 전송 Mesh는 미디어와 다른 문제가 있다. 같은 파일을 여러 명에게 직접 보내면 송신자가 같은 데이터를 여러 번 업로드해야 한다. 받는 사람마다 속도가 다르면 가장 느린 수신자 때문에 큐 관리가 복잡해진다. 일부는 직접 받고 일부는 cloud 경로로 받게 할지, 전송 완료를 누가 확정할지 정해야 한다. 사람 수가 조금만 늘어도 단순한 1:1 전송과 다른 기능이 된다.
Mesh에서 먼저 정해야 할 것은 최대 방 크기다. “작은 방”이라는 말은 기준이 아니다. 1:1 파일 전송인지, 4명 스터디 통화인지, 8명 회의인지에 따라 완전히 다르다. 각 참여자의 업로드 목표 bitrate와 화면 공유 여부를 곱해 보면 금방 한계가 보인다. 예를 들어 한 사람이 2Mbps 스트림을 네 명에게 각각 보내야 하면 업로드만 8Mbps가 필요하다. 모바일망이나 카페 와이파이에서는 넉넉한 숫자가 아니다.
테스트도 방 전체 성공 여부만 보면 부족하다. A-B, A-C, B-C처럼 pair별 상태를 일부러 깨뜨려 봐야 한다. 한 명만 relay로 빠지는 경우, 한 명의 업로드만 느린 경우, 한 명이 탭을 백그라운드로 보낸 경우를 따로 본다. Mesh 장애는 대개 전체가 동시에 무너지는 모양보다 특정 연결에서 먼저 시작한다. 그 신호를 빨리 잡으면 품질 낮춤이나 topology 전환을 늦지 않게 할 수 있다.
Mesh의 어려움은 수식보다 체감에서 먼저 온다. 참여자 한 명이 늘 때마다 내 브라우저가 보내야 할 상대도 하나씩 늘어난다. 화면 공유까지 켜면 그 부담은 더 커진다. 같은 4명 방이라도 모두 카메라만 켠 경우와 한 명이 고해상도 화면을 공유하는 경우는 전혀 다르다. 그래서 방 인원 상한은 기능 소개 문구가 아니라 성능 예산의 일부로 다뤄야 한다.

처음에는 Mesh면 충분할 줄 알았다
실패 모양은 참여자별로 갈라진다. A와 B는 잘 연결됐지만 A와 C만 relay로 갈 수 있다. D의 업로드가 느려 모든 사람이 D 화면만 끊겨 볼 수 있다. 한 명이 브라우저를 백그라운드로 보내면 그 사람의 송신 상태가 흔들린다. 전체 방이 망가진 것이 아니라 특정 pair나 특정 송신자가 문제인 경우가 많다. 그래서 Mesh 로그는 방 단위만으로 부족하고 peer pair 단위 관측이 필요하다.
내가 Mesh 설계 앞에 두는 질문은 네 가지다. 참여자 수 상한을 숫자로 적었는가. 각 클라이언트의 업로드와 CPU 부담을 계산했는가. pair별 연결 상태와 relay 비율을 볼 수 있는가. 한계에 닿았을 때 SFU, 서버 경유, 품질 낮춤 같은 대체 경로가 있는가. 이 질문이 비어 있으면 Mesh는 데모에서는 가볍고 제품에서는 무거운 구조가 된다. Mesh를 처음 구현할 때는 연결 생성 코드가 반복되기 쉽다.
참가자가 들어올 때마다 새 PeerConnection을 만들고, 나갈 때마다 닫고, 화면 공유가 바뀔 때마다 track을 갈아 끼운다. 이 로직이 UI 이벤트와 섞이면 방 상태가 조금만 흔들려도 정리되지 않은 연결이 남는다. 방 멤버십, peer connection 수명, media track 수명을 분리해 두면 나중에 SFU로 옮길 때도 덜 아프다. Mesh를 제품에 넣는다면 “몇 명까지 지원”이라는 문구를 기술팀만의 내부 제한으로 두지 않는 편이 낫다.
사용자가 초대할 수 있는 인원, 품질 안내, 유료 플랜의 회의 규모가 모두 이 제한과 연결된다. 제한을 숨기면 초반에는 기능이 넓어 보이지만, 한계에 닿는 순간 제품이 거짓말을 한 것처럼 느껴진다. 작은 방에 강하다고 솔직히 말하는 편이 오래 간다. Mesh 장애는 방 전체 오류보다 특정 peer pair, 특정 송신자, 특정 네트워크 조건에서 자주 시작한다. 특히 Mesh에서는 재현 조건을 같이 적어야 의미가 있었다.

반례가 선명해진 순간
PonsLink와 PonsWarp 관점에서도 Mesh는 제한을 분명히 말해야 하는 구조다. 1:1 파일 전송이나 아주 작은 그룹의 임시 연결에는 직접 경로가 단순하고 빠를 수 있다. 하지만 여러 명에게 같은 데이터를 뿌리거나 모든 참여자 상태를 동시에 맞춰야 한다면 중앙 조율이 더 안전하다. PonsWarp의 Direct 경로가 의미 있으려면 방 크기, 파일 크기, relay fallback, backpressure 기준이 같이 있어야 한다. 품질 조절 정책도 미리 필요하다.
네트워크가 나빠졌을 때 모두에게 같은 해상도를 계속 보내려 하면 끊김이 심해진다. 특정 상대에게만 낮은 품질을 보내는지, 전체 품질을 낮추는지, 화면 공유 프레임레이트를 줄이는지 정해야 한다. Mesh에서는 중앙 서버가 품질을 대신 조절해 주지 않으므로 클라이언트가 더 많은 판단을 해야 한다. 이 판단이 없으면 사용자는 갑자기 멈춘 화면만 보게 된다.
Mesh는 서버 부담을 줄이는 대신 각 클라이언트의 업로드와 연결 관리를 키운다. 특히 Mesh에서는 재현 조건을 같이 적어야 의미가 있었다. 운영 도구도 Mesh에 맞게 달라져야 한다. 서버 중심 구조에서는 서버 지표만 봐도 꽤 많은 것을 알 수 있다. Mesh에서는 브라우저 쪽 stats가 없으면 방 품질을 제대로 해석하기 어렵다. 어떤 peer pair가 relay였는지, 누가 높은 packet loss를 겪었는지, 누가 화면 공유 중이었는지 모르면 문제를 “네트워크 불안정”으로 뭉개게 된다.
클라이언트 지표 수집은 선택이 아니라 Mesh 운영의 일부다. 두 명 통화에서 Mesh는 좋은 출발점이다. 서버는 signaling과 권한만 맡고, 미디어는 두 브라우저 사이로 흐른다. 지연도 낮고 구조도 이해하기 쉽다. 세 명, 네 명까지도 조건이 좋으면 버틸 수 있다. 하지만 회의가 길어지고 화면 공유가 들어가고 모바일 사용자가 섞이면 부담이 빨리 드러난다.
한 사람이 느린 업로드를 갖고 있으면 그 사람의 모든 송신 경로가 영향을 받는다. Mesh의 한계선도 운영하면서 다시 잡아야 한다. 4명까지 괜찮던 방이 화면 공유나 고해상도 카메라를 만나면 3명에서도 흔들릴 수 있다. 특정 브라우저나 모바일 환경에서 fan-out 부담이 커지면 전환 기준을 낮춰야 한다. topology는 배포 전에 한 번 정하는 값이 아니라 관측 지표를 보며 계속 조정하는 정책이다.
Mesh를 설명할 때 서버/클라이언트/사용자 중 누구 문장으로 말하는지 먼저 고르면 논쟁이 줄었다.
사람 수에 따라 경계를 다시 그리기
여기서 서버 비용만 보면 판단이 틀어진다. Mesh는 중앙 미디어 서버의 egress를 줄일 수 있지만 클라이언트의 업로드, CPU, 배터리, 네트워크 안정성을 소비한다. 사용자는 “서버 비용을 아꼈다”는 설명을 듣지 않는다. 화면이 끊기거나 노트북 팬이 돌거나 모바일 배터리가 빨리 줄어드는 경험을 한다. 제품 판단에서는 서버 청구서와 사용자 기기 부담을 함께 봐야 한다.
Mesh는 그래서 숫자와 문구를 함께 설계해야 한다. 몇 명까지 권장하는지, 어떤 조건에서 품질이 낮아지는지, 언제 다른 topology로 넘어가는지 사용자가 이해할 수 있어야 한다. 내부 구조를 모두 설명할 필요는 없지만 제한을 숨길 필요도 없다. 작은 방에 강한 구조라는 사실을 정확히 말하는 것이 가장 좋은 안내다. Mesh가 맞지 않는 순간에는 SFU나 서버 경유 구조를 고려해야 한다.
SFU는 각 클라이언트가 서버에 한 번 보내고 서버가 다른 참여자에게 전달한다. 중앙 egress는 늘지만 클라이언트 업로드는 줄고 방 크기를 키우기 쉽다. MCU는 서버가 미디어를 합성해 보내는 방식이라 서버 부담이 더 크지만 클라이언트는 단순해진다. Mesh, SFU, MCU는 우열이 아니라 비용을 어디에 둘지의 선택이다. Mesh 적합성은 참여자 수, 업로드 상한, 인코딩 부담, fallback 기준을 함께 봐야 한다.
마치며
사용자 장치 차이도 크다. 고성능 노트북에서는 5명 Mesh가 버틸 수 있지만 오래된 노트북이나 모바일 브라우저에서는 같은 방이 버겁다. 배터리 절약 모드, 발열, 브라우저 백그라운드 제한은 네트워크 지표만으로 설명되지 않는다. Mesh를 제품 기본값으로 삼으려면 최소 지원 장치와 브라우저 조건을 분명히 해야 한다. 그렇지 않으면 같은 기능이 사용자마다 전혀 다른 품질로 보인다.
Full Mesh에서는 n명이 있으면 각 참여자가 n-1명에게 보내고 n-1명에게 받는다. 전체 연결 수는 n(n-1)/2로 늘어난다. 세 명이면 연결이 3개라 괜찮아 보이지만, 여섯 명이면 15개, 열 명이면 45개가 된다. 미디어라면 각 참여자가 같은 영상을 여러 번 인코딩하거나 여러 경로로 보내야 하고, 파일이나 데이터 이벤트라도 송신 큐와 backpressure를 각각 봐야 한다. 그래서 Mesh는 topology 전환 계획과 함께 쓰는 편이 좋다.
1:1과 3명까지는 Mesh, 그 이상은 SFU, 네트워크가 막히면 relay, 대용량 파일은 cloud drop까지 염두에 두는 식이다. 특히 Mesh에서는 재현 조건을 같이 적어야 의미가 있었다. 다음에 Mesh를 다음에 코드를 짠다면 작은 방 상한부터 코드와 UI에 박아 둘 것이다. 성공 경로를 만든 뒤에는 일부러 느린 업로드, relay가 섞인 참여자, 화면 공유, 모바일 탭 전환을 넣어 본다. 그때도 사용자가 왜 품질이 바뀌는지 이해하고 계속 진행할 수 있다면 Mesh는 좋은 선택이다.
그렇지 않다면 더 중앙화된 topology로 옮기는 편이 솔직하다. Mesh의 장점은 중앙 미디어 서버 없이 작은 방을 빠르게 연결할 수 있다는 점이다. 단점은 사람이 늘 때 서버 대신 사용자 기기가 그 비용을 떠안는다는 점이다. 그래서 “사람이 늘수록 급격히 무거워진다”는 말은 단순한 수식이 아니라 제품 경험의 경고다. 연결 수가 늘고, 업로드가 늘고, 디코딩이 늘고, 장애 원인도 pair별로 흩어진다.
'[Mesh 딥다이브 Mesh는 왜 사람이 늘수록 급격히 무거워질까'을 관통하는 질문은 이 섹션에서도 같았고, 답만 더 구체적이 됐다.