毎日、何百万人もの視聴者がインターネットでビデオを視聴しています。ただし、ビデオを利用できるようにするには、サーバーにアップロードするだけでなく、処理する必要もあります。これが早く起こるほど、サービスとそのユーザーにとっては良いことになります。
私の名前はアスカル・カマロフです。1 年前に Yandex ビデオ テクノロジー チームに加わりました。今日は、Habr 読者に、エンコード プロセスを並列化することで、ユーザーへのビデオ配信を大幅に高速化する方法について簡単に説明します。
この投稿は主に、ビデオ サービスの内部で何が起こっているかについてこれまで考えたことのない人に興味深いものです。コメントでは、質問したり、今後の投稿のトピックを提案したりできます。
タスク自体について一言。 Yandex は、他のサイトでビデオを検索できるだけでなく、独自のサービス用にビデオを保存することもできます。オリジナルの番組でも、放送中のスポーツの試合でも、KinoPoisk の映画でも、Zen and News のビデオでも、これらはすべて当社のサーバーにアップロードされます。ユーザーがビデオを視聴するには、必要な形式に変換したり、プレビューを作成したり、テクノロジーを実行したりするなどの準備が必要です。
シーケンシャルエンコーディング
したがって、ユーザーの幸福は、ビデオがどれだけ早く利用可能になるかに大きく依存します。これは主にトランスコーディング速度によって決まります。ビデオのアップロード速度に厳密な要件がない場合は、問題はありません。単一の分割できないファイルを取得し、変換してアップロードします。私たちの旅の初めに、私たちは次のように取り組みました。
クライアントはビデオをストレージにアップロードし、Analyzer コンポーネントはメタ情報を収集し、変換のためにビデオを Worker コンポーネントに転送します。すべてのステージは順番に実行されます。この場合、多くのエンコード サーバーが存在する可能性がありますが、特定のビデオの処理でビジー状態にあるのは 1 つだけです。シンプルで透明な図。これでその利点は終わります。このスキームは垂直方向にのみ拡張できます (より強力なサーバーを購入するため)。
中間結果を使用したシーケンシャルエンコード
苦痛な待ち時間を何とかスムーズにするために、業界は高速コーディングのオプションを考案しました。実際、完全なコーディングは順番に行われ、同じくらいの時間がかかるため、この名前は誤解を招きます。しかし、中間の結果が得られました。考え方は次のとおりです。ビデオの低解像度バージョンをできるだけ早く準備して公開し、それから高解像度バージョンを準備して公開します。
一方で、ビデオはより速く利用可能になります。そして重要なイベントにも役立ちます。しかしその一方で、画像がぼやけてしまい、視聴者をイライラさせてしまいます。
ビデオを迅速に処理するだけでなく、その品質を維持する必要があることがわかりました。これは現在、ユーザーがビデオ サービスに期待しているものです。最も生産性の高いサーバーを購入する (そして定期的にすべてを一度にアップグレードする) だけで十分だと思われるかもしれません。しかし、これは行き止まりです。最も強力なハードウェアでも速度を低下させるビデオが常に存在するからです。
並列エンコード
複雑な問題を多数のそれほど複雑でない問題に分割し、異なるサーバー上で並行して解決する方がはるかに効率的です。これはビデオ用の MapReduce です。この場合、1 台のサーバーのパフォーマンスに制限されず、(新しいマシンを追加することで) 水平方向に拡張できます。
ちなみに、ビデオを小さな部分に分割し、それらを並行して処理し、結合するというアイデアは、特別な秘密ではありません。このアプローチについては多くの参考文献を見つけることができます (たとえば、Habré では、このプロジェクトに関する投稿をお勧めします)
そこで、新しいアーキテクチャでは、逐次コーディングを行うモノリシック Worker ブロックをマイクロサービス Segmenter、Tcoder、Combiner に分割しました。
- セグメンターはビデオを約 10 秒の断片に分割します。フラグメントは XNUMX つ以上の GOP で構成されます (
写真のグループ )。各 GOP は独立しており、個別にエンコードされるため、他の GOP からのフレームを参照せずにデコードできます。つまり、フラグメントは互いに独立して再生できます。このシャーディングによりレイテンシが短縮され、処理をより早く開始できるようになります。 - Tcoder は各フラグメントを処理します。キューからタスクを取得し、ストレージからフラグメントをダウンロードし、それをさまざまな解像度にエンコードして (プレーヤーは接続速度に基づいてバージョンを選択できることに注意してください)、結果をストレージに戻し、フラグメントに処理済みのマークを付けます。データベース内で。すべてのフラグメントを処理した後、Tcoder は次のコンポーネントの結果を生成するタスクを送信します。
- Combiner は結果をまとめて収集します。Tcoder によって作成されたすべてのフラグメントをダウンロードし、さまざまな解像度のストリームを生成します。
サウンドについて一言。最も人気のある AAC オーディオ コーデックには不快な機能があります。フラグメントを個別にエンコードした場合、それらをシームレスに結合することはできません。変化が顕著になります。ビデオ コーデックにはこの問題はありません。理論的には、複雑な技術的解決策を探すこともできますが、このゲームはまだろうそくの価値がありません (オーディオはビデオよりもはるかに軽い)。したがって、ビデオのみが並行してエンコードされ、オーディオ トラック全体が処理されます。
結果
ビデオの並列処理のおかげで、ビデオがアップロードされてからユーザーが利用できるようになるまでの遅延が大幅に短縮されました。たとえば、以前は、15 時間半にわたる FullHD 映画に対して、異なる品質の複数のフル バージョンを作成するのに XNUMX 時間かかることがありました。ここまでの作業には XNUMX 分かかります。さらに、並列処理により、従来の中間結果アプローチによる低解像度バージョンよりもさらに高速に高解像度バージョンを作成します。
後もう一つ。以前のアプローチでは、十分なサーバーがなかったか、サーバーがタスクなしでアイドル状態になっていました。パラレルコーディングにより、鉄のリサイクルの割合を増やすことができます。現在、1,000 台を超えるサーバーからなるクラスターは常に何かでビジー状態です。
実際、まだ改善の余地があります。たとえば、ビデオ全体が届く前にその断片の処理を開始すれば、時間を大幅に節約できます。彼らが言うように、さらに多くのことが起こるでしょう。
ビデオを扱う分野でどのようなタスクについて読みたいかをコメントに書いてください。
業界の同僚の経験への役立つリンク
出所: habr.com