벤자민의 블로그 2기 시작
2023년 6월 13일 갑작스러운 부친상을 격고나서 무언가를 한다라는 것에서 거의 손을 대지 않고 있었네요. 슬프다거나 그런 감정보다는 그냥 무언가 빠져버린
TURN relay server performance: load balance and network optimization
이번 포스트는 위 사이트의 내용을 구글 번역기를 통해서 정리해둔 내용입니다.
이 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 할당(수천 또는 수만 개의 일반 트래픽 스트림)을 처리할 수 있습니다. 이 문서는 그 수를 최대화하는 것에 관한 것입니다.
미디어 그룹 :
네트워크 위상 및 프로토콜 그룹
하드웨어, OS 및 소프트웨어 설정 그룹
가장 빠른 데이터베이스 옵션은 SQLite입니다. 프로세스 간 또는 네트워크 통신이 필요하지 않기 때문에 데이터베이스 관리 라이브러리가 TURN 서버 프로세스에 직접 연결됩니다. 그러나 다음과 같은 경우 더 강력한 데이터베이스 관리 시스템(예: PostgreSQL, MySQL, Redis 또는 MongoDB)이 필요할 수 있습니다.
간결하고 단순한 설정에서 SQLite는 가장 간단하고 빠른 옵션입니다.
TURN 서버 성능은 운영 체제가 TCP/IP 스택 작업을 얼마나 효율적으로 처리하는지에 따라 크게 달라집니다. 성능 최적화는 여러 접근 방식을 조합하여 달성할 수 있습니다.
"소프트웨어 RSS": 패킷 조정(RPS)을 수신합니다.
네트워크 카드가 RSS를 지원하지 않으면 소프트웨어에서 해당 기능을 에뮬레이트하는 OS(예: 최신 버전의 BSD 및 Linux)를 사용할 수 있습니다. RSS 및 RPS를 켜는 방법을 알아보려면 OS의 설명서를 읽으십시오. RSS 및 RPS에 대한 일반적인 설명은 다음에서 찾을 수 있습니다.
여러 시스템 간의 로드 밸런싱.
이것은 가장 효율적이고 가장 효율적인 성능 조정 방법입니다. 사용 가능한 시스템 수에 비례하여 거의 선형에 가까운 성능 개선이 가능합니다. 사실상 무제한 확장성을 달성할 수 있습니다.
여기에는 세 가지 옵션이 있습니다.
이 섹션은 주로 2.6.32-431 이전 커널이 있는 Linux 시스템 또는 3.0에서 3.8 커널을 위한 것입니다. 예를 들면 CentOS 6.4 및 Debian Wheezy가 있습니다. Cygwin 사용자도 동일한 기술을 적용할 수 있습니다.
이 섹션은 다음에 적용 되지 않습니다 .
ArchLinux, Debian Sid, Fedora와 같은 Linux 커널 3.9 이상이 있는 시스템;
2.6 라인의 최신 Linux 커널이 있는 시스템(CentOS 6.5와 같은 2.6.32-431 이상);
BSD 시스템;
솔라리스 시스템;
맥 OS X;
이전 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 서버용 플랫폼으로서 최고의 성능을 보인다는 것을 보여줍니다. 그 이유를 분석하는 것은 매우 어렵습니다. 그러나 마일리지는 다를 수 있습니다.