NGINX Serving Large mp4-Dateien äußerst ineffizient

8

Ich verwende derzeit nginx / 1.0.15 unter einem Centos 6.6-Betriebssystem. Der Server hat die folgenden Spezifikationen:

  • Intel (R) Atom (TM) CPU C2750 bei 2,40 GHz (8 Kerne)
  • 32 GB RAM
  • 5 x 6000 GB 7200 U / min (RAID 10)

Das Problem

Der Server verfügt über eine 1-Gbit / s-Verbindung, erreicht jedoch nach 400-500 mbit / s Spitzen- und Engpässe. Bei ungefähr 100 Verbindungen nimmt der Service ab. Die Geschwindigkeit mit dem Server sinkt dramatisch (obwohl noch 50% Bandbreite verfügbar sind).

Der NGINX-Server dient ausschließlich zur Bereitstellung statischer MP4-Dateien. Jede Datei ist normalerweise 400-1200 MB groß (700 MB sind der Durchschnitt).

Ich habe viele, viele Konfigurationen ausprobiert und fast alle liefern die gleichen Ergebnisse. Ich bin äußerst frustriert.

Die Serverlast überschreitet auch nie 0,3.

Gibt es irgendetwas, das in meiner Konfiguration offensichtlich falsch oder falsch ist? Alles könnte helfen.

Die Konfigurationen

/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;
    }
}
Kennysmoothx
quelle
1
Gibt es einen bestimmten Grund, so veraltet zu sein? Die stabile Version ist jetzt 1.8.
Poige
@poige Ich habe Nginx heute Morgen auf 1.8 Stable aktualisiert
Kennysmoothx
@poige Auch beim Betrachten von iotop ist mir aufgefallen, dass die meisten, wenn nicht alle meiner Nginx-Worker-Prozesse normalerweise bis zu 1918 kb / s Read platzen. Ist das eine Puffergrenze, die ich haben kann?
Kennysmoothx
Kontaktinformationen finden Sie in meinem Profil.
Poige
@Kennysmoothx teilen die Ausgabe von sysstat und ifstat während der Datei-Streaming-Zeit
Anatoly

Antworten:

5

Der bessere Start können die folgenden Regeln sein:

  1. Deaktivieren Sie die Protokollierung und accept_mutex
  2. Aktivieren Sie sendfile
  3. setze sendfile_max_chunk

Aufbau:

events {
    accept_mutex off;
}

access_log off;
sendfile on;
sendfile_max_chunk 512k;

Der neue Nginx-Feature-Thread-Pool (1.7.11 oder neuer) kann in Ihrem Fall sehr hilfreich sein:

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

Bei Testbeispielen hilft es Ihnen erheblich, die Bandbreite von 1 Gbit / s auf 9 Gbit / s zu erhöhen. Neun Mal! Sie haben nur 1 Gbit / s, aber es macht alles ausgenutzt.

Weitere Details finden Sie unter: https://www.nginx.com/blog/thread-pools-boost-performance-9x/

Anatoly
quelle
Ich habe dies heute versucht und leider keine Verbesserungen. Ich habe bemerkt, dass meine Nginx-Worker-Prozesse bei 1918 kb / s Lesespitze zu toppen scheinen. Irgendeine Idee, wie hoch diese Grenze sein könnte?
Kennysmoothx
@Kennysmoothx es ist weniger wahrscheinlich, Nginx, weil Sie fast alles versucht haben, um es so zu konfigurieren, dass große Dateien effizient bereitgestellt werden
Anatoly
@Kennysmoothx das ist uralt, aber hast du jemals eine Lösung gefunden? Ich würde Ihrem Hosting die Schuld geben, dass sie möglicherweise zu viel verkaufen. Deshalb erreichen Sie nicht 1 Gbit / s. Probieren Sie ein anderes Hosting mit derselben Konfiguration aus, um zu sehen, was Sie erhalten.
Michael Rogers
4

Ein guter erster Ausgangspunkt sind die eigentlichen MP4-Dateien, bei denen es normalerweise massive Verbesserungsmöglichkeiten gibt.

Bevor Sie sich beim Optimieren von NGINX oder Apache verlieren, sollten Sie zuerst Ihre MP4-Dateien optimieren.

Für diesen Beitrag ist cinematic wie ein Film oder eine Fernsehsendung, in der jeder Bildwechsel erforderlich ist. Mit anderen Worten, der Versuch, einen Film wie "The Croods" auf 1 fps (Bild / Sekunde) neu zu codieren, würde die Qualität auf nicht beobachtbar reduzieren.

Und nicht-filmisch bezieht sich auf Screenshots wie Webinare, die unsere Kursunterlagen an Udemy senden.

Betrachten Sie zunächst die Audiokomponente der Datei. Wenn die Audiokomponente hauptsächlich spricht, verwenden Sie ffmpeg, um die Datei, in die Sie den Videostream kopieren (keine Änderung), erneut zu transkodieren und den Stereostream in Mono zu konvertieren. Bei vielen MP4-Dateien (nicht filmisch) ist ungefähr 1/3 der Filmdateigröße Video + 1/3 ist linker Audiokanal + 1/3 ist rechter Audiokanal. Durch den Wechsel von Stereo zu Mono kann die Dateigröße erheblich reduziert werden.

Zweitens: Transcodieren Sie Audio mit FDK-AAC ( https://github.com/mstorsjo/fdk-aac ) erneut, wodurch weitaus kleinere Dateien als mit anderen AAC- Encodern erstellt werden. Die meisten modernen Versionen von ffmpeg bauen heutzutage automatisch FDK-AAC. Sogar Macports baut dies jetzt. Eine Überlegung, damit FDK wirklich magisch ist, ist eine Stereospur + erforderlich, wenn FDK-Stereo-Audiokomprimierungen verwendet werden, die weitaus kleiner als Mono sind. Wenn Sie also FDK verwenden, bleiben Sie bei Stereo.

Drittens für Audio Bitrate reduzieren. Oft sind dies 48 KB, daher sollten Sie im Allgemeinen -ar 44100 (ffmpeg) oder für gesprochene (niedrige Fi) in Betracht ziehen, auf 22050 zu fallen.

Stellen Sie die Bildrate Ihres Videos so niedrig wie möglich ein. Wenn Sie also eine Bildschirmaufnahme machen, ändert sich ein Bild möglicherweise nur einmal in 10-60 Sekunden, sodass Sie die Bildrate mit -r $ fps senken können. Oft bleibt die Qualität von 30-60 fps auf 1-5 fps + gleich während die Dateigröße sinkt.

Oft komprimiere ich nicht-filmische Dateien, bei denen jedes 1G auf 10-20M reduziert wird.

Fünftens: Stellen Sie sicher, dass sich das Faststart-Mov-Atom vorne in Ihren Dateien befindet, damit Ihre Dateien gestreamt und nicht heruntergeladen werden können.

Meine ffmpeg fdk Parameter ...

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

In der Tat ist hier ein typischer vollständiger ffmpeg-Befehl ...

Das mp4-Skript ist nur ein Wrapper um ffmpeg, mit dem Sie beispielsweise erraten können, welche Audio- und Videospuren in Englisch vorliegen (für mehrspurige AVI + MKV-Dateien) und dann den Befehl ffmpeg erstellen. Interessant ist der eigentliche Befehl, der den Rest jahrelanger Experimente darstellt.

Versuchen Sie zuerst, Ihre Dateien durch ffmpeg extreme Komprimierung auszuführen, und prüfen Sie dann, ob die Dateigewichte so niedrig / klein sind, dass keine Optimierung des Webservers erforderlich ist.

Versuchsbereiche: -r $ fps + -v: crf + -v: voreingestellte + -ar Bitrate

Ein bisschen experimentieren gibt Ihnen die Einstellungen für kleinste Dateigröße + akzeptable Qualität.

Viele der seltsamen Optionen wie + genpts + Löschen von SAR / DAR sind vorhanden, um sicherzustellen, dass MP4-Dateien auf Roku-Einheiten abgespielt werden. Diese sind gut aufzubewahren, falls Sie jedes Mal Ihren eigenen Roku-Kanal einrichten. Dies ist eine kostenlose Möglichkeit, mehr als 5.000.000 Haushalte zu erreichen.

Mein ffmpeg Befehl ...

imac> mp4 --dr --noisy foo.avi

tc: diag = v :! h264: mpeg4, a :! aac: ac3 title = 'Foo (TC)' Foo-640x480-sehr schnell-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: ein libfdk_aac -profil: ein aac_he_v2 -afterburner 1 -signaling explizit_sbr -vbr 5 -ac 2 -ar 44100 - Metadatentitel = 'Foo (TC)' -Threads 0 -f mp4 -Benchmark Foo-640x480-sehr schnell-crf18-max-tc.mp4.tmp mv -f Foo-640x480-sehr schnell-crf18-max-tc.mp4.tmp Foo-640x480-veryfast-crf18-max-tc.mp4

David Favor
quelle
5
Diese Antwort ist nicht hilfreich, da das Hauptproblem darin besteht, große Dateien mit Nginx effizient bereitzustellen.
unwichtich
2

Das Einschalten von multi_accept hat bei mir funktioniert (das Video wurde ungefähr auf halber Strecke angehalten und der Besucher konnte die andere Hälfte nicht hören / sehen, sehr frustrierend).

Das einzige, was ich in nginx.conf unter den Ereignissen festgelegt habe, ist Folgendes:

events {
worker_connections 768;
multi_accept on;
}

** Es funktioniert heute LOL .... morgen müssen wir nur sehen, ob es noch voll abgespielt wird

kennyhendrick
quelle