Wie wir die Videokodierung um das Achtfache beschleunigt haben

Wie wir die Videokodierung um das Achtfache beschleunigt haben

Jeden Tag schauen Millionen von Zuschauern Videos im Internet. Doch damit das Video verfügbar wird, muss es nicht nur auf den Server hochgeladen, sondern auch verarbeitet werden. Je schneller dies geschieht, desto besser für den Dienst und seine Nutzer.

Mein Name ist Askar Kamalov, vor einem Jahr bin ich dem Videotechnologie-Team von Yandex beigetreten. Heute werde ich den Habr-Lesern kurz erzählen, wie es uns durch die Parallelisierung des Kodierungsprozesses gelungen ist, die Bereitstellung von Videos an den Benutzer erheblich zu beschleunigen.

Dieser Beitrag wird vor allem für diejenigen interessant sein, die sich bisher noch keine Gedanken darüber gemacht haben, was unter der Haube von Videodiensten passiert. In den Kommentaren können Sie Fragen stellen und Themen für zukünftige Beiträge vorschlagen.

Ein paar Worte zur Aufgabe selbst. Yandex hilft Ihnen nicht nur bei der Suche nach Videos auf anderen Websites, sondern speichert auch Videos für seine eigenen Dienste. Ob eine Originalsendung oder ein ausgestrahltes Sportmatch, ein Film auf KinoPoisk oder Videos auf Zen und News – all das wird auf unsere Server hochgeladen. Damit Benutzer das Video ansehen können, muss es vorbereitet werden: in das erforderliche Format konvertiert, eine Vorschau erstellt oder sogar die Technologie durchlaufen DeepHD. Eine unvorbereitete Datei nimmt nur Speicherplatz in Anspruch. Darüber hinaus geht es nicht nur um die optimale Nutzung der Hardware, sondern auch um die Geschwindigkeit der Bereitstellung von Inhalten an Benutzer. Beispiel: Eine Aufzeichnung des entscheidenden Moments eines Eishockeyspiels kann innerhalb einer Minute nach dem eigentlichen Ereignis gesucht werden.

Sequentielle Kodierung

Die Zufriedenheit des Nutzers hängt also maßgeblich davon ab, wie schnell das Video verfügbar ist. Und diese wird hauptsächlich durch die Transkodierungsgeschwindigkeit bestimmt. Wenn es keine strengen Anforderungen an die Video-Upload-Geschwindigkeit gibt, gibt es keine Probleme. Sie nehmen eine einzelne, unteilbare Datei, konvertieren sie und laden sie hoch. Zu Beginn unserer Reise haben wir so gearbeitet:

Wie wir die Videokodierung um das Achtfache beschleunigt haben

Der Client lädt das Video in den Speicher hoch, die Analyzer-Komponente sammelt Metainformationen und überträgt das Video zur Konvertierung an die Worker-Komponente. Alle Phasen werden nacheinander durchgeführt. In diesem Fall kann es viele Codierungsserver geben, aber nur einer ist mit der Verarbeitung eines bestimmten Videos beschäftigt. Einfaches, transparentes Diagramm. Hier enden seine Vorteile. Dieses Schema ist nur vertikal skalierbar (aufgrund der Anschaffung leistungsstärkerer Server).

Sequentielle Kodierung mit Zwischenergebnis

Um das schmerzhafte Warten irgendwie zu verkürzen, hat die Branche eine schnelle Codierungsoption entwickelt. Der Name ist irreführend, denn tatsächlich erfolgt die vollständige Codierung sequentiell und dauert genauso lange. Allerdings mit einem Zwischenergebnis. Die Idee ist folgende: Erstellen und veröffentlichen Sie so schnell wie möglich eine Version des Videos mit niedriger Auflösung und erst dann Versionen mit höherer Auflösung.

Einerseits wird Video schneller verfügbar. Und es ist nützlich für wichtige Ereignisse. Andererseits wird das Bild jedoch unscharf, was den Betrachter nervt.

Es stellt sich heraus, dass Sie das Video nicht nur schnell verarbeiten, sondern auch seine Qualität beibehalten müssen. Das ist es, was Nutzer heutzutage von einem Videodienst erwarten. Es mag den Anschein haben, dass es ausreicht, die produktivsten Server zu kaufen (und sie alle regelmäßig auf einmal zu aktualisieren). Aber das ist eine Sackgasse, denn es gibt immer ein Video, das selbst die leistungsstärkste Hardware langsamer macht.

Parallele Kodierung

Es ist viel effizienter, ein komplexes Problem in viele weniger komplexe aufzuteilen und diese parallel auf verschiedenen Servern zu lösen. Dies ist MapReduce für Videos. In diesem Fall sind wir nicht auf die Leistung eines Servers beschränkt und können horizontal skalieren (durch Hinzufügen neuer Maschinen).

Die Idee, Videos in kleine Stücke zu zerlegen, parallel zu verarbeiten und zusammenzukleben, ist übrigens kein Geheimnis. Es gibt viele Hinweise auf diesen Ansatz (auf Habré empfehle ich beispielsweise einen Beitrag über das Projekt). DistVIDc). Aber das macht es insgesamt nicht einfacher, denn man kann nicht einfach eine fertige Lösung nehmen und in sein Zuhause einbauen. Wir müssen unsere Infrastruktur, unser Video und sogar unsere Auslastung anpassen. Im Allgemeinen ist es einfacher, selbst etwas zu schreiben.

Deshalb haben wir in der neuen Architektur den monolithischen Worker-Block mit sequentiellem Codieren in die Microservices Segmenter, Tcoder und Combiner unterteilt.

Wie wir die Videokodierung um das Achtfache beschleunigt haben

  1. Der Segmenter zerlegt das Video in Fragmente von etwa 10 Sekunden. Fragmente bestehen aus einer oder mehreren GOPs (Gruppe von Bildern). Jede GOP ist unabhängig und separat codiert, sodass sie ohne Bezug auf Frames von anderen GOPs decodiert werden kann. Das heißt, Fragmente können unabhängig voneinander abgespielt werden. Dieses Sharding reduziert die Latenz und ermöglicht einen früheren Beginn der Verarbeitung.
  2. Tcoder verarbeitet jedes Fragment. Es nimmt eine Aufgabe aus der Warteschlange, lädt ein Fragment aus dem Speicher herunter, kodiert es in verschiedene Auflösungen (denken Sie daran, dass der Player eine Version basierend auf der Verbindungsgeschwindigkeit auswählen kann), legt das Ergebnis dann zurück in den Speicher und markiert das Fragment als verarbeitet in der Datenbank. Nachdem alle Fragmente verarbeitet wurden, sendet Tcoder die Aufgabe, Ergebnisse für die nächste Komponente zu generieren.
  3. Combiner sammelt die Ergebnisse: lädt alle von Tcoder erstellten Fragmente herunter und generiert Streams für verschiedene Auflösungen.

Ein paar Worte zum Klang. Der beliebteste AAC-Audiocodec hat eine unangenehme Funktion. Wenn Sie Fragmente separat kodieren, können Sie sie einfach nicht nahtlos zusammenfügen. Übergänge werden spürbar sein. Bei Videocodecs tritt dieses Problem nicht auf. Theoretisch kann man nach einer komplexen technischen Lösung suchen, aber dieses Spiel ist einfach noch nicht die Kerze wert (Audio wiegt deutlich weniger als Video). Daher wird nur das Video parallel codiert und die gesamte Audiospur verarbeitet.

Ergebnisse

Dank der parallelen Videoverarbeitung haben wir die Verzögerung zwischen dem Hochladen eines Videos und der Bereitstellung für Benutzer erheblich verkürzt. Beispielsweise konnte es bisher zwei Stunden dauern, mehrere Vollversionen unterschiedlicher Qualität für einen eineinhalbstündigen FullHD-Film zu erstellen. Das alles dauert jetzt 15 Minuten. Darüber hinaus erstellen wir mit der Parallelverarbeitung noch schneller eine hochauflösende Version als eine niedrigaufgelöste Version mit dem alten Zwischenergebnis-Ansatz.

Und noch etwas. Beim alten Ansatz waren entweder nicht genügend Server vorhanden oder sie waren ohne Aufgaben im Leerlauf. Durch die Parallelkodierung können Sie den Anteil des Eisenrecyclings erhöhen. Jetzt ist unser Cluster aus mehr als tausend Servern immer mit etwas beschäftigt.

Tatsächlich gibt es noch Raum für Verbesserungen. Wir können beispielsweise viel Zeit sparen, wenn wir mit der Verarbeitung von Fragmenten des Videos beginnen, bevor es vollständig bei uns eintrifft. Wie sie sagen, kommt noch mehr.

Schreiben Sie in die Kommentare, über welche Aufgaben im Bereich der Arbeit mit Video Sie gerne lesen würden.

Nützliche Links zu den Erfahrungen von Branchenkollegen

Source: habr.com

Kommentar hinzufügen