NGINX 매우 비효율적 인 대용량 mp4 파일 제공


8

현재 Centos 6.6 OS에서 nginx / 1.0.15를 실행하고 있습니다. 서버에는 다음과 같은 사양이 있습니다.

  • Intel (R) Atom (TM) CPU C2750 @ 2.40GHz (8 코어)
  • 32GB 램
  • 5 개의 6000GB 7200RPM (Raid 10)

문제

서버의 연결은 1Gbit / s이지만 400-500mbit / s 후에는 병목 현상이 발생합니다. 약 100 개의 연결에서 서비스가 감소하기 시작합니다. 서버 속도는 급격히 떨어집니다 (50 %의 대역폭을 사용할 수 있음에도 불구하고)

NGINX 서버는 정적 .mp4 파일을 제공하기위한 것입니다. 각 파일은 일반적으로 400-1200MB (평균 700MB)입니다.

많은 구성을 시도했지만 거의 모든 구성에서 동일한 결과를 얻습니다. 매우 실망했습니다 ..

서버로드도 0.3을 통과하지 않습니다.

구성에 명백히 잘못되었거나 잘못 안내 된 것이 있습니까? 무엇이든 도움이 될 것입니다.

구성

/etc/nginx/nginx.conf

user              nginx;
worker_processes  9;

error_log  /var/log/nginx/error.log;


pid        /var/run/nginx.pid;


events {
    worker_connections  51200;
    use epoll;
 }

worker_rlimit_nofile 600000;

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

#access_log  /var/log/nginx/access.log  main;
access_log off;

aio on;
sendfile        off;
tcp_nopush      off;
tcp_nodelay      on;

#keepalive_timeout  0;
keepalive_timeout  65;

output_buffers 1 3m;
#gzip  on;

include /etc/nginx/conf.d/*.conf;

open_file_cache          max=10000 inactive=5m;
open_file_cache_valid    2m;
open_file_cache_min_uses 1;
open_file_cache_errors   on;

}

/etc/nginx/conf.d/default.conf

server {
    listen       80 default_server sndbuf=32k;
    server_name  _;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    include /etc/nginx/default.d/*.conf;


    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /Videos/ {
        root /home;
        gzip off;
        gzip_static off;

        mp4;
        mp4_max_buffer_size   300m;
    }

    location /stats {
        stub_status on;
    }

    error_page  404              /404.html;
    location = /404.html {
        root   /usr/share/nginx/html;
    }


    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

1
너무 오래된 특정 이유가 있습니까? 안정적인 버전은 이제 1.8입니다.
poige

나는 1.8 안정이 아침의 nginx 업데이트 @poige
Kennysmoothx

@poige 또한 iiotop을 보면서 대부분의 nginx 작업자 프로세스가 일반적으로 최대 1918 kb / s Read로 버스트하는 것은 아닙니다. 내가 가질 수있는 버퍼 제한입니까?
Kennysmoothx

연락처 정보는 내 프로필을 참조하십시오.
poige

@Kennysmoothx는 파일 스트리밍 시간 동안 sysstat 및 ifstat의 출력을 공유합니다
Anatoly

답변:


5

더 나은 시작은 다음 규칙 세트 일 수 있습니다.

  1. 로깅 비활성화 및 accept_mutex
  2. sendfile 활성화
  3. sendfile_max_chunk 설정

구성 :

events {
    accept_mutex off;
}

access_log off;
sendfile on;
sendfile_max_chunk 512k;

새로운 Nginx (1.7.11 이상) 기능 스레드 풀이 실제로 도움이 될 수 있습니다.

location / {
    root /home;
    aio threads;
    mp4;
}

테스트 샘플에서는 대역폭을 1Gbps에서 최대 9Gbps로 크게 높일 수 있습니다. 아홉 번! 1Gbps 만 있지만 모두 활용합니다.

자세한 내용은 https://www.nginx.com/blog/thread-pools-boost-performance-9x/를 참조하십시오.


나는 오늘 이것을 시도했지만 불행히도 개선이 없었습니다. 내 nginx 작업자 프로세스가 1918kb / s 읽기 속도에서 최고를 차지하는 것으로 나타났습니다. 그 한계가 무엇인지 알 수 있습니까?
Kennysmoothx

@Kennysmoothx Nginx가 거의 없습니다. 대용량 파일을 효율적으로 제공하도록 거의 모든 것을 시도했기 때문에
Anatoly

@ Kennysmoothx 이것은 고대이지만 해결책을 찾았습니까? 나는 그들이 당신이 1Gbps에 도달하지 않는 이유 때문에 그들이 초과 판매하고있는 호스팅을 비난 할 것입니다. 동일한 구성으로 다른 호스팅을 시도해보십시오.
Michael Rogers

4

시작하기에 좋은 첫 번째 장소는 실제 .mp4 파일을 사용하는 것입니다.이 파일은 대개 방대한 개선 영역이 있습니다.

따라서 NGINX 또는 Apache 조정에서 길을 잃기 전에 먼저 .mp4 파일을 조정하십시오.

이 포스트 시네마틱은 각 프레임 변경이 필요한 영화 또는 텔레비전 쇼와 같습니다. 다시 말해, "The Croods"와 같은 동영상을 1fps (프레임 / 초)로 다시 트랜스 코딩하려고하면 품질이 눈에 띄지 않게 줄어 듭니다.

비 시네마틱은 코스 데웨어가 Udemy에 게시 한 웨비나와 같은 화면 캡처를 말합니다.

먼저 파일의 오디오 구성 요소를 고려하십시오. 오디오 컴포넌트가 주로 말하고있는 경우, ffmpeg를 사용하여 비디오 스트림을 복사 한 파일을 변경하지 않고 파일을 다시 트랜스 코딩하십시오 (변경 없음) + 스테레오 스트림을 모노로 변환하십시오. 많은 .mp4 파일 (비 시네마틱)의 경우 동영상 파일 크기의 약 1/3은 비디오 + 1/3은 왼쪽 오디오 채널 + 1/3은 오른쪽 오디오 채널입니다. 스테레오에서 모노로 변경하면 파일 크기가 상당히 줄어들 수 있습니다.

둘째, 다른 aac 인코더보다 훨씬 작은 파일을 생성 하는 FDK-AAC ( https://github.com/mstorsjo/fdk-aac )를 사용하여 오디오를 다시 트랜스 코딩 하십시오 . 오늘날 대부분의 ffmpeg 버전은 자동으로 FDK-AAC를 구축합니다. Macports조차도 이것을 구축합니다. FDK를 사용하려면 FDK 스테레오 오디오가 모노보다 훨씬 작게 압축 될 때 스테레오 트랙 +가 필요하므로 FDK를 사용하는 경우 스테레오를 사용하십시오.

셋째, 오디오의 경우 비트 전송률을 줄입니다. 여러 번 이것이 48k이므로 일반적으로 -ar 44100 (ffmpeg) 또는 음성 (low fi)으로 22050으로 떨어 뜨리는 것을 고려하십시오.

넷째, 비디오의 프레임 속도를 가능한 낮게 설정하십시오. 따라서 화면 캡처를 수행하는 경우 프레임은 10-60 초에 한 번만 변경 될 수 있으므로 -r $ fps를 사용하여 30-60fps에서 1-5fps까지 여러 번 프레임 속도를 떨어 뜨릴 수 있습니다. 파일 크기는 급감합니다.

여러 번 나는 1G마다 10-20M로 감소하는 비 영화 파일을 압축합니다.

다섯째, 빠른 시작 mov atom이 파일의 맨 앞에 있어야 파일을 다운로드하지 않고 스트리밍 할 수 있습니다.

내 ffmpeg fdk 매개 변수 ...

-c : libfdk_aac-프로파일 : a aac_he_v2-애프터 버너 1-표현식 explicit_sbr -vbr 5 -ac 2 -ar 44100

사실 여기 전형적인 ffmpeg 명령이 있습니다 ...

mp4 스크립트는 ffmpeg를 감싸는 래퍼입니다. 오디오 + 비디오 트랙이 영어로되어 있는지 (멀티 트랙 avi + mkv 파일의 경우) + ffmpeg 명령을 빌드하는 것과 같은 작업을 수행하는 것과 같은 작업을 수행합니다. 흥미로운 점은 실제 명령인데, 이는 수년간의 실험의 잔재입니다.

ffmpeg 극단적 압축을 통해 파일을 먼저 실행 한 다음 파일 무게가 너무 작거나 작은 지 확인하십시오. 웹 서버 조정이 필요하지 않습니다.

실험 영역 : -r $ fps + -v : crf + -v : preset + -ar bitrate

약간의 실험을 통해 가장 작은 파일 크기 + 허용 가능한 품질에 대한 설정을 제공합니다.

+ genpts + clearing SAR / DAR과 같은 많은 이상한 옵션이있어 .mp4 파일이 Roku 장치에서 재생되도록합니다. 모든 Roku 채널을 설정할 때를 대비하여 5 만 가구 이상에 무료로 접속할 수 있습니다.

내 ffmpeg 명령 ...

아이맥> mp4 --dr --noisy foo.avi

tc : diag = v :! h264 : mpeg4, a :! aac : ac3 title = 'Foo (TC)'Foo-640x480-veryfast-crf18-max-tc.mp4

cd '/Users/david/Downloads/Casper.A.Spirited.Beginning.1997.DVDrip.iNTERNAL.XviD-BPDcarrier'nice -19 ffmpeg -fflags + genpts -i "foo.avi"-map 0 : 0 -c : v libx264 -crf : v 18 -preset : v 매우 빠름 -tune : v film -level : v 4.1 -profile : v high -bufsize : v 5000k -vf setdar = dar = 0, setsar = sar = 0 -x264optprim = bt709 : transfer = bt709 : colormatrix = bt709 : fullrange = off -r 29.97 -movflags + faststart -map 0 : 1 -c : a libfdk_aac -profile : a aac_he_v2 -afterburner 1 -signaling explicit_sbr -vbr 5 -ac 2 -ar 44100- 메타 데이터 제목 = 'Foo (TC)'-threads 0 -f mp4 -benchmark Foo-640x480-veryfast-crf18-max-tc.mp4.tmp mv -f Foo-640x480-veryfast-crf18-max-tc.mp4.tmp Foo-640x480-veryfast-crf18-max-tc.mp4


5
이 문제는 Nginx를 사용하여 큰 파일을 효율적으로 제공하기 때문에 큰 도움이되지 않습니다.
unwichtich

2

multi_accept를 켜면 나에게 도움이되었습니다 (비디오는 약 중간에 멈췄으며 방문자는 다른 절반을 듣거나 볼 수 없었으므로 매우 실망했습니다).

이벤트에서 nginx.conf에 설정 한 것은 다음과 같습니다.

events {
worker_connections 768;
multi_accept on;
}

** 오늘은 LOL에서 작동합니다 ... 내일은 여전히 ​​완전히 작동하는지 확인해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.