화상 공유 기능 성능 개선 - boostcampwm-2022/web30-TODY GitHub Wiki

WebRTC 화상 공유 성능 개선

💡 WebRTC 화상 공유를 구현하기 위해 Mesh 방식을 적용한 후, 클라이언트 측 성능개선을 위해 SFU 방식으로 전환했습니다. 10인 연결 기준 클라이언트 CPU 점유율을 평균 75% → 55%로 개선했습니다. (4vCPU, 8GB Mem 사양)

목표

  • Mesh 방식 & SFU 방식을 통해 화상 공유 기능 구현
  • 두 방식의 성능 측정 및 비교
  • 라이브러리의 도움 없이 구현
  • 기대 : SFU로의 전환 시 클라이언트 측 성능 개선

배경 : 어떤 WebRTC 연결 방식을 적용해 구현할까?

  • WebRTC 연결 방식 조사

    • WebRTC를 이용한 화상 공유 구현 방식에는 Mesh, SFU, MCU 3가지 연결 방식이 있다. 이 중에서 Mesh(P2P)가 가장 간단한 구현 방식인데 다만 클라이언트 부하가 제일 심하다는 단점이 있다. 반면 SFU 방식은 Mesh 방식에 비해 클라이언트 부하가 적다.
  • Mesh 방식으로 구현한 후, SFU 방식으로 전환하여 두 방식의 성능을 비교하기로 했다.

성과

방식 인원 CPU 점유율 (최소~최대%) 메모리 사용량(MB) 딜레이 시간(s) 영상 끊김 (육안상) 화질 저하 (육안상)
Mesh 10 72~80 550 15 있음 없음
SFU 10 45~60 450 2 약간 있음 없음
  • Mesh 방식에서 SFU 방식으로 전환했을 때, 10인 연결 기준 클라이언트 CPU 점유율이 평균 75% → 55%로 개선되었다. 영상 딜레이 시간 또한 평균 15초 → 2초로 단축됐다. (4vCPU, 8GB Mem)

Mesh vs SFU 성능 측정

테스트 환경 1) 고사양 PC 클라이언트, 저사양 미디어/시그널링 서버

[ Mesh ] 고사양 클라이언트

인원 CPU 점유율(최소~최대 (평균)%) 메모리 사용량(MB) 딜레이 시간(s) 영상 끊김(육안상) 화질 저하(육안상)
2 4.2~6.9 410 0.1 없음 없음
3 6.7~9.9 380 0.1 없음 없음
4 9~12.2 410~450 0.2 없음 없음
5 9.6~15.9 440 0.2 없음 없음
6 15.1~20.8 460~520 0.2 없음 없음
7 20.0~24.1 490~530 0.2 없음 없음
8 22.1~28.5 520~560 0.2 없음 없음
  • 사양 : 6vCPU, 64GB Mem
  • 총평 : CPU 점유율, 메모리 사용량, GPU 메모리 사용량이 선형으로 증가했다. 반면 영상 실시간성 및 화질에는 저하 및 변화가 거의 없었다.

[ Mesh ] 시그널링 서버

인원 CPU 점유율(%) 메모리 사용량(%)
2 0.3 4.1
3 0.3 4.1
4 0.3 4.1
5 0.3 4.1
6 0.3 4.1
7 0.3 4.2
8 0.3 4.2
  • 사양 : 2vCPU, 2GB Mem, 50GB Disk
  • 총평 : mesh 방식에서는 역시 단순 signaling의 역할만 해서 그런지 cpu 점유율과 메모리 사용량 자체도 매우 낮고, 인원이 많아져도 cpu 점유율과 메모리 사용량에 그다지 변화가 보이지 않았다.

[ SFU ] 고사양 클라이언트

인원 CPU 점유율(최소~최대 (평균)%) 메모리 사용량(MB) 딜레이 시간(s) 영상 끊김(육안상) 화질 저하(육안상)
2 4~5.5 (4.5) 360 0.1 없음 없음
3 4.5~7.7 (5.5) 340~380 0.5 거의 없음 없음
4 3.5~6.5 (4.5) 360~400 1 약간 있음 약간 있음
5 2.5~5.8 (4) 340~390 3 있음 약간 있음
6 2.4~5.0 (3.5) 340~380 4~5 심함 있음
7 2.0~5.6 (3.5) 340~380 12 심함 심함
8 2.8~5.9 (4) 350 20 아주 심함 아주 심함
  • 사양 : 6vCPU, 64GB Mem
  • 총평 : CPU 점유율, 메모리 사용량은 변화가 거의 없었다. 6명부터 실시간성이 급격히 저하되었다. 8명에서는 영상이 거의 멈춰있었다.

[ SFU ] 저사양 미디어 서버

인원 CPU 점유율(%) 메모리 사용량(%)
2 80.4 33.8
3 170.2 35.7
4 182.1 39.1
5 192.3 44.5
6 185.8 46.6
7 176.8 45.4
8 180.2 48.8
  • 사양 : 2vCPU, 2GB Mem, 50GB Disk
  • 총평 : 기본적으로 메모리는 선형적으로 인원에 비해 증가하는 모습을 보였다. 2GB 메모리로도 괜찮았다. 하지만 cpu 점유율이 4명부터 한계점에 달하는 모습을 보였다. 그때부터 클라이언트 상에서 실시간성이 저하되는 모습을 보였다. 6명부터는 더욱 극심해졌다.

테스트 환경 2) 저사양 PC 클라이언트, 고사양 미디어/시그널링 서버

[ Mesh ] 저사양 클라이언트

인원 CPU 점유율(최소~최대 (평균)%) 메모리 사용량(MB) 딜레이 시간(s) 영상 끊김(육안상) 화질 저하(육안상)
2 19~23 230 0.1 없음 없음
3 41~50 300 0.1 없음 없음
4 65~70 360 0.1 없음 없음
5 65~78 390 1 없음 없음
6 73~80 390 2 없음 없음
7 77~80 450 3 약간 있음 없음
8 73~77 480 4 약간 있음 없음
9 75~80 500 20 있음 없음
10 72~80 550 15 있음 없음
  • 사양 : 4vCPU, 8GB Mem
  • 총평 : 인원이 7명이 되었을 때부터 딜레이가 많이 심해지기 시작했고, 영상 끊김이 시작되었다. 8명 부터는 소통이 거의 불가능한 수준이었다. Mesh 방식에서의 클라이언트 CPU 부하가 심하다는 것을 알 수 있었다. 저사양 클라이언트에서는 많은 인원과 사용하기 힘든 방식이라고 생각한다.

[ Mesh ] 시그널링 서버

인원 CPU 점유율(%) 메모리 사용량(%)
2 0.4 4.6
3 0.5 4.6
4 0.3 4.6
5 0.3 4.5
6 0.3 4.5
7 0.3 4.5
8 0.3 4.5
9 0.3 4.5
10 0.3 4.5
  • 사양 : 2vCPU, 2GB Mem, 50GB Disk
  • 총평 : 인원에 상관없이 점유율과 메모리 사용량이 일정하고 매우 낮았다. Mesh 방식에서는 peer 간 연결을 해줄 때만 서버에 부하가 일어나고 그 뒤로는 peer 끼리 미디어 스트림을 직접 공유하므로 당연하다면 당연한 결과로 보인다.

[ SFU ] 저사양 클라이언트

인원 CPU 점유율(최소~최대 (평균)%) 메모리 사용량(MB) 딜레이 시간(s) 영상 끊김(육안상) 화질 저하(육안상)
2 24~27 250 0.1 없음 없음
3 33~37 250 0.1 없음 없음
4 35~40 300 0.1 없음 없음
5 45~55 350 0.1 없음 없음
6 43~60 360 0.1 없음 없음
7 50~65 350 0.1 없음 없음
8 55~65 400 0.1 없음 없음
9 45~60 450 0.7 약간 있음 없음
10 45~60 450 2 약간 있음 없음
  • 사양 : 4vCPU, 8GB Mem
  • 총평 : CPU 점유율과 메모리 사용량이 선형으로 증가했으나, 9명 이상부터는 거의 증가하지 않았다. 또한 클라이언트의 사양이 낮음에도 불구하고 저사양의 미디어 서버를 사용했을 때에 비해 영상 딜레이 및 저하가 거의 발생하지 않았다.

[ SFU ] 고사양 미디어 서버

인원 CPU 점유율(%) 메모리 사용량(%)
2 50 2.3
3 150 2.5
4 300 2.5
5 400 2.6
6 650 2.6
7 1000 2.7
8 1400 2.7
9 1500 2.7
10 1600 2.8
  • 사양 : 32vCPU, 64GB Mem, 50GB Disk
  • 총평 : 기본적으로 CPU 점유율은 선형적으로 증가했고, 메모리 사용량은 모두 3%이하로 여유로운 모습을 보였다. 32cpu기 때문에 클러스터링 세팅까지 된다면 좀 더 개선을 할 수 있을 것 같다.