大量のユーザーを抱える
将来のサービス拡充に向けて土台を整備
- ――今回、
サービスの基盤部分を大幅に刷新された理由は何でしょうか。 原:ニコ動は、
サービスの提供開始から時間が経ったことで裏側のコードが複雑になっており、 これから新たな機能をバンバン追加するのが厳しい状況になっていました。そこで、 将来的なサービス拡充に対応できる新たな土台をスクラッチから作ろうという話になりました。 太田:典型的な部分では、
動画と生放送がそれぞれ別のしくみで配信されていることが挙げられます。さらに、 同じ生放送でもPC向けとモバイル向けで別のシステムが使われていて、 なおかつサービスの拡充に伴って肥大化していたことも問題でした。この先に進むためにはさまざまなサービスをまとめて扱える基盤を作る必要があるということで、 このプロジェクトがスタートしたんです。 - ――今回の基盤部分の刷新において、
最も大きなポイントになった要件は何だったのでしょうか。 原:ニコニコで扱っている各々のコンテンツをできるだけ統一された形で取り扱えるようにすることが大きな要件でした。生放送や動画のコンテンツ、
あるいは生放送を録画してあとで動画として視聴するなど、 さまざまなユースケースが考えられます。その一つ一つのコンテンツを別々なものとしてとらえるのではなく、 状況に応じて適切に配信する基盤を整えたいと考えました。 - ――アーキテクチャの設計はスムーズに進んだのでしょうか。
原:設計はすんなり進められましたが、
実装を進める中で隠れていた要件が発覚することもあり、 多少の手戻りはありました。たとえば、 動画視聴時の手順の1つに、 その動画を再生するための権利を取得する処理があります。我々はそれをサーバ側から呼ぶことを前提にしていましたが、 プロジェクトの途中で、 権利取得の処理をクライアントが直接呼び出すケースもあることがわかったんです。手戻りが発生することにはなりますが、 必要な処理だったので対応しました。 川平:サービスとしての歴史が長い分、
要件も複雑になっていました。当然ヒアリングにも時間を割きましたが、 それでも見逃してしまう部分があり、 その対応も苦労しました。
独自のアルゴリズムで多数のノードの協調制御を実現
- ――簡単に、
今回のシステムの概要を教えてください。 原:データフローで表現するとすごくシンプルです
(図1)。アプリサーバでユーザー認証などの処理が行われたあと、 ユーザーのスマートフォンやPCから生放送の映像や動画がアップロードされます。今回開発した 「Dwango Media Cluster」 は、 こうした生放送の映像や動画をスマートフォン用やPC用などいくつかのターゲットに分けてトランスコードを行いつつ、 動画であればストレージにも保存し、 最終的にエッジサーバから配信します。
- ――以前の基盤と比べて、
最も大きく変わったのはどういった部分でしょうか。 原:以前はバラバラだったシステムを完全に統合したことです。従来のしくみはそれぞれのサービスで別々のサーバが使われていたため、
サービスをまたいでリソースを融通させられませんでした。しかし今回の基盤では、 各々のノードが動画と生放送のどちらにでも対応でき、 必要に応じてリソースを適切に配分できます。 太田:年末の深夜の生放送や、
人気のあるユーザーの生放送で急激にトラフィックが増えたとき、 以前は対応するのが大変だったんです。しかし今回の基盤では、 そのような急激なトラフィックの変化にも対応しやすくなりました。 - ――今回のシステムで特に工夫した点を教えてもらえますか。
原:まず1つは、
それぞれのノードに対する処理の振り分けですね。単純なサービスであれば、 ロードバランサでそれぞれのノードに処理を振り分ければ十分です。ただ、 今回の基盤は動画のトランスコードが含まれるので、 すごく処理が重いんですね。さらに生放送では、 1つの番組でも5~6ノードが連携して動作します。こうした処理を単純なロジックで振り分けると、 ハードウェアリソースを有効に活用できないだけではなく、 そもそもサービスとして成り立たないことが予想されました。そこで、 利用しているリソースを各ノードで常に管理し、 それを一元的に把握することで、 適切なノードに処理を割り当てています。 川平:実際にはマスタノードのようなものはなく、
各ノードのCPUやディスクの使用率をクラスタ全体で共有し、 どのノードに処理させるのがベストかを判断するアルゴリズムを作りました。 太田:マスタがコントロールする形では、
どうしてもそこがボトルネックになりやすいので、 マスタとなる情報をすべてのノードが持ち、 どのノードでも判断できるようにしました。ただこの方式も、 クラスタのサイズが巨大になるにつれて、 各ノードの情報を通知・ 収集するためのコストが無視できなくなってきます。そのため、 リソース管理を階層化したり、 各ノードが必要な情報のみを共有する、 といったしくみを入れることも検討しています。 原:配信処理は複数のノードを使って実現しているので、
それぞれの処理を有向グラフとして抽象化し、 たくさんあるクラスタ内のノードのどれに割り当てるかというアルゴリズムを開発しています (図2)。配信処理におけるタスクグラフを定義して、 そのときどきでどのノード群に処理を割り当てるかを判断しています。
太田:ノード数が多いので、
通信コストも重要です。生放送ストリームをノード間で中継したり、 動画ファイルを移動・ 複製したりする場合に、 位置関係を意識して目的ノードや転送経路を決定しないと、 経路上のネットワークのキャパシティをオーバーしてしまうことにもなるため、 そのあたりも考慮したアルゴリズムにしています。
クラスタ内通信で使うプロトコルを独自に開発
川平:通信という意味では、
システム内で使う映像や音声を低遅延で転送するために、 DMTPという独自のプロトコルを開発しました。似た特性のプロトコルに、 アドビシステムズが開発したRTMP (Real-Time Messaging Protocol) がありますが、 今回の基盤刷新ではノード間の映像の転送などをすべて独自開発のDMTPで実現しました。 - ――RTMPを使わずに独自開発のプロトコルを開発した理由は何でしょうか。
川平:RTMPは自由度が低い部分があるほか、
クラスタ内での利用には不要な仕様が多かったりするため、 シンプルなプロトコルで通信したいと考えました。特に、 将来的に複数の映像の同期や合成などの加工も考えているのですが、 RTMPではタイムスタンプを表すために32ビットのミリ秒単位の値を使っているため、 正確な時刻が必要な加工では精度が不足することがあります。たとえば44. 1kHzの音声の1サンプルをミリ秒で指定できませんし、 30fpsのフレームの間隔も正しく表現できません。ニコ生には1週間以上のすごく長い番組もあるので、 32ビット幅だとすこし心許ないと思い、 そういった面からも独自に開発しようということになりました。 太田:DMTPの一番の目的は映像と音声の配信で、
それに特化することでコンパクトな仕様になっているほか、 用途などに応じて調整できる自由度も持たせています。
動画配信に特化した分散ファイルシステム
- ――それ以外で、
今回の新たな基盤構築のために新規で開発したものはありますか。 太田:実は分散ファイルシステムも独自に開発しました。もともと既存のオープンソースのファイルシステムを使っていたのですが、
それだと期待する性能が出ないことがわかり、 独自に調査開発を進めることにしました。 川平:当初利用しようとしていた分散ファイルシステムが、
思ったよりも性能が出ないことがわかったときは結構焦りました。まずは設定や構成の変更で性能の向上を試みたり、 実装を読んだうえでデータへのアクセスのしかたを工夫したりして処理効率を高めました。それでも目標とする性能を出すことは難しいとわかったのですが、 ネットワークやサーバの性能をちゃんと使えればもっと多くの配信をさばけるはずと考え、 独自に開発しようという流れになったんです。 太田:動画配信サービスの特徴として、
1つのファイルのデータサイズが数百MBから数十GBと非常に大きいことが挙げられます。それを保存する際に、 冗長性を担保するために複数のノードに複製を置くわけですが、 ディスク容量をできるだけ抑えて、 かつ耐障害性を高めなければなりません。 この際、
単に複数のノードに同じ内容を分散して保存するだけだとディスク容量的に厳しい。そこで、 消失訂正符号 (イレイジャーコード) と呼ばれるしくみを採り入れたのですが、 ここでも1つ問題がありました。1つのファイルを小さなブロックに分割して複数のノードに分散するのですが、 ブロックサイズが小さいため動画再生時に5~6台程度のノードから細かいブロックを同時に集めてくる必要があり、 これはハードディスクに優しくないんです。ブロックサイズを大きくすればスループットは出しやすくなりますが、 ストリーム配信で重要となる 「安定したペースで最初から最後まで配信し続ける」 といった要件を達成するのが困難になるという問題がありました。 基本的にハードディスクは一気に読み込んだほうが性能を引き出せますが、
イレイジャーコードを使うと複数のノードで細かなデータアクセスが発生してしまいます。当初は1ノードあたり1,000ユーザー程度をさばければよいと考えていましたが、 実際はそれを大きく下回るアクセスにしか対応できませんでした。それが最も大きな課題で、 その解決に向けて調査を行い、 独自の分散ファイルシステムの開発を進めることになりました。現状は初期バージョンの開発完了にかなり近づいています。 - ――オープンソースとして公開されている分散ファイルシステムはいくつかありますが、
汎用的なプロダクトで対応するのは難しかったのですね。 太田:そうですね。やはり動画配信で求められるスペックは、
一般的な分散ファイルシステムの仕様から考えると特殊な部分があり、 一般に公開されているプロダクトで対応するのは難しいかもしれません。 - ――ちなみに、
分散ファイルシステムの開発に使った言語は何だったのでしょうか。 太田:Rustという言語で、
ガベージコレクションがなく、 C++にメモリ安全性の機能を付加したようなものです。ニコニコの動画・ 生放送の配信基盤開発ではErlangを使うことが多いのですが、 レイテンシを細かく制御したい分散ファイルシステムの分野では、 どうしてもガベージコレクションが気になってきます。たしかにErlangのガベージコレクションはすごく優秀ですが、 自分で制御したほうが安定して予測した性能を出しやすく、 またデータ構造を工夫することで消費メモリサイズも大幅に削減できるので、 ガベージコレクションのないRustを選択しました。Rustは低レイヤのリソースを直接操作するような領域にも強いので、 将来的に検討している、 ブロックデバイスを直接制御するような場面でも有効だと考えています。
“すごいサービス”に向けての土台作り
- ――現状のプロジェクトの進捗状況を教えてください。
原:会長の川上
(量生氏) やリーダー陣、 僕たちアーキテクトの中で話し合っている 「こんなものが作りたいね」 というのが100だとすると、 現状はまだ3とか5くらいです (笑)。現状は、 とにかく複雑化した従来のしくみをキレイにして作り直し、 一部を載せ替えたという段階で、 載せ替えを完了するのが次のステップです。この基盤を使ってすごいサービスを作っていくのが3番目のステップで、 そこに向けて開発を続けています。 太田:ニコ動とニコ生の基盤を1つにまとめるという目標の第一段階は達成できましたが、
それは1つのステップにすぎません。やりたいことはもっと先にあるんです。 原:単純な基盤の作り直しであれば、
こんなオーバースペックなプロジェクトをやる必要はなかったのですが、 先ほどお話しした100を目指すための投資ということです。 - ――その100を目指すうえで、
エンジニアの役割は非常に大きいと思います。ドワンゴでは、 どういったエンジニアが求められているのでしょうか。 原:コンピュータサイエンスの深い知識を持っていて、
言語は比較的何でもかまわない、 そんな人がいいですね。要件やサービス特性に基づいた最高のアルゴリズムとデータ構造はどのようなものか、 その時間╱空間計算量はどうなのか、 ハードウェアリソースを使い切れるか……このようなことについて、 ホワイトボードを使いながら議論できる、 そういった人に来てほしいと思っています。 - ――本日はありがとうございました。
ドワンゴでは、
詳しくは、
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/
定価1,628円
ISBN978-4-297-13000-8
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現! - 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう - 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、 NFT