AppBrew Tech Blog

AppBrewのエンジニアチームの日々です

【負荷対策】CM放映期間にサーバを落とさない方法(保存版)

遊撃エンジニアの @anoworl です。最近はメンバーを巻き込みつつ転職ドラフトで指名をして指名承諾率1位になったり、SaaSをReactやReduxと戯れながら開発してちょっとだけSPAが分かった気になったりしました。

この記事では「CM放映期間にサーバを落とさない方法」と題して、昨年12月〜今年の1月のCM放映時行っていたことを紹介したいと思います。↓このCMです。

CM放映期間は記事に書いてあることを実践し、事前の負荷試験では元の10倍の負荷に耐えられるようにしました。

その結果、5xx皆無とか99パーセンタイルレスポンスタイム完璧!とまではいきませんが大きな障害も無く、分かりやすい値だとNew Relicで測定しているUptimeは期間中100%を記録しました。

f:id:appbrew-sota:20190925205720p:plain
Uptime 100% !

注意事項
この記事は、私自身CMを放映することになった際まとまった情報がインターネット上に余り無く困ったので、今後CMを行う時に見返せる「保存版」です。

そのため、抽象的なことから具体的なことまで包括的にすべきことを網羅したため長くなってしまったのですが、こちら一気に読む必要はありません。必要に応じて拾い読みして頂けたらと思います。

またこの記事ではAWSを使っていることを前提に書かれていますが、多くは使用しているインフラに依存しないものになっています。当該箇所はお使いのインフラに合わせて読み替えて頂けると嬉しいです。

では私が経験した「CM放映期間にサーバを落とさない方法」を解説していきます!

「CM放映期間にサーバを落とさない」理由

CM放映をすると、それを見た人が新しくアプリを使ってくれたり既存ユーザが再度使ってくれることでサーバの負荷が大幅に上がります。

どの場所でどの時間、どれぐらいの期間に放映するかにもよりますが、一定の量・期間全国で打ち続けるとピークの負荷は何倍にもなることがあり、何も対策してなければサーバは落ちるでしょう(特に今回のように、実家で年末年始にこたつに入りながらテレビを見つつスマホを見る層にCMを当てれば…)。

まずはどのような方法で負荷に立ち向かうか考えるために、一度CMとインフラの目的を振り返ります。

CMの目的

他のマーケティング手法と同様に認知を獲得することが目的です。大きくは以下の数字に表れてきます。

  • アプリのユーザ獲得数RR
  • ウェブやアプリストアの検索数
  • 売上(ワンデーセールを行うECアプリやソシャゲなどの場合)

デジタルマーケティングと違ってどれがどう獲得に繋がったか測りにくい、ワンショットの費用がそこそこでかいという性質があります。

f:id:appbrew-sota:20190922170944p:plain:w300
テレビ経由で認知を得ているイラスト

インフラの目的

このシチュエーションにおいて、インフラはCMの効果を最大化することが目的です。

端的には可用性を最大にし、なおかつ非機能要件を達成することで、CMによってサービスに興味を持ってくれたユーザを取りこぼさないことです。

話は逸れますがユーザを取りこぼさないことの重要性はマーケティングにも言え、CMを打つ際にはCM以外のマーケティング施策(アプリストア、リスティング、SNS、ディスプレイ…)も同様に重要になってきます。

インフラだけ完璧でも意味が無いので、インフラだけに留まらずマーケティングやアプリ内の施策など、それらも含めて全体設計することが重要です。

次の章からはこの目的を見据えた上で、インフラで行うことを説明していきます。

"事前"の負荷テスト

ぶっつけ本番でCMに望んだ場合、負荷に耐えられなかった際にはリアルISUCON1が始まってしまいます。 その場合、多額の金額を投下して放映しているCMの機会損失は多大であり、サーバだけではなくインフラ担当の精神的負荷も大きいです。

なおかつ単にアプリケーションサーバをスケールするだけで済めばいいですが、DBのスケールアウト、リードレプリカやキャッシュの導入などはダウンタイムやそれなりの手間が発生する場合があり、思った以上に時間がかかってしまうこともあります。

"事前"の負荷テストは必ずやりましょう。

f:id:appbrew-sota:20190922210835p:plain
リアルISUCON開催のイラスト

負荷の見積もり

負荷テストをやるために、まずは現状どのような負荷がかかっているかを既存ユーザと新規ユーザに分けて測定し、トラフィックのパターンをざっくり捉えましょう。

  1. 既存ユーザ: 現状のエンドポイント別の流量
  2. 新規ユーザ: ユーザがアプリ初回立ち上げ・使用時に発生するエンドポイントへのアクセス

新規ユーザを別にしているのは、CM放映時特に増えるからです。また放映時には追加で負荷がかかるので、以下の情報からどれぐらいの負荷がどんな感じにかかるのか計算しましょう。

  • スポットCMの場合、どの時間にどれぐらいのGRPの獲得が見込めるかという表が貰えたりするので、それを参考に計算する
  • 以前行ったCM・マーケティング施策を参考にする
  • やったことがある人に聞く
  • 過去にCMを行っていた同系統アプリをApp Annieで分析する

新規ユーザがどれぐらい単位時間あたり増えるか、どれぐらい再帰ユーザが増えるか、二つの軸で考えます。

ただCMに多額の金額をかける場合、それに比べたらインフラの料金は比較的安いです。余裕を持って見積もることをお勧めします。

負荷をかける

テスト環境の用意

負荷をかけるにあたって、本番環境にかけると影響が出てしまうので、完全に隔離したテスト環境を用意します。

テスト環境ではちゃんと本番を模したテストを行えるよう、本番とデータ量含め同一の構成を持つ環境を用意しましょう。データ量が違うと結構負荷のポイントも違います。

f:id:appbrew-sota:20190923201516p:plain:w300
本番と同一構成のテスト環境のイラスト

ベンチマーカーの用意

ベンチマーカーのソフトウェアは問いませんが、ただ新規ユーザの行動を模すとなると「アプリの初回立ち上げ・使用時のAPIアクセス」などを記述したくなるため、シナリオテスト出来るものがあると望ましいと思っています。なおSaaSで提供されており、サーバを管理しなくて良いものも選択肢としてはあります。

ちなみに私達の場合ですが、求める負荷をそれらのSaaSでかけると多額の料金が発生してしまうことが分かったので、JMeterクラスタをEC2で組んでベンチマーカーを用意しました。ただ望む負荷を望む形でかけられれば、どのような方法でも良いと思います。

ベンチマーカーですがテスト環境とは別のVPCに用意しましょう。同じVPC内に存在させると、帯域を食い合ってしまうことがあるとのことでした。

ボトルネックを解消する、その前に

ボトルネック発見には慣れの部分もあるので、力を付けるために私は以下の二つをお薦めします。

  1. 関連書籍を読む
  2. ISUCONの過去問を解く

1. 関連書籍を読む

負荷テストそのものを取り扱った本はそんなに数多くないですが、良書があるので紹介します。

こちらの書籍ですが、実際の負荷テストの手順を追って分かりやすく、かつ陥りやすい落とし穴などへの対処法などについても触れられている、実践的でめっちゃ良い本でした。AWSに閉じた話でも無いので、負荷テストをやる人全員にお薦めです。

取り急ぎ負荷テストをしないといけなくなったが、何からすれば良いか分からない場合などは、この本を読みつつやるのが良さそうだと思いました。

他にはパフォーマンス測定ではLinuxの知識が必要になるので、以下なども参考になります。

こういった本は負荷テストそのものの本よりも多種多様にあるので、色々探してみると良いかもしれません。

2. ISUCONの過去問を解く

1だけだとどうしても、ボトルネックを発見する手順が身についておらず、PDCAを回す際に時間がかかったり精度が悪かったりするので、実際に練習するのもお薦めです。

ISUCONというのは「いいかんじにスピードアップコンテスト」の略で、お題となったウェブサービスを高速化するコンテストです。

ちなみに前回の本戦は、仮想椅子取引所「ISUCOIN」がお題でした。先日の予選は、椅子を売りたい人/買いたい人をつなげるフリマアプリ「ISUCARI」でしたね。

f:id:appbrew-sota:20190615155657p:plain
仮想椅子取引所「ISUCOIN」(公式ブログ「ISUCON8 本選問題の解説と講評」より)

2019年までに9回行われており、なおかつ第3回からは予選と本戦があるので15の過去問があります。これらの過去問を複数こなすことで、応用が効くようになります。

ただ年が経つにつれ、言語やコンピュータの性能、クラウド環境など変わってきた部分もあるので、最近のものを解くことをお薦めします(昔のだと環境構築が大変なことも)。

解いた後は必ず解説を読みましょう。公式にも解説と講評がありますが、みなさん様々な言語で挑戦して「ブログを書くまでがISUCON」と言われるように(要出典)、各人が色んな形でやったことなどをまとめているので、自分が使っている言語の解説も見てみるのが良いです。

自分が気づかなかった高速化やよりよいボトルネックの発見法など、凄い勢いで吸収できます。

以下は私お気に入りの「@methaneさんが書いたpixiv private isucon 2016の解説」です。

実際にボトルネックを解消する

以下の1〜5を望んだパフォーマンスになるまで繰り返すのが基本的な流れになります。

ほぼISUCONと同じ流れでやることも似ているので、具体的な方法などは割愛します。ただISUCONと違って使うリソースは制限されません(金銭的な部分などでは制限されるかもですが)。スケールアップ、スケールアウト、別のサービスを使うことなども検討しましょう。

  1. ベンチマーカーで負荷をかける
  2. リクエストを捌けているか、レスポンスタイムが遅くないかなど確認する
  3. 問題があれば、リソース監視からボトルネックを大まかに推測する(ウェブなのか、DBなのかなど)
  4. プロファイリングなどを活用し、ボトルネックを絞り込む(メモリなのか、listen queueなのかなど)
  5. 問題を解消する仮説を立て実行し、マイクロベンチで検証
  6. 1に戻る

CMだからといって特別なことはしておらず、やはり基本に忠実に対応することが主になります。

負荷に耐えられるようにする

ただ、大きな負荷に耐えられるようにする・可用性を上げるという観点で、いくつか普段のオペレーション以外にやっておくべきことがあるので説明します。

使うインフラへの申請祭り

ここではAWSを例に挙げて、必要となる申請事を説明します。AWSでは大きく必要なことは3つあります。

  1. ビジネスサポートへの加入
  2. ロードバランサの暖機運転
  3. 上限緩和

1. ビジネスサポートへの加入

入らずに済ませることも出来るとは思いますが、以下の観点から入っておくと安心です。

  • ロードバランサの暖機運転が出来る(自分でも暖気しようと思えば出来はしますが…)
  • AWSサービスについての疑問点が出た際に質問を投げられる
  • CM期間中に障害が発生した際に24時間チャットや電話で相談できる

ドキュメント化されてない知見を教えて頂いたり、IaaSの裏側にいるからこそ出来る障害調査なども行ってくれるので、個人的には入っておくことを推奨します。

AWSの回し者ではないですが実際CMの準備期間から実施中まで、色々助けて頂きました。

2. ロードバランサの暖機運転

ALBやELBは急激なリクエスト増加が起こると、スケールアウトが間に合わずエラーコードを返してしまう恐れがあるので、見積もったリクエスト数を添えて事前に暖機運転の申請を行いましょう。

スポットCMの場合、スパイクがあるというより、放映期間中のトラフィックが底上げされるイメージなので(弊社マーケティング担当の受け売り)、特別なイベント事が無ければ放映期間の最初さえ乗り切ってしまえば大丈夫かなという感触でした(一定数のトラフィックが継続的にあれば、スケールした状態は保たれる)。

3. 上限緩和

こちらの上限緩和については、ボトルネック解消時に行うことにはなると思いますが、一通り確認しておくと想定外のことに悩まされずに済みます。EC2の中やLambdaのコードを必死に覗いていたけど関係なかった、なんてことが防げます。

  • CloudFront: 1 秒あたりのリクエスト数
  • EC2: オンデマンドインスタンス、スポットインスタンス、それぞれインスタンスタイプにおける起動数
  • Lambda: 同時実行数
  • Aurora: 起動数
  • ...

他にも色々あるので、一通り自分が使用しているサービスの制限についは目を通しておいた方が良いかなと思います(AWSドキュメントに記載があります)。

f:id:appbrew-sota:20190923212313p:plain:w300
応援に駆けつけてくれるAWSサポートの方のイラスト

"最中"の運用

一番サーバを注視しておかないといけないのは、CM放映開始時とGRPを多く獲得出来るときです。

それ以外は想定外のことが起こらないか、監視体制を作っておくと良いでしょう。

監視

大きく外形監視とリソース監視に分けられるかなと思います。挙げていくとキリが無いので、ほどほどに列挙しました。

実用上問題がないのに厳しくしすぎると、オオカミ少年アラートが出来上がって疲弊するので(私です)、バランスを見極めて設定しましょう。

1. 外形監視

  • レスポンスタイム
  • レスポンスコード
  • シナリオテスト

2. リソース監視

  • レスポンスタイム(平均、中央値、95パーセンタイル、90パーセンタイル)
  • DBのCPU使用率、メモリ使用率、レイテンシ、Performance Insights
  • ElastiCache、Elasticsearch、Kinesis、Dynamo ...

通知体制

Slackに加えPagerDutyなどを使って電話させとくと気づきやすいです。

障害対応

もしデプロイ起因であれば、1にも2にもロールバックしましょう。慌てて対応するとろくな結果を生み出しません。

そのためにBlue-Green Deploymentやカナリアリリースなども有効です。

f:id:appbrew-sota:20190923212513p:plain:w300
障害対応のイラスト

Continuous Integration

CMの効果を見ながら、追加の開発をすることもあるでしょう。ただ何か起こった時の影響範囲を抑えるために、デプロイをする時間帯はトラフィックの少ない時間帯に縛っておくと良いかなと思います。

"事後"の振り返り

リソースのお片付け

CM放映が終わると、CMがある度に流入が跳ねるというスパイクは無くなっているでしょう。コスト削減のために、今一度見直すのが吉です。

CMの効果および対応が適切だったか

一番最初に挙げた目的は達成できたでしょうか。達成できなかったとしたら、何が問題だったのか、インフラで出来たことは何かなど振り返りましょう。

次に繋げて改善し続けることで、次のCM施策はもっと上手く出来るでしょう。

おわりに

以前まで、自分はCM放映と聞くと「何か華やかでイケてる感が出てそう!」と浮足立ってました。

ただ実際にやってみると、費用対効果を得るためにやらないといけないことは多く、またそれらは大半が泥臭い準備です。

けどそれだけ、目的を達成できた時は感無量です。この記事が貴方の目的達成の一助になれば幸いです。

参考になったらはてブ、コメント、SNSシェアなど頂けると喜びます!

We are Hiring!

弊社AppBrewでは現在、400万DL突破のコスメクチコミアプリ「LIPS」をはじめとした「ユーザーが熱狂するプロダクト」を、「再現性をもって開発すること」に携わるエンジニアを積極採用中です。

目的に真摯に向き合い、技術でそれを解決したいと思うエンジニアの方はぜひ一度ご応募ください!お待ちしております。


  1. ウェブサービスを高速化するコンテスト。詳しくはISUCONの過去問を読むを参照。