Hur vi snabbade upp videokodningen med åtta gånger

Hur vi snabbade upp videokodningen med åtta gånger

Varje dag tittar miljontals tittare på videor på Internet. Men för att videon ska bli tillgänglig måste den inte bara laddas upp till servern utan också bearbetas. Ju snabbare detta sker, desto bättre för tjänsten och dess användare.

Jag heter Askar Kamalov, för ett år sedan gick jag med i Yandex videoteknikteam. Idag ska jag kort berätta för Habr-läsarna om hur vi, genom att parallellisera kodningsprocessen, lyckades avsevärt påskynda leveransen av video till användaren.

Det här inlägget kommer i första hand att vara av intresse för dem som inte tidigare har tänkt på vad som händer under huven på videotjänster. I kommentarerna kan du ställa frågor och föreslå ämnen för framtida inlägg.

Några ord om själva uppgiften. Yandex hjälper dig inte bara att söka efter videor på andra webbplatser, utan lagrar också videor för sina egna tjänster. Oavsett om det är ett originalprogram eller en sportmatch i luften, en film på KinoPoisk eller videor på Zen och News - allt detta laddas upp till våra servrar. För att användarna ska kunna se videon måste den förberedas: konverteras till önskat format, skapa en förhandsvisning eller till och med köra igenom teknik DeepHD. En oförberedd fil tar bara upp plats. Dessutom talar vi inte bara om optimal användning av hårdvara, utan också om hastigheten för leverans av innehåll till användarna. Exempel: en inspelning av det avgörande ögonblicket i en hockeymatch kan sökas efter inom en minut efter själva evenemanget.

Sekventiell kodning

Så användarens lycka beror till stor del på hur snabbt videon blir tillgänglig. Och detta bestäms huvudsakligen av omkodningshastigheten. När det inte finns några strikta krav på videouppladdningshastighet är det inga problem. Du tar en enda, odelbar fil, konverterar den och laddar upp den. I början av vår resa arbetade vi så här:

Hur vi snabbade upp videokodningen med åtta gånger

Klienten laddar upp videon till lagringen, Analyzer-komponenten samlar in metainformation och överför videon till Worker-komponenten för konvertering. Alla steg utförs sekventiellt. I det här fallet kan det finnas många kodningsservrar, men bara en är upptagen med att bearbeta en specifik video. Enkelt, transparent diagram. Det är där dess fördelar slutar. Detta schema kan endast skalas vertikalt (på grund av köp av kraftfullare servrar).

Sekventiell kodning med mellanresultat

För att på något sätt jämna ut den smärtsamma väntan kom branschen med ett snabbt kodningsalternativ. Namnet är missvisande, eftersom fullständig kodning faktiskt sker sekventiellt och tar lika lång tid. Men med ett mellanresultat. Tanken är denna: förbered och publicera en lågupplöst version av videon så snabbt som möjligt, och först därefter versioner med högre upplösning.

Å ena sidan blir video tillgänglig snabbare. Och det är användbart för viktiga händelser. Men å andra sidan blir bilden suddig, och det irriterar tittarna.

Det visar sig att du inte bara behöver bearbeta videon snabbt utan också bevara dess kvalitet. Detta är vad användarna förväntar sig av en videotjänst nu. Det kan tyckas att det räcker med att köpa de mest produktiva servrarna (och regelbundet uppgradera dem alla på en gång). Men detta är en återvändsgränd, eftersom det alltid finns en video som kommer att få även den mest kraftfulla hårdvaran att sakta ner.

Parallell kodning

Det är mycket mer effektivt att dela upp ett komplext problem i många mindre komplexa och lösa dem parallellt på olika servrar. Det här är MapReduce för video. I det här fallet är vi inte begränsade av prestanda för en server och kan skala horisontellt (genom att lägga till nya maskiner).

Förresten, idén att dela upp videor i små bitar, bearbeta dem parallellt och limma ihop dem är ingen hemlighet. Du kan hitta många referenser till detta tillvägagångssätt (till exempel på Habré rekommenderar jag ett inlägg om projektet DistVIDc). Men detta gör det inte enklare totalt sett, för du kan inte bara ta en färdig lösning och bygga in den i ditt hem. Vi behöver anpassa oss till vår infrastruktur, vår video och till och med vår belastning. I allmänhet är det lättare att skriva själv.

Så i den nya arkitekturen delade vi upp det monolitiska Worker-blocket med sekventiell kodning i mikrotjänster Segmenter, Tcoder, Combiner.

Hur vi snabbade upp videokodningen med åtta gånger

  1. Segmenter delar upp videon i fragment på cirka 10 sekunder. Fragment består av en eller flera GOPs (grupp bilder). Varje GOP är oberoende och kodad separat så att den kan avkodas utan referens till ramar från andra GOP. Det vill säga fragment kan spelas oberoende av varandra. Denna skärning minskar latensen, vilket gör att bearbetningen kan börja tidigare.
  2. Tcoder bearbetar varje fragment. Den tar en uppgift från kön, laddar ner ett fragment från lagringen, kodar det till olika upplösningar (kom ihåg att spelaren kan välja en version baserat på anslutningshastigheten), lägger sedan tillbaka resultatet i lagringen och markerar fragmentet som bearbetat i databasen. Efter att ha bearbetat alla fragment skickar Tcoder uppgiften för att generera resultat för nästa komponent.
  3. Combiner samlar ihop resultaten: laddar ner alla fragment gjorda av Tcoder, genererar strömmar för olika upplösningar.

Några ord om ljud. Den mest populära AAC-ljudcodec har en obehaglig funktion. Om du kodar fragment separat, kommer du helt enkelt inte att kunna limma ihop dem sömlöst. Övergångar kommer att märkas. Videocodec har inte detta problem. Teoretiskt kan du leta efter en komplex teknisk lösning, men det här spelet är helt enkelt inte värt ljuset ännu (ljud väger betydligt mindre än video). Därför kodas endast videon parallellt, och hela ljudspåret bearbetas.

Resultat

Tack vare parallell videobearbetning har vi avsevärt minskat fördröjningen mellan att en video laddas upp till oss och att den är tillgänglig för användarna. Tidigare kunde det till exempel ta två timmar att skapa flera fullständiga versioner av olika kvalitet för en FullHD-film som varar i en och en halv timme. Nu tar allt detta 15 minuter. Med parallell bearbetning skapar vi dessutom en högupplöst version ännu snabbare än en lågupplöst version med den gamla metoden för mellanresultat.

Och en sak till. Med det gamla tillvägagångssättet fanns det antingen inte tillräckligt med servrar eller så var de inaktiva utan uppgifter. Parallell kodning gör att du kan öka andelen järnåtervinning. Nu är vårt kluster med mer än tusen servrar alltid upptaget med något.

Det finns faktiskt fortfarande utrymme för förbättringar. Vi kan till exempel spara mycket tid om vi börjar bearbeta fragment av videon innan den kommer till oss i sin helhet. Som de säger, mer kommer.

Skriv i kommentarerna vilka uppgifter inom området att arbeta med video du skulle vilja läsa om.

Användbara länkar till branschkollegers erfarenheter

Källa: will.com

Lägg en kommentar