各種 RTMP サーバーでのライブストリーミングの実現

こんにちは、株式会社ドワンゴの糸柳です。何故突然名乗っているのかというと、業務での成果を外部に出す場合には所属を明らかにせよと言われたからです。実際の僕はというと、グッドウィルに登録し日雇いの派遣で肉体労働をしているワーキングプアということになっているのですから、本当にインターネットというのは信用できませんね。このようなブログも読まない方が良いと思いますよ。

本題に移る。Flash を使ってライブストリーミング(生放送)を実現するためには、Flash Media Server と Flash Player 上で動いている .swf ファイルのクライアントとの間で通信を行うために作られた RTMP(Real Time Messaging Protocol)という独自のプロトコルを使用する。RTMP はサーバーや別クライアントへの通知及び呼び出しの送受信(Notify 及び Invoke)、複数の Flash クライアント上でのオブジェクトの共有(Shared Object)、ストリーミングデータの送受信(Video Data 及び Audio Data)という 3 つの機能を持っている。ライブストリーミングではこのうち、ストリーミングデータと一部の通知及び呼び出しを使用する。

RTMP のサーバー側が最初に実装された Flash Media Server(旧 Flash Communication Server)シリーズでは、大規模なストリーミングデータを配信する際、サーバーの処理能力や帯域を分散するために配置するサーバーのうち、配信する元データを受け取り下位構造にデータを流すものをオリジンサーバー、オリジンの下に複数ぶら下がりクライアントからの接続を受けてオリジンからのデータをクライアントへブロードキャストするものをエッジサーバーと呼んでいる。

Flash Media Server におけるライブストリームのクラスタリング

エッジ一台で捌くことのできるクライアントの台数には限度があるため、このようにしてスケーラビリティを確保する。

現在 RTMP による通信が可能なサーバーソフトウェアは自分が知る限り Flash Media Server、Wowza Media Server、Red5 の 3 種類があり、それぞれに大きく特性が違う。これらについてオリジンサーバー、エッジサーバーによるクラスタリングを実現する方法を紹介する。

この記事を書いている時点において、Windows Media Video を使った大規模配信があちこちで実現しているので、わざわざ Flash でやるということで、ニコニコ動画の最高画質の 500kbps から 600kbps あたりを勝手に目標に定めて検証する。

Flash Media Server 2 を使ってのライブストリーミング

Flash Media Server 2 は Adobe 純正の RTMP サーバーの最新版であり、これを使うと確実ではあるのだが、非常にコストパフォーマンスが悪い。これで環境を構築しようにも、莫大なユーザーがアクセスできる状態にするのは金銭的な面で少々大変だ。

Flash Media Server 2 の価格について書かれているページを見てみると「Edge Edition はハードウェアに大きな負担をかける、メディア配信の大部分を処理することから、Edge Edition の同時接続ユーザー数は 600 人以下に制限することが推奨され」ている。帯域とパフォーマンスについての文書(PDF)の中の「Max Total Server Bandwidth」という表を見ると、600 人の場合は全体で 60 Mbps 弱の帯域を処理することができる。

Flash Media Server の帯域幅とコネクション数のトレードオフ

青い破線がライブストリーミングでのパフォーマンス

しかし、60Mbps では 1 クライアントの帯域が 500kbps でも 120 人しか捌くことができない。余裕を持たせて考えれば無理をしても 100 人が限度だろう。1 クライアント 500kbps を前提にしてグラフと照らし合わせると、80Mbps で 160 人を処理するのが良さそうだ。実運用では余裕を持たせて 130 人ぐらいにするなりすれば良い。

この設定だとエッジを 1 台追加して配信可能人数を 130 人増やすごとに 175 万円が必要だ。もちろん別途オリジンの代金 520 万円もかかる。ちなみに先ほどのページでフェイルオーバーと書かれているオリジンは、障害時に置き換えて動作するためのサーバーなので、それ単体では使えない。

ちなみに Professional Edition を購入する場合は、3 種類の Profile から、最大接続数と最大帯域幅のトレードオフで 1 つを選んで 1 ライセンス 156,000 円で購入することになる。自分が把握している限りでは、このライセンスではオリジンやエッジとして動作させることはできない。

最大接続数最大帯域幅
Profile 1150無制限
Profile 2100040Mbps
Profile 3250025Mbps

複数のライセンスを一つのマシンの中に束ねることもできるとあるので、Profile 1 を 2 つ、312,000 円で買えば、ライセンス上は、500kbps の動画を 300 人に配信することができる。但し、処理能力のグラフから考えれば、それだけの処理は全く期待できない。300 人ギリギリまで配信するならば 200kbps 強までビットレートを下げる必要があるだろう。

Wowza Media Server を使ってのライブストリーミング

元 Adobe の社員がスピンアウトして立ち上げた Wowza Media Systems という会社の製品で、Flash Media Server とほぼ同等の機能を持っている。User's Guide によれば、クラスタリングは、クライアントがエッジに接続したあと、再生するストリーム名としてオリジンへのアドレスを含めた URI を記述し、エッジがプロキシのように動作することで実現しているようだ。これはちょっと微妙な実装のような気もするが確かに手軽ではある。

また、FAQ の「Have you conducted any performance tests?」という項において、ライブストリーミングで 512kbps まで出しても 2000 の接続に対応できると書かれている。いくらカタログスペックとは言え Flash Media Server を極端に引き離している。

更には接続数無制限ライセンスでも $5,000(2007/11/09 現在で約 57 万円)でしかない。極めて安い。

自分は Flash Media Server と Wowza Media Server に関して、評価として双方のサーバー側アプリケーションの開発や通信実験などをある程度やったが、Wowza Media Server に機能的な遜色は無いと言っていい。カタログスペック及び価格の面で大幅に Flash Media Server を引き離し、またサーバー側アプリケーションの実装方法もかなり似せてあるので、現在 Flash Media Server を使っている人間は、可能であれば Wowza Media Server に乗り換えることを検討するのも悪くはない。但し現時点で日本に代理店は存在しない。

Red5 を使ってのライブストリーミング

Red5 は Open Source Flash という団体が作っているその名の通りオープンソースの RTMP を喋るサーバーで、やはり Flash Media Server をかなり真似て作られている。単体のサーバーならば、おおよそ同等の機能を有している。

にゃふにゃふ動画が既に Red5 を使った一般向けのライブストリーミング配信を実現している。とりあえず動く。但し、ざっと使ってみた限りだとどうしても再生クライアント側での動画がカクついてしまって、それを改善することができなかった。接続しているクライアント数を増やしても減らしても目視で把握できるような差が無い。つまり配信が遅れているというわけでもないようで、多分パケットの扱いが Flash Media Server や Wowza Media Server とは異なっている、というか要するに実装を間違えているのだと思う。

また、クラスタリング構成に全く対応していない。つい数ヶ月前に Terracotta を使ってクラスタリングを実現した人が出たようではあるが、Terracotta というのは JavaVM 上の Java オブジェクトのうち一部を複数のサーバーで同期させるようなものなのであって、あまりスマートな方法とは言えない。同期のための処理速度低下は、ライブストリーミングのような大量のデータを扱う場合に大きくなりやすい。

比較的まともな方法として、RTMPClient を使うことが考えられる。これは Red5 開発者の Joachim Bauch が勝手に Red5 の中に突っ込んだクラスで、名前の通り RTMP のクライアントとして通信することが可能なものだ。検索すればいくつかサンプルは転がっている。エッジがオリジンに RTMPClient で接続することで、クラスタリングを実現することは充分に可能だ。但し、「The RTMPClient currently doesn't support streams, only method calls and shared objects.」とあるようにライブを含めたストリームの配送には全く対応していない。

RTMPClient の実装は粗方把握しているが、正直言って Red5 そのものと癒着しすぎている。Red5 はあくまでもサーバーなのであって RTMP のクライアントとして通信することを目的としていない。つまり RTMPClient は、サーバーとして動作するはずの様々なクラスを騙しながらクライアントとして動作している。かなりの力技で更にもう一段階あちこちを騙して回ることでストリーミングデータの受信には成功しているが、Red5 本体の設計にも多少難があるためその辺りの修正にまで手を回さなければならなかった。ストリーミングデータのクラスタリングの実現を本家に contribute するためには Red5 本体の設計にまで口を挟まなければならない。

そしてそこまでやっても Red5 のみで構成している限りでは動画のカクりが生じる。試しにオリジンを Flash Media Server に、エッジを Red5 + RTMPClient にしたのだが、こうするとカクりが突然消滅する。これならば上手くいくかも知れない。仮にこれでエッジの Red5 の処理能力が物凄く低くてその分だけハードウェアにやたらと投資しなければならず、Wowza Media Server にコストパフォーマンスで負けてしまうため Red5 をエッジにすることにあまり意味が無いとしても、コマンドラインから外部の RTMP を喋るサーバーに接続して通信や負荷の実験を行う用途に転用できる。上手く使えば無駄にはならないだろう。

ところで何故上記の実験でオリジンを Flash Media Server にしたかというと、Wowza Media Server に RTMPClient で接続できなかったからだ。ハンドシェイクのどこかでコケている。現在パケットを解析して問題を追っているが本来の仕事が忙しくてあまり時間を割けていない。Wowza Media Server にさえ接続できれば、動画のカクりなく、かつ台数が必要なエッジのソフトウェアへの現金でのコストをタダにすることができるようになる。業務でライブストリーミングの配信に使うかどうかはともかくとして何らかの使い道はある。

ところで Red5 でのパフォーマンスだが、500kbps で RTMPClient を接続させ続ける負荷テストを行ったところ、データセンターのマシンと自席の机で数百本のコネクションを張った時点で近くにあった 100Mbps のハブが死に掛けて情シスの人間が飛んできて痛烈なお叱りを受け、データセンター内に研究用のマシンを三台借りることができたので一台をサーバーに、2 台を RTMPClient にしたのだけれど、その 2 台の RTMPClient からそれぞれ 300 コネクションぐらい張った時点で、クライアント側二台が負荷に耐え切れずエラーを吐きまくってコネクションを切断しだしたり、600 コネクションぐらいから Out of Memory で落ちたりした。誰かデータセンター内に十台ぐらいマシンを出してくれ。ドワンゴはニコニコ動画にハードウェア取られてるからあんまり回してもらえないんだよ。

その改造版 Red5 は後日詳説する。ブログを書く意欲が全く無いので、実際に書くのは十年後ぐらいとかになるんじゃないですかね。

総括

ライブストリーミングをクラスタリング構成で大規模に配信する際、ハードウェアの台数も含めて安くあげるならば Wowza Media Server を使うと良い。信頼性やサポートを得る必要があって、かつソフトウェアやハードウェアに多くの投資が可能な状況ならば Flash Media Server を選択することになるだろう。ハードウェアだけが何故か潤沢にあり、ソフトウェアに全く金をかけたくなくて、更に高い技術力でパケット配送の様々な問題を自分で解決したいぜ、という知能に障害があるとしか思えない人間は Red5 を選択するといいが、多分お前は報われない。

また、実際に配信するとなると他にも問題がある。最も重大なのは配信側のソフトウェアのライセンスだ。まともな画質を実現しようとするとかなり面倒くさい縛りがある。これについてはまた今度まとめて報告する。