May 29, 2023

coTurn performance upgrade

coTurn performance upgrade

TURN relay server performance: load balance and network optimization

이번 포스트는 위 사이트의 내용을 구글 번역기를 통해서 정리해둔 내용입니다.

TURN 릴레이 서버 성능: 부하 분산 및 네트워크 최적화

이 TURN 서버는 node.js 및 nginx에서 사용하는 것과 유사한 혼합 작업 모델을 사용합니다. 비동기 IO는 다중 CPU 하드웨어를 활용하기 위해 스레딩 모델과 결합됩니다. 스레드 수는 제한되어 있고(CPU 수에 가까움) 리소스 소비가 최적입니다. 많은 클라이언트 연결을 동시에 처리할 수 있습니다. TURN 서버는 epoll(Linux), kqueue(BSD 및 Mac OS X), 이벤트 포트(Solaris), poll(Cygwin) 또는 select를 통해 운영 체제에 새 이벤트가 발생할 때 알림을 받아야 한다고 알려줍니다. 새 패킷이 도착하거나 새 타이머 이벤트가 발생하면 TURN 서버가 깨어나서 콜백을 실행합니다. 각 이벤트별 작업은 매우 짧기 때문에 시스템은 거의 실시간에 가까운 반응 시간을 갖습니다(효율적인 미디어 트래픽 처리에 필요함).

물론 많은 TURN 세션이 관련된 고부하 시나리오에서 턴서버 프로세스는 사실상 휴면 시간이 없으며 세미 풀 모드로 작동합니다.

비교적 장기적인 작업(데이터베이스 상호 작용, CLI 처리)의 경우 TURN 서버는 별도의 스레드를 사용하므로 트래픽 처리 처리는 더 긴 작업의 영향을 받지 않습니다.

시스템은 효율성과 이식성을 위해 C 언어로 구현됩니다. IO 및 타이머 이벤트 다중화를 위해 libevent2 라이브러리가 사용됩니다.

TURN 서버는 또한 네트워크 프로토콜 서버에 특정한 몇 가지 최적화를 통합합니다. 예를 들어 "풀" 처리의 일부 요소가 포함됩니다(일반적인 "푸시" 접근 방식과 반대).

각 TURN 세션(할당)은 비교적 적은 리소스를 소비합니다.

  • 할당에는 자체 스레드나 프로세스가 없습니다.
  • 할당은 일반적으로 동일한 스레드 내에 유지되므로 컨텍스트 전환 및 잠금이 줄어듭니다.
  • 할당은 다른 할당과 많은 시스템 리소스를 공유합니다.

물론 TURN 세션에는 여전히 리소스가 필요하며 여전히 CPU 전력과 네트워크 처리량을 소비합니다. 각 시스템은 규모에 상관없이 여전히 제한된 수의 TURN 할당(수천 또는 수만 개의 일반 트래픽 스트림)을 처리할 수 있습니다. 이 문서는 그 수를 최대화하는 것에 관한 것입니다.

최대 동시 세션 수에 영향을 미치는 사항:

  • 미디어 그룹 :

    1. 사용할 코덱(페이로드 크기).
    2. 패킷 간격.
  • 네트워크 위상 및 프로토콜 그룹

    1. ISP 퍼포먼스
    2. P2P 세션
    3. 관련 프로토콜 (TCP, UDP 또는 TLS)
    4. TLS가 관련된 경우 TLS 세션의 매개변수(무거운 정도)
    5. 클라이언트가 밸런싱을 위해 서버의 300오류(리다이렉션)를 대체할 수 있는지 여부(WebRTC 클라이언트는 현재 불가능).
    6. 라운드로빈 DNS 방식을 사용할 수 있는가?
  • 하드웨어, OS 및 소프트웨어 설정 그룹

    1. NIC 수
    2. How advanced are the NICs.
    3. 시스템 메모리 및 버스 성능(많은 트래픽이 통과함).
    4. CPU 수 및 CPU 성능(캐시 등).
    5. OS 유형 및 버전.
    6. NIC가 OS와 얼마나 잘 통합되어 있는지(드라이버가 전체 NIC 기능을 사용하는지 여부).
    7. 시스템이 처리할 수 있는 파일 설명자 수(전체 및 프로세스당 제한). 일반적으로 이것은 ulimit 시스템 매개변수입니다. 프로세스별 및 시스템 전체 ulimit를 늘리는 방법은 시스템 설명서를 참조하십시오. 각 TURN 할당은 적어도 1개 이상의 파일 디스크립터를 사용합니다(서로 다른 유형의 세션은 다른 수의 파일 디스크립터를 사용하고 다른 네트워크 엔진은 이와 관련하여 다르게 작동합니다). 시스템 제한이 허용하는 것보다 더 많은 세션을 열려고 하면 TURN 서버 콘솔이나 로그 파일에 "Too many open files"와 같은 오류가 표시됩니다.

데이터베이스 최적화

  • 가장 빠른 데이터베이스 옵션은 SQLite입니다. 프로세스 간 또는 네트워크 통신이 필요하지 않기 때문에 데이터베이스 관리 라이브러리가 TURN 서버 프로세스에 직접 연결됩니다. 그러나 다음과 같은 경우 더 강력한 데이터베이스 관리 시스템(예: PostgreSQL, MySQL, Redis 또는 MongoDB)이 필요할 수 있습니다.

    1. 데이터베이스는 수천 개 이상의 레코드입니다.
    2. 추가 보안이 필요한 경우
    3. 다른 프로세스가 TURN 서버와 동시에 TURN 데이터베이스에 능동적으로 액세스하려는 경우;
    4. 데이터베이스가 여러 TURN 서버에서 공유되는 경우.
  • 간결하고 단순한 설정에서 SQLite는 가장 간단하고 빠른 옵션입니다.

네트워크 운영 성능 최적화

TURN 서버 성능은 운영 체제가 TCP/IP 스택 작업을 얼마나 효율적으로 처리하는지에 따라 크게 달라집니다. 성능 최적화는 여러 접근 방식을 조합하여 달성할 수 있습니다.

  • "소프트웨어 RSS": 패킷 조정(RPS)을 수신합니다.
    네트워크 카드가 RSS를 지원하지 않으면 소프트웨어에서 해당 기능을 에뮬레이트하는 OS(예: 최신 버전의 BSD 및 Linux)를 사용할 수 있습니다. RSS 및 RPS를 켜는 방법을 알아보려면 OS의 설명서를 읽으십시오. RSS 및 RPS에 대한 일반적인 설명은 다음에서 찾을 수 있습니다.

  • 여러 시스템 간의 로드 밸런싱.

이것은 가장 효율적이고 가장 효율적인 성능 조정 방법입니다. 사용 가능한 시스템 수에 비례하여 거의 선형에 가까운 성능 개선이 가능합니다. 사실상 무제한 확장성을 달성할 수 있습니다.

여기에는 세 가지 옵션이 있습니다.

  1. 요청을 TURN 서버 그룹의 구성원으로 리디렉션하는 네트워킹 부하 분산 장비를 설정합니다. 일반적으로 동일한 클라이언트의 일부 TURN 세션이 정보를 공유해야 하기 때문에 동일한 클라이언트 IP에서 동일한 서버로 요청을 리디렉션하는 데 주의해야 합니다. 서로 다른 TURN 세션이 상호 작용해야 하는 두 가지 경우가 있습니다. RTP/RTCP 연결 쌍(RFC 5766)과 TCP 릴레이(RFC 6062)입니다. 이러한 기능을 사용하지 않는 경우 간단한 네트워크 로드 밸런싱으로 충분합니다. 이러한 기능을 사용하는 경우 동일한 TURN 서버에 전체 클라이언트 IP(모든 네트워크 포트 포함)를 매핑해야 합니다. 또한,
  2. 라운드 로빈 DNS를 사용하여 덜 복잡한 체계를 설정합니다. 클라이언트는 모든 요청을 동일한 DNS 검색 TURN 서버로 보내야 합니다. 이 체계는 모든 사용 사례를 지원합니다.
  3. ALTERNATE-SERVER 옵션(--alternate-server 옵션)과 함께 내장 밸런싱 기능을 사용하십시오. 이 경우 클라이언트는 모든 요청을 동일한 대체 서버 주소로 보내야 합니다. 단일 시스템을 TURN 서버 클러스터의 "프론트 엔드"로 설정하고 해당 "로드 banacer" 시스템은 아무 작업도 수행하지 않습니다. 대체 서버 IP 주소와 함께 모든 클라이언트에 300 ALTERNATE-SERVER 오류를 반환하므로 클라이언트가 다른 서버에 다시 연결합니다. 대체 서버가 라운드 로빈 방식으로 선택되면 TURN 서버의 로드 밸런싱 클러스터가 있습니다.
  • 단일 시스템 내에서 로드 밸런싱 및 최적화.

이 섹션은 주로 2.6.32-431 이전 커널이 있는 Linux 시스템 또는 3.0에서 3.8 커널을 위한 것입니다. 예를 들면 CentOS 6.4 및 Debian Wheezy가 있습니다. Cygwin 사용자도 동일한 기술을 적용할 수 있습니다.

이 섹션은 다음에 적용 되지 않습니다 .

  1. ArchLinux, Debian Sid, Fedora와 같은 Linux 커널 3.9 이상이 있는 시스템;

  2. 2.6 라인의 최신 Linux 커널이 있는 시스템(CentOS 6.5와 같은 2.6.32-431 이상);

  3. BSD 시스템;

  4. 솔라리스 시스템;

  5. 맥 OS X;

    • 해당 시스템의 사용자는 이 섹션을 건너뛸 수 있습니다. 귀하의 TURN 서버 아키텍처는 귀하의 플랫폼에 대해 매우 미세하게 조정되어 있으며 이미 있는 그대로 합리적으로 최적입니다. 턴서버 프로세스가 시작되면 시스템에 가장 적합한 성능 옵션이 자동으로 선택됩니다.

이전 Linux 시스템 시스템을 사용하는 경우에도 여전히 우수한 성능을 얻을 수 있습니다. 계속 읽으십시오.

이전에 말했듯이 TURN 서버 성능은 주로 운영 체제가 TCP/IP 스택 작업을 얼마나 효율적으로 처리하는지에 달려 있습니다. 일반적으로 스택의 TCP 부분은 적절하게 최적화되지만 UDP 처리는 종종 차선책입니다. 지금까지 일반적인 UDP 스택 구현은 TURN에서 사용되는 것과 같은 "영구적인" UDP 세션에 대해 잘 조정되지 않았습니다. 예를 들어, 기본적으로 Linux 커널은 128개의 버킷에 있는 모든 UDP 소켓을 해시합니다. 수천 개의 UDP 세션이 있는 경우 비효율적으로 처리되는 UDP 소켓이 많이 있습니다.

즉, Linux 커널에서 UDP를 구현하면 해시 테이블을 사용하여 소켓 구조를 저장합니다. 이전 2.6.32 커널(예: CentOS 6.0-6.4의 기본값)에서 이 해시 테이블은 128개의 항목을 갖도록 하드코딩됩니다. 따라서 많은 수의 소켓을 사용하면 테이블의 성능이 각 수신 패킷에 대해 통과해야 하는 연결 목록으로 저하됩니다.

2.6.33 이전의 Linux 커널이 있는 경우 커널 코드에서 하드코딩된 해시 크기를 변경하고 커널을 다시 컴파일할 수 있습니다. 최신 커널이 있는 경우 커널 재컴파일 없이 이를 수행할 수 있습니다. 커널 2.6.33은 구성 가능한 UDP 해시 테이블 크기와 IP+port로 키가 지정된 두 번째 UDP 해시 테이블을 도입했습니다(이전에는 포트만 사용). "uhash_entries" 부팅 시 커널 변수를 설정하여 해시 테이블 크기를 구성할 수 있습니다(예: /etc/grub.conf에서). 최상의 성능을 위해 65536으로 설정하십시오.

다른 OS에도 비슷한 문제가 있습니다. 구성 지침은 OS 설명서를 확인하십시오.

TURN 서버는 다중 스레드 네트워크 패킷 라우팅 시스템으로 설계되었습니다. 그러나 멀티스레딩이 항상 특정 시스템 구성에 가장 적합한 옵션은 아닙니다. 기본 시작 TURN 서버 구성은 메모리, 스레드 선호도, 캐시 및 CPU 리소스 간, 그리고 TCP와 UDP 일반적인 "바닐라" OS 네트워킹 스택 구현 간의 절충안입니다. 이것은 특정 하드웨어, 특정 OS 또는 특정 로드 패턴에 맞게 조정된 특수 시스템이 아닙니다. TURN 서버 설계는 가능한 응용 프로그램의 범위가 매우 넓기 때문에 특정 플랫폼의 특정 응용 프로그램에 대해 100% 최적이 아닐 수 있습니다. 하지만 어디에서나 사용할 수 있을 만큼 충분히 좋아야 합니다.

TURN 서버 매개변수 -m을 사용하면 스레딩 구성을 조정할 수 있습니다. "-m 0" 매개변수(또는 "--relay-threads=0")를 사용하여 멀티스레딩을 끌 수 있습니다. 모든 네트워크 패킷 처리를 하나의 스레드 내에서 유지하여 컨텍스트 전환 등을 제거합니다. 이는 시스템에 더 효율적인 옵션일 수 있습니다. 인증 프로세스가 일반 패킷 라우팅을 보유하지 않아야 하기 때문에 여전히 별도의 인증 스레드가 있습니다.

"-m 0" 옵션을 사용하고 CPU 코어당 하나씩 시스템에서 여러 TURN 서버를 실행할 수 있습니다. 그것은 아마도 확장성 측면에서 최고의 성능 옵션일 것입니다. 각 TURN 서버에는 자체 네트워크 수신 주소와 자체 중계 IP 및/또는 중계 포트 범위가 있어야 하므로 구성이 복잡하지만 성능은 최고가 될 것입니다. ALTERNATE-SERVER 메커니즘을 사용하여 전체 "팩"을 외부 세계에 단일 "초기" TURN 서버 프런트 엔드로 표시할 수 있습니다.

  • 효율적인 이벤트 다중화

대규모 TURN 서버의 경우 다중 소켓을 효율적으로 처리하는 것이 가장 심각한 문제가 될 수 있습니다. TURN 서버는 이를 위해 libevent2 도구를 사용합니다. Libevent2는 현재 플랫폼에서 사용 가능한 가장 효율적인 이벤트 다중화 기능을 활용합니다. * Linux: epoll * BSD 및 Mac OS X: kqueue * Solaris: 이벤트 포트 * Cygwin: poll

이러한 기능 중에서 kqueue는 아마도 가장 발전된 것입니다.

따라서 엄청난 수의 소켓이 있는 경우 BSD 시스템은 특히 TCP 프로토콜 성능이 중요한 경우 매력적인 옵션이 될 수 있습니다. 예를 들어 DragonFlyBSD는 성능 지향적인 BSD 변형입니다. FreeBSD도 좋은 선택입니다.

클라이언트 트래픽이 대부분 UDP(또는 DTLS)를 사용하는 경우 최신 Linux 커널 버전(Google 네트워킹 패치 포함)이 유리할 수 있습니다. 최근 Linux 커널은 몇 개의 "프론트 엔드" 소켓을 통해 다중 스레드 환경에서 UDP 처리를 허용합니다(동일한 스레드에 속한 모든 세션은 동일한 UDP 소켓을 공유합니다). 소켓 수가 적을수록 이벤트 다중화 라이브러리에 의한 트래픽 처리가 더 효율적입니다. 따라서 Google 커널 패치가 있는 시스템은 가장자리가 있습니다(작성 ​​당시 CentOS 6.5, ArchLinux 및 Fedora).

모든 유형의 다양한 로드를 포함하는 우리의 결합된 테스트는 일반적으로 FreeBSD 9.x와 DragonflyBSD가 TURN 서버용 플랫폼으로서 최고의 성능을 보인다는 것을 보여줍니다. 그 이유를 분석하는 것은 매우 어렵습니다. 그러나 마일리지는 다를 수 있습니다.