
Ogni giorno milioni di spettatori guardano video online. Ma per rendere un video accessibile, deve essere non solo caricato sul server, ma anche elaborato. Più velocemente avviene questo, meglio è per il servizio e i suoi utenti.
Mi chiamo Askar Kamalov, e un anno fa mi sono unito al team di tecnologie video di Yandex. Oggi racconterò brevemente ai lettori di Habr come, attraverso il parallelismo del processo di codifica, siamo riusciti ad accelerare notevolmente la consegna dei video agli utenti.
Questo post sarà particolarmente interessante per coloro che non hanno mai riflettuto su ciò che avviene dietro le quinte dei servizi video. Nei commenti puoi porre domande e proporre argomenti per futuri post.
Qualche parola sulla questione stessa. Yandex non solo aiuta a cercare video su altri siti, ma archivia anche video per i propri servizi. Che si tratti di un programma originale, di una partita sportiva in diretta, di un film su Kinopoisk o di clip su Zen e Notizie, tutto questo viene caricato sui nostri server. Affinché gli utenti possano guardare i video, è necessario prepararli: convertirli nel formato necessario, creare una miniatura o anche passarli attraverso la tecnologia . Un file non preparato occupa semplicemente spazio. Ed è una questione che riguarda non solo l'uso ottimale dell'hardware, ma anche la velocità di consegna dei contenuti agli utenti. Un esempio: una registrazione con un momento decisivo di una partita di hockey può essere cercata già un minuto dopo l'evento stesso.
Codifica sequenziale
Quindi, la felicità dell'utente dipende in gran parte da quanto rapidamente il video diventa disponibile. E questo è principalmente determinato dalla velocità di transcodifica. Quando non ci sono requisiti rigorosi per la velocità di pubblicazione dei video, non ci sono neanche problemi. Prendi un file unico e indivisibile, lo converti e lo carichi. All'inizio del nostro percorso, abbiamo lavorato in questo modo:

Il cliente carica il video nel vault, il componente Analyzer raccoglie i metadati e invia il video al componente Worker per la conversione. Tutte le fasi vengono eseguite in sequenza. Sebbene ci possano essere molti server per la codifica, solo uno è impegnato a elaborare un video specifico. Uno schema semplice e trasparente. Ma qui finiscono i suoi pregi. Questo schema può scalare solo verticalmente (acquistando server più potenti).
Codifica sequenziale con risultato intermedio
Per alleviare l'inevitabile attesa, nel settore è stata inventata una variante di codifica rapida. Un nome ingannevole, perché in realtà la codifica completa avviene in sequenza e richiede lo stesso tempo. Ma offre un risultato intermedio. L'idea è quella di preparare e pubblicare la versione video a bassa risoluzione il più rapidamente possibile, per poi seguire con versioni ad alta risoluzione.
Da un lato, il video è disponibile più rapidamente. Questo è utile per eventi importanti. Dall'altro, la qualità dell'immagine risulta sfocata, che irrita gli spettatori.
È fondamentale non solo elaborare rapidamente i video, ma anche preservarne la qualità. Questo è ciò che gli utenti si aspettano da un servizio video al giorno d'oggi. Potrebbe sembrare sufficiente acquistare i server più potenti (e aggiornarli regolarmente). Ma questo è un vicolo cieco, poiché ci sarà sempre un video che farà rallentare anche l'hardware più potente.
Codifica parallela
È molto più efficiente suddividere un compito complesso in molteplici compiti più semplici e risolverli in parallelo su server diversi. Una sorta di MapReduce per i video. In questo modo non ci limitiamo alle prestazioni di un singolo server e possiamo scalare orizzontalmente (aggiungendo nuove macchine).
A proposito, l'idea di frammentare i video in piccoli pezzi, elaborarli in parallelo e poi riunirli non è un segreto. Puoi trovare numerosi riferimenti a questo approccio (ad esempio, su Habr, consiglio un post sul progetto ). Ma questo non rende tutto più semplice, perché non puoi semplicemente prendere una soluzione pronta e integrarla con la tua. È necessaria un'adattamento alla nostra infrastruttura, ai nostri video e persino ai nostri carichi di lavoro. Insomma, è spesso più facile scrivere il proprio.
Nella nuova architettura del blocco monolitico Worker con codifica sequenziale, abbiamo suddiviso il sistema in microservizi Segmenter, Tcoder e Combiner.

- Segmenter suddivide il video in frammenti di circa 10 secondi. I frammenti sono composti da uno o più GOP (). Ogni GOP è indipendente e viene codificato separatamente, consentendo la decodifica senza fare riferimento ai frame di altre GOP. Ciò significa che i frammenti possono essere riprodotti indipendentemente l'uno dall'altro. Questa segmentazione riduce la latenza, permettendo di avviare l'elaborazione anticipatamente.
- Tcoder elabora ogni frammento. Prende un compito dalla coda, scarica il frammento dal deposito, lo codifica in diverse risoluzioni (ricordiamo che il lettore può scegliere la versione in base alla velocità della connessione), quindi ripone il risultato nuovamente nel deposito e segna il frammento come elaborato nel database. Dopo aver elaborato tutti i frammenti, Tcoder invia il compito per la generazione dei risultati al prossimo componente.
- Combiner raccoglie i risultati insieme: scarica tutti i frammenti creati da Tcoder e forma flussi per diverse risoluzioni.
Alcune parole sul suono. Il codec audio AAC, il più popolare, ha una sgradevole peculiarità. Se si codificano i frammenti separatamente, non sarà possibile unirli senza soluzione di continuità. Le transizioni saranno visibili. I codec video, invece, non hanno questo problema. Teoricamente, sarebbe possibile cercare una soluzione tecnica complessa, ma al momento non ne vale la pena (l'audio pesa notevolmente meno del video). Pertanto, codifichiamo parallelamente solo il video, mentre la traccia audio viene elaborata nella sua interezza.
Risultati
Grazie all'elaborazione parallela del video, abbiamo ridotto significativamente il ritardo tra il caricamento del video e la sua disponibilità per gli utenti. Ad esempio, in passato, per creare diverse versioni complete di qualità diversa per un film in FullHD della durata di un'ora e mezza, potevano servire fino a due ore. Ora, tutto questo richiede solo 15 minuti. Inoltre, nell'elaborazione parallela, riusciamo a creare una versione ad alta risoluzione anche più velocemente rispetto a una versione a bassa risoluzione con l'approccio precedente che prevedeva un risultato intermedio.
E un'ultima cosa. Con il vecchio approccio, a volte mancavano i server o rimanevano inattivi senza compiti. La codifica parallela aumenta la percentuale di utilizzo dell'hardware. Ora il nostro cluster, composto da oltre mille server, è sempre impegnato in qualche attività.
In realtà, c'è ancora molto da migliorare. Ad esempio, potremmo risparmiare significativamente tempo se iniziassimo a elaborare i frammenti video ancora prima che arrivino completamente. Come si suol dire, il meglio deve ancora venire.
Scrivete nei commenti quali argomenti legati alla lavorazione video vi piacerebbe leggere.
Link utili sulle esperienze dei colleghi del settore
Fonte: habr.com
