NGINX che serve file mp4 di grandi dimensioni in modo estremamente inefficiente


8

Attualmente sto eseguendo nginx / 1.0.15 su un sistema operativo Centos 6.6. Il server ha le seguenti specifiche:

  • CPU Intel (R) Atom (TM) C2750 a 2,40 GHz (8 core)
  • Ram da 32 GB
  • 5 x 6000 GB 7200 RPM (Raid 10)

Il problema

Il server ha una connessione a 1 Gbit / s, tuttavia supera e colli di bottiglia dopo 400-500 mbit / s. Il servizio inizia a diminuire a circa 100 connessioni .. e la velocità con il server diminuisce drasticamente (nonostante la larghezza di banda del 50% sia ancora disponibile)

Il server NGINX serve esclusivamente per la gestione di file .mp4 statici. Ogni file è in genere 400-1200 MB (700 MB è la media)

Ho provato molte configurazioni e quasi tutte mi danno gli stessi risultati .. Sono estremamente frustrato ..

Anche il caricamento del server non supera mai lo 0,3.

C'è qualcosa di palesemente sbagliato o sbagliato nella mia configurazione? Qualunque cosa potrebbe aiutare.

Le configurazioni

/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
Qualche motivo specifico per essere così obsoleto? La versione stabile ora è 1.8.
poige,

@poige Stamattina ho aggiornato nginx a 1.8
Kennysmoothx il

@poige Inoltre ho notato mentre guardavo iotop, la maggior parte se non tutti i miei processi di lavoro nginx di solito esplodevano fino a 1918 kb / s Leggi. È un limite di buffer che posso avere?
Kennysmoothx,

Vedi il mio profilo per le informazioni di contatto.
poige,

@Kennysmoothx condivide l'output di sysstat e ifstat durante il tempo di streaming del file
Anatoly,

Risposte:


5

L'inizio migliore può essere l'insieme delle seguenti regole:

  1. disabilita la registrazione e accetta_mutex
  2. abilita sendfile
  3. imposta sendfile_max_chunk

Configurazione:

events {
    accept_mutex off;
}

access_log off;
sendfile on;
sendfile_max_chunk 512k;

Il nuovo pool di thread delle funzionalità di Nginx (1.7.11 o più recenti) può essere davvero utile nel tuo caso:

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

Sui campioni di test ti aiuta notevolmente ad aumentare la larghezza di banda da 1 Gbps a 9 Gbps. Nove volte! Hai solo 1 Gbps ma rende tutto utilizzato.

Vedi maggiori dettagli: https://www.nginx.com/blog/thread-pools-boost-performance-9x/


Ho provato questo oggi e sfortunatamente nessun miglioramento. Ho notato che i miei processi di lavoro nginx sembrano superare i 1918kb / s di lettura spead, hai idea di quale possa essere quel limite?
Kennysmoothx,

@Kennysmoothx è meno probabile Nginx perché hai provato quasi tutto per configurarlo per servire in modo efficiente file di grandi dimensioni
Anatoly

@Kennysmoothx questo è antico, ma hai mai trovato una soluzione? Vorrei dare la colpa al tuo hosting che potrebbero essere in eccesso per questo motivo non raggiungi 1 Gbps. Prova un hosting diverso con la stessa configurazione per vedere cosa ottieni.
Michael Rogers,

4

Un buon primo punto di partenza è con i file .mp4 reali, dove di solito ci sono enormi aree di miglioramento.

Quindi, prima di perderti nell'ottimizzazione di NGINX o Apache, ottimizza i tuoi file .mp4.

Per questo post il cinema è come un film o un programma televisivo in cui è necessario cambiare ogni fotogramma. In altre parole, provare a ritrascrivere un film come "The Croods" a 1 fps (frame / secondo) ridurrebbe la qualità a inattaccabile.

E non cinematografico si riferisce a catture di schermate come i webinar i nostri corsi pubblicati su Udemy.

Innanzitutto, considera il componente audio del file. Se il componente audio parla principalmente, usa ffmpeg per ritrascrivere il file in cui copi il flusso video (nessuna modifica) + converti il ​​flusso stereo in mono. Per molti file .mp4 (non cinematografici) circa 1/3 della dimensione del file del filmato è video + 1/3 è il canale audio sinistro + 1/3 è il canale audio destro. Passando da stereo a mono, è possibile ridurre notevolmente le dimensioni del file.

In secondo luogo, ritrascrivere l'audio utilizzando FDK-AAC ( https://github.com/mstorsjo/fdk-aac ) che produce file molto più piccoli rispetto ad altri encoder aac. Oggi la maggior parte delle versioni moderne di ffmpeg costruisce automaticamente FDK-AAC. Anche Macports ora lo costruisce. Una considerazione, per fare FDK, la vera magia richiede una traccia stereo + quando si utilizzano compressioni audio stereo FDK molto più piccole di mono, quindi se si utilizza FDK, attenersi allo stereo.

Terzo, per l'audio ridurre il bitrate. Molte volte questo è 48k, quindi in generale -ar 44100 (ffmpeg) o per parlato (basso fi) considera di scendere a 22050.

Quindi, imposta il frame rate del tuo video il più basso possibile. Quindi, se stai facendo una cattura dello schermo, un fotogramma può cambiare solo una volta in 10-60 secondi, quindi puoi abbassare il frame rate usando -r $ fps, molte volte da 30-60 fps a 1-5 fps + la qualità rimane la stessa mentre la dimensione del file precipita.

Molte volte comprimo file non cinematografici in cui ogni 1G si riduce a 10-20M.

In quinto luogo, assicurati che l'atomo mov faststart sia nella parte anteriore dei tuoi file, in modo che i tuoi file possano essere trasmessi in streaming anziché scaricati.

I miei parametri fdmp fdk ...

-c: a libfdk_aac -profile: a aac_he_v2 -afterburner 1 -signaling esplicito_sbr -vbr 5 -ac 2 -ar 44100

In effetti, ecco un tipico comando completo ffmpeg ...

Lo script mp4 è solo un wrapper di ffmpeg che fa cose come indovinare quali tracce audio + video sono in inglese (per i file multitraccia avi + mkv) + quindi crea il comando ffmpeg. Ciò che interessa è il comando effettivo, che è il residuo di anni di esperimenti.

Prova prima a eseguire i tuoi file tramite la compressione estrema di ffmpeg, quindi vedi se i pesi dei file sono così bassi / piccoli, non è necessaria l'ottimizzazione del server Web.

Aree di esperimento: -r $ fps + -v: crf + -v: preset + -ar bitrate

Un po 'di sperimentazione ti darà le impostazioni per la dimensione del file più piccola + qualità accettabile.

Molte delle strane opzioni come + genpt + clearing SAR / DAR sono lì per garantire la riproduzione di file .mp4 su unità Roku. Questi sono buoni da conservare, nel caso in cui ogni installazione del proprio canale Roku, che è un modo gratuito per raggiungere oltre 5.000.000 di famiglie.

Il mio comando ffmpeg ...

imac> 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 veryfast -tune: v film -level: v 4.1 -profile: v high -bufsize: v 5000k -vf setdar = dar = 0, setsar = sar = 0 -x264opts colorprim = 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 esplicito_sbr -vbr 5 -ac 2 -ar 44100 - metadata title = '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
Questa risposta non è utile perché il problema principale è servire in modo efficiente file di grandi dimensioni con Nginx.
unwichtich,

2

L'attivazione di multi_accept ha funzionato per me (il video si fermava a metà strada e il visitatore non era in grado di ascoltare / guardare l'altra metà, molto frustrante).

L'unica cosa che ho impostato in nginx.conf sotto gli eventi è questa:

events {
worker_connections 768;
multi_accept on;
}

** Funziona oggi LOL .... domani dovremo solo vedere se continua a giocare pienamente

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.