実例に学ぶ動画配信サービスの負荷試験~テストケース作成からツール選定、性能劣化への対応まで
ライブ動画ストリーミングプラットフォーム「SHOWROOM」で実施した負荷試験の内容とはどのようなものだったのでしょうか。DeNAのインフラ基盤を支えるエンジニア漢 祐介さんに、貴重なノウハウを徹底解説してもらいました!
サービスが業務に耐えうる処理性能を持っているかを検証するため、システムに対して擬似的に大量アクセスを発生させて反応を測定する「負荷試験」。サーバーの限界性能を見極め、安定稼働させるための指標や仕組みを作るために、なくてはならないものです。
では、多くの人が知るサービスは、どのような負荷試験を経てリリースされたのでしょうか。すでに運用段階にあるサービスの背後にある負荷試験のノウハウは、これから何らかのサービスをリリースしようとしているエンジニアにとって有用な情報です。
そこで今回は、DeNAのインフラ基盤を支えるエンジニア漢 祐介(はた・ゆうすけ)さんに、ライブ動画ストリーミングプラットフォーム「SHOWROOM」で実施した負荷試験の内容を中心に、そのノウハウを徹底解説してもらいました!
- 漢 祐介(はた・ゆうすけ)
- 株式会社ディー・エヌ・エー システム&デザイン本部IT基盤部第一グループ・グループリーダー。都内ベンチャーから「もっと自分の力を試したい」という思いで2012年にDeNAに転職。モバイルゲームの開発・運用を経てIT基盤部に配属、開発からインフラまで幅広い技術を身に付けフルスタックエンジニアを目指す。現在はIT基盤部第1Gのリーダーとして、様々な領域のインフラ業務に携わっている。
(1)テストケース作成の基準
──まず、どのような基準でテストケースを作成しているかについて教えてください。
漢 負荷試験で求めるべき重要な指標の一つとして「サービスを安定運用するにはサーバーが何台必要か」があります。
それを求めるために、私たちのチームは「サーバーが冗長化されている構成で1台のサーバーがダウンした場合、サービスの負荷が他のサーバーに分散されても、1台あたりの負荷が85%(目安値)を上回らないこと」を指標として負荷試験を実施し、その結果を元にサーバーが何台必要かを求めています。例えば、サーバーが10台あれば1台あたりの負荷が85%を下回るならば、プラス1台(=計11台)用意するという考え方です。
なぜなら、もしも必要な台数ギリギリにしてしまうと、何かのトラブルで1台がダウンした場合に、そのサーバーにかかっていたアクセスが残りのサーバーに流れ、高負荷のために処理できなくなってしまうからです。必ず、冗長化を前提にテストケースを作っていきます。
また、「1台のサーバーがどれだけのDAU*1をさばけるか」も負荷試験をして求めていきます。この指標は、サーバーを増設する際に、何台必要なのかを計算するときに使います。
──冗長化して障害に強くするならば、プラス1台だけではなく2台、3台にした方がより安全なのではないでしょうか?
漢 私たちのグループでは、「多重障害(同時に複数の障害が発生すること)」を考慮しない方針にしているんです。なぜなら、同時に2つ以上のサーバーが壊れる確率は極めて低いにもかかわらず、むやみに冗長化してしまうとサーバーの維持にかかる人的・金銭的コストが膨れ上がってしまいます。要するに、不必要なコストが多くなってしまうんです。
「サービスの可用性を担保しつつ、運用にかかるコストがなるべく低くなるサーバー台数」を意識して、私たちは運用をしています。
(2)過去事例・SHOWROOMで実施した負荷試験
──「SHOWROOM」のサーバー構築の際には、どういった観点でどんなテストを実施しましたか?
漢 まず前提として、SHOWROOMでは大きく2種類の動画配信サーバーがあります。映像データが配信されるOriginサーバーと、映像を利用者に届けるEdgeサーバーです。
OriginサーバーとEdgeサーバーは数台ごとにShardingされており、Originサーバーから配信された映像データが同一Shard内に配置されたEdgeサーバーを経由するような仕組みになっています。
これらのサーバーを運用するうえで重要なのは、トラフィックが大量に出ることと、映像に遅延が発生しない・止まらない・途切れないことです。そのため、以下のような観点でテストを実施しました
- Originサーバー1台あたりどれだけの配信をできるのか
- Originサーバー複数台あたりどれだけの配信をできるのか
- Edgeサーバー1台あたりどれだけの配信をできるのか
- Edgeサーバー複数台あたりどれだけの配信をできるのか
- Originサーバーには何台のEdgeサーバーをぶら下げることができるのか
- Originサーバーがダウンしても、即座にOriginサーバーのStandbyに切り替わるか
- Standbyに切り替わった際に、配信映像を観ることができ、映像に乱れや遅延がないか
映像配信がサービスの根幹であり、配信者と受信者がコミュニケーションを取れることも重要であるため、映像の遅延や映像の乱れ(カクカクするなど)はかなり気を遣ってテストを実施しました。
──他に、テストケースを立てるうえで心掛けたことはありますか?
漢 実は動画配信サービスは「視聴者がiPhoneで3G回線を用いて視聴する場合」と「それ以外のパソコンやスマートフォンなどで視聴する場合」とで、使用するプロトコルをアプリ側で切り替えているんです。より具体的に言えば、前者の場合はHLS*2が、後者の場合はRTMP*3が用いられます。
そのため、プロトコルの組み合わせを変えてテストを実施しました。HLSだけ、RTMPだけ、両者の混合、プロトコルが途中でRTMPからHLSに切り替わる、などです。
──プロトコルを変更するテストケースは、動画配信系のサービスならではですね。
漢 そう思います。さらに言えば、プロトコル以外にもビットレートを考慮することも重要です。例えばSHOWROOMの場合、回線が細くなっている方(月あたりの利用可能パケット量を超過しているなど)向けに低ビットレートで動画を配信しているんですが、その際にOriginサーバーで画質を変換する処理を行います。
そのため、画質変換処理の有無によってさばける配信数が違ってきます。こういった点を考慮しながら、SHOWROOMのアーキテクチャ構築の際にはテストケースを考えました。
(3)負荷試験に使用するツール
──負荷試験ツールには、どんなものを用いていますか?
漢 Webサーバーの負荷試験ではApache Bench(ab)やApache JMeterを使うことが多いです。Gatlingも使うことがあります。動画配信サーバーへの負荷試験では、内製のScalaで書かれたツールを用いています。
──各ツールの特徴を教えてもらえますか?
漢 Apache Benchは、Apacheに標準で付属している負荷試験ツールです。特別な設定作業などが必要ないので、シンプルに負荷をかけたい場合によく用いています。例えば、負荷をかけ続けながらサーバー台数を減らしたりDeployしたりしてエラーが発生しないことを確認するとか、負担を長時間かけ続けてメモリリークしないことを検証するとか。
Apache JMeterはテストのシナリオを書けるため、より詳細なテストが実施できます。1,000人同時にログインするシナリオを用意しておいて、DBへの負荷のかかり具体を確認するとか。Gatlingはテストシナリオをコードで残せるのが便利なので使っていますが、どちらを使っても構わないと思います。
──動画配信サーバーへの負荷試験で、Scala製のツールを用いているのはなぜですか?
漢 視聴者が使っているブラウザと、テストツールの挙動を合わせたかったからです。より具体的に言うと、「ブラウザが動画のセグメントデータ*4を取得する際の挙動」まで再現したかったんです。それを実現するのは既存のツールでは難しかったため、Scala製のツールを内製しました。
──具体的には、どんな種類のアクセスを設定してテストしましたか?
漢 一例を挙げると、HLSの場合、Playlistに記述されているセグメントデータを全部取得するアクセスが流れるのですが、それは初回のアクセス時だけで毎回その処理が流れるわけではありません。通常は2~3秒おきにPlaylistを再取得し、セグメントデータの再生が終わってから次のセグメントを取りに来るというシナリオになります。
Webアプリにも同じことは言えて、単純に画像データを取得するだけの負荷試験をしていても意味は薄く、「アプリケーションロジックがどう走るか」を考慮してテストをしなければいけません。
──利用者やブラウザなどの挙動を考慮したうえで、ツールを選定することが大事なんですね。
漢 そうですね。実運用とかけ離れたテストをしても、意味が薄くなってしまいますから。サービスにどのような種類のアクセスが来ているか調査したうえで、その実態に合わせたテストをするのが重要なんです。
──少し話が飛びますが、最近、Tsungというロードジェネレータツールが注目されています。漢さんのこのツールに対する見解は?
漢 たくさんのプロトコルが利用できるな、という印象を受けます。負荷をかけることでサーバーの性能限界を調査できるのは良いことです。このツールの場合、自分が設定したミドルウェアの設定値がどこまでチューニングできているか、どこに原因がありそうかを特定するのに役立ちそうです。
ただ、負荷試験ツール全般に言えることなのですが、負荷が「さばけるようにアプリケーションをチューニングする」ということも重要なのですが、負荷をかけることで「アプリケーションがさばける量を知る」というのが重要です。
サーバーを横に並べるだけで良いのか、将来的に増えるであろう負荷を見積もれるか、といった点が鍵だと思います
(4)テスト実施時にチェックするパラメータ
──テストを実施する際には、どんなパラメータをチェックしますか?
漢 サーバーの種類によってさまざまですが、大きくCPU / MEMORY使用率(vmstat)、Disk IO状況(iostat)、ネットワーク利用状況がベースのパラメータになります。そして、全てのパラメータは秒単位でチェックします。
──「動画配信サーバー」「DBサーバー」「Webサーバー」などサーバーの種類ごとに、チェックすべきパラメータは異なりますか?
漢 異なりますね。動画配信サーバーでは、映像を配信するためのトラフィックが大きく出ることが多いため、outboundの転送量がNIC*5の性能に達しないか、もしくはNICの性能限界までトラフィックが出せるかを負荷試験では最初に確認します。
NICは、Linuxのドライバの性能によっても出せるトラフィックが全く違ってきます。NICからパケットを取り出すときのCPU使用状況(sysやinterruputなどのパラメータ)が頭打ちになってしまい、トラフィックが出る前にCPU側でサチる(利用状況が飽和するサチュレーションを意味する)ことがあるんです。
そのため、ドライバを入れ替えながらNICの性能が最大限発揮できる状態を保ち、その上で映像が遅延せず安定したトラフィックが出せる上限を調査します。
さらに言うと、映像をやりとりするプロトコル(HLS / RTMP)によっても高負荷となるパラメータは変わってきます。そのため、負荷試験の結果をべースとして、「このプロトコルの場合は、1台のサーバーがこれくらいの流量を許容できる」という閾値を決めているんです。
──具体的にどれくらいの数値が出れば、OKと見なせるのでしょうか?
漢 例えばNICが1000Mbps出せる場合、HLSのプロトコルで1000Mbpsまで負荷をかけると、おそらく映像は視聴できますが途切れたり止まったりして不安定になります。このとき、クライアント側ではTimeoutや再送が発生しているはずです。
では、何MbpsだったらこのTimeoutが無くなるのか、というのを調べていきます。数値はサーバーのスペックによってさまざまなので、ピッタリこれ、という値はなく安定した数値の上限が閾値となります。
──DBサーバーはどうでしょうか?
漢 DBサーバーの場合、チューニングされていないクエリが発行されるとDB自体の負荷が上がってしまうため、I/Oの性能以外にもクエリそのものがスループットを高く出せているかも確認します。また、MySQLのshow statusで出てくるような値は毎秒常に保存しているのと、SELECT/INSERT/DELETE/UPDATEそれぞれのQPS(Queries Per Second:秒間あたりのクエリ数)やconcurrency状況もチェックします。
──DML文の割合やconcurrency状況をチェックするのはなぜですか?
漢 サーバーの性能やMySQLの設定値によって、どういった種類のクエリをどれくらいさばけるかが決まっています。だからその上限に達しないように、指標となる値を確認しておくためです。
──Webサーバーについては?
漢 Webサーバーの場合、アプリケーションのWorkerが大量に生成された際にはメモリ使用量も増大します。そのため、効率よくメモリを利用できているか、Copy on Write を効率よく利用できているかなども確認する項目の一つです。
また、多くの処理を受け入れるには多くのWorkerが起動している必要があるため、各Workerのアイドル状況も確認します。さらに、status codeやresponse timeなども見た上で、1台のサーバーが許容できるWorkerの最大数を決めているんです。
全ての種類のサーバーに言えることですが、ベースラインの負荷状況ではなくピークラインの負荷をもとに性能を検証します。最も処理が重くなる状況でも、問題なくアクセスをさばけることが目的だからです。
(5)問題発生時の対処方法
──SHOWROOMや他の動画配信サービスの負荷試験を実施する中で、直面した「課題」などはありますか?
漢 いくつも課題はありましたが、一番分かりやすいもので言えばSSL対応でしょうか。RTMP / HTTPのプロトコルだったものをRTMPS / HTTPSのプロトコルに変更した上で負荷試験を実施したのですが、最大でも変更前の8分の1ほどしか配信性能が出なかったんです。
──その課題を、どのような手順で解決しましたか?
漢 負荷試験に限らずですが、私たちはサーバーに何らかの問題が起きた場合、「どのパラメータがなぜ高負荷になっているかを調べること」と「状態を再現させること」を目標にしています。
このとき性能劣化が発生していた原因は、SSLの暗号化を解くためにsys/intrが大量に使われていたためでした。このままでは、今まで1台で済んでいたサーバーが8台必要になってしまうため、SSL offloadingの検討をしました。
それまではアプリケーション側でSSLを解いていたのを、同じサーバーの前段にhaproxyを入れ、そちらでssl offloadingする方針に変えたんです。その結果、元の性能の75%ほどまで戻すことができました。
──それを踏まえ、読者へアドバイスはありますか?
漢 今回の例のように、アプリケーションやサーバーに何らかの変更を加えたことで性能劣化が起きるケースがあります。その状態でリリースをかけてしまうと、処理が遅延し障害が発生してしまいます。
それを防ぐには、変更前の性能値をきちんと計測しておき変更後と比較することで、どんなパラメータが劣化しているのかを把握し、アーキテクチャを最適な形に変更することが重要です。本番環境リリース後も、全期間のサーバーのデータをロギングしておき、いつでも状態をチェックできる状態にしておくことが大切だと思います。
──負荷試験を実施する上で役立つノウハウが盛りだくさんでした。どうもありがとうございました!
取材・執筆:中薗昴(サムライト)/写真:小堀将生
{$annotation_1}:Daily Active Users。1日あたりの利用者数。
{$annotation_2}:HTTP Live Streaming。Apple社が自社iOS向けに開発した、HTTPベースのストリーミングプロトコル。
{$annotation_3}:Real Time Messaging Protocol。Adobe社が開発した、Adobe Flash プレーヤーとサーバーの間で音声・動画・データをやりとりするストリーミングプロトコル。
{$annotation_4}:HTTP Live Streaming で使用される分割された映像データのこと。通常、2~3秒単位で小さく分割され、ブラウザはこのデータを繋ぎ合わせて映像を再生している。
{$annotation_5}:Network Interface Card。コンピューターなどの機器を通信ネットワークに接続するためのカード型拡張装置。