Jak przyspieszyliśmy kodowanie wideo ośmiokrotnie

Jak przyspieszyliśmy kodowanie wideo ośmiokrotnie

Każdego dnia miliony widzów ogląda filmy w Internecie. Jednak aby film stał się dostępny, musi zostać nie tylko przesłany na serwer, ale także przetworzony. Im szybciej to nastąpi, tym lepiej dla serwisu i jego użytkowników.

Nazywam się Askar Kamalov, rok temu dołączyłem do zespołu technologii wideo Yandex. Dziś opowiem krótko czytelnikom Habr o tym, jak dzięki równoległości procesu kodowania udało nam się znacznie przyspieszyć dostarczanie wideo do użytkownika.

Ten post zainteresuje przede wszystkim tych, którzy wcześniej nie zastanawiali się nad tym, co dzieje się pod maską usług wideo. W komentarzach możecie zadawać pytania i sugerować tematy przyszłych postów.

Kilka słów o samym zadaniu. Yandex nie tylko pomaga wyszukiwać filmy w innych witrynach, ale także przechowuje filmy dla własnych usług. Niezależnie od tego, czy jest to autorski program, czy mecz sportowy nadawany na antenie, film w KinoPoisk, czy filmy w Zen i News - wszystko to jest przesyłane na nasze serwery. Aby użytkownicy mogli obejrzeć wideo, należy je przygotować: przekonwertować do wymaganego formatu, utworzyć podgląd, a nawet przepuścić technologię GłębokieHD. Nieprzygotowany plik po prostu zajmuje miejsce. Co więcej, mówimy nie tylko o optymalnym wykorzystaniu sprzętu, ale także o szybkości dostarczania treści użytkownikom. Przykład: nagranie decydującego momentu meczu hokejowego można wyszukać w ciągu minuty po samym wydarzeniu.

Kodowanie sekwencyjne

Zatem szczęście użytkownika w dużej mierze zależy od tego, jak szybko film stanie się dostępny. Zależy to głównie od szybkości transkodowania. Jeśli nie ma ścisłych wymagań dotyczących szybkości przesyłania wideo, nie ma problemów. Bierzesz pojedynczy, niepodzielny plik, konwertujesz go i przesyłasz. Na początku naszej podróży pracowaliśmy tak:

Jak przyspieszyliśmy kodowanie wideo ośmiokrotnie

Klient przesyła wideo do magazynu, komponent Analyzer zbiera metainformacje i przesyła wideo do komponentu Worker w celu konwersji. Wszystkie etapy wykonywane są sekwencyjnie. W takim przypadku może być wiele serwerów kodujących, ale tylko jeden jest zajęty przetwarzaniem określonego wideo. Prosty, przejrzysty schemat. Na tym kończą się jego zalety. Schemat ten można skalować jedynie w pionie (ze względu na zakup mocniejszych serwerów).

Kodowanie sekwencyjne z wynikiem pośrednim

Aby w jakiś sposób złagodzić bolesne oczekiwanie, branża wymyśliła opcję szybkiego kodowania. Nazwa jest myląca, bo tak naprawdę pełne kodowanie następuje sekwencyjnie i trwa równie długo. Ale z efektem pośrednim. Pomysł jest taki: jak najszybciej przygotować i opublikować wersję filmu w niskiej rozdzielczości, a dopiero potem wersje w wyższej rozdzielczości.

Z jednej strony wideo staje się dostępne szybciej. I przydaje się podczas ważnych wydarzeń. Ale z drugiej strony obraz okazuje się rozmazany, co denerwuje widzów.

Okazuje się, że trzeba nie tylko szybko przetworzyć wideo, ale także zachować jego jakość. Tego właśnie oczekują obecnie użytkownicy od usługi wideo. Może się wydawać, że wystarczy kupić najbardziej produktywne serwery (i regularnie je wszystkie na raz modernizować). Ale to ślepy zaułek, bo zawsze znajdzie się wideo, które spowolni nawet najpotężniejszy sprzęt.

Kodowanie równoległe

O wiele efektywniej jest podzielić złożony problem na wiele mniej skomplikowanych i rozwiązać je równolegle na różnych serwerach. To jest MapReduce dla wideo. W tym przypadku nie jesteśmy ograniczeni wydajnością jednego serwera i możemy skalować w poziomie (dodając nowe maszyny).

Nawiasem mówiąc, pomysł dzielenia filmów na małe kawałki, przetwarzania ich równolegle i sklejania nie jest jakąś tajemnicą. Można znaleźć wiele odniesień do tego podejścia (przykładowo na Habré polecam post o projekcie DistVIDc). Ale to wcale nie ułatwia sprawy, ponieważ nie można po prostu wziąć gotowego rozwiązania i wbudować go w swój dom. Potrzebujemy dostosowania do naszej infrastruktury, naszego wideo, a nawet naszego obciążenia. Ogólnie rzecz biorąc, łatwiej jest napisać własny.

Tak więc w nowej architekturze podzieliliśmy monolityczny blok Worker z kodowaniem sekwencyjnym na mikrousługi Segmenter, Tcoder, Combiner.

Jak przyspieszyliśmy kodowanie wideo ośmiokrotnie

  1. Segmenter dzieli wideo na fragmenty trwające około 10 sekund. Fragmenty składają się z jednego lub więcej GOP (grupa zdjęć). Każdy GOP jest niezależny i kodowany oddzielnie, dzięki czemu można go dekodować bez odniesienia do ramek z innych GOP. Oznacza to, że fragmenty można odtwarzać niezależnie od siebie. To fragmentowanie zmniejsza opóźnienia, umożliwiając wcześniejsze rozpoczęcie przetwarzania.
  2. Tcoder przetwarza każdy fragment. Pobiera zadanie z kolejki, pobiera fragment z pamięci, koduje go w różnych rozdzielczościach (pamiętaj, że gracz może wybrać wersję na podstawie szybkości połączenia), następnie umieszcza wynik z powrotem w pamięci i oznacza fragment jako przetworzony w bazie danych. Po przetworzeniu wszystkich fragmentów Tcoder wysyła zadanie wygenerowania wyników dla kolejnego komponentu.
  3. Combiner zbiera wyniki razem: pobiera wszystkie fragmenty utworzone przez Tcodera, generuje strumienie dla różnych rozdzielczości.

Kilka słów o dźwięku. Najpopularniejszy kodek audio AAC ma nieprzyjemną cechę. Jeśli kodujesz fragmenty osobno, po prostu nie będziesz w stanie ich płynnie skleić. Przejścia będą zauważalne. Kodeki wideo nie mają tego problemu. Teoretycznie można szukać skomplikowanych rozwiązań technicznych, ale ta gra po prostu nie jest jeszcze warta świeczki (audio waży znacznie mniej niż wideo). Dlatego równolegle kodowane jest tylko wideo, a przetwarzana jest cała ścieżka audio.

wyniki

Dzięki równoległemu przetwarzaniu wideo znacznie zmniejszyliśmy opóźnienie pomiędzy przesłaniem filmu do nas a udostępnieniem go użytkownikom. Na przykład wcześniej utworzenie kilku pełnych wersji o różnej jakości filmu FullHD trwającego półtorej godziny mogło zająć dwie godziny. Teraz to wszystko zajmuje 15 minut. Co więcej, dzięki przetwarzaniu równoległemu tworzymy wersję o wysokiej rozdzielczości jeszcze szybciej niż wersję o niskiej rozdzielczości przy starym podejściu do wyników pośrednich.

I jeszcze jedno. Przy starym podejściu albo nie było wystarczającej liczby serwerów, albo były one bezczynne i pozbawione zadań. Kodowanie równoległe pozwala zwiększyć udział recyklingu żelaza. Teraz nasz klaster składający się z ponad tysiąca serwerów jest zawsze czymś zajęty.

Tak naprawdę jest jeszcze wiele do poprawy. Możemy na przykład zaoszczędzić sporo czasu, jeśli zaczniemy przetwarzać fragmenty filmu, zanim dotrze on do nas w całości. Jak mówią, będzie ich więcej.

Napisz w komentarzach, o jakich zadaniach z zakresu pracy z wideo chciałbyś przeczytać.

Przydatne linki do doświadczeń kolegów z branży

Źródło: www.habr.com

Dodaj komentarz