[レポート]サーバレスアーキテクチャで実現した『M-1グランプリ2015』敗者復活戦投票システム #AWSRoadshow

2016.11.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは、中山です。

2016年11月22日(火)ハービスホールにて行われたAWS Cloud Roadshow 2016 大阪に参加してきました。本エントリでは15:00から導入事例トラックで発表されたサーバレスアーキテクチャで実現した『M-1グランプリ2015』敗者復活戦投票システムというセッションの内容についてレポートしたいと思います。

資料

※ 資料がアップされ次第反映いたします。

スピーカー

  • 小南 英司さま
  • 朝日放送株式会社
  • 技術局 開発部
  • サーバサイドからアプリ開発まで幅広く担当

アジェンダ

  • 朝日放送について
  • M-1グランプリ敗者復活戦について
  • 開発当時の状況
  • システムの概要
  • サーバーレスアーキテクチャを採用した理由
  • Kinesis/Kinesis enabled APP on EC2/DynamoDB
  • Apache JMeterを利用した負荷試験
  • リージョンレベルのDR対策
  • 放送当日のアクセス数
  • 2016年のシステム変更箇所

朝日放送について

  • 大阪に本社を置く放送局
  • 関西圏向けのローカル番組や全国区向けの番組を制作
  • システムやアプリは内製で作成している

M-1グランプリ敗者復活戦について

  • M-1グランプリとは2001年から2010年までやっていた漫才コンテスト
  • 2015年、5年ぶりに復活した
  • お笑いコンビが漫才を披露し、優勝者を決めるという内容
  • 番組制作とシステム構築の両方を朝日放送が担当している
  • 決勝戦の前に予選で負けたコンビの敗者復活戦がある
  • 20組の内、復活戦で勝った1組が決勝戦に参加できる
  • 復活戦の結果は視聴者からの投票数が一番多いコンビが選ばれる
  • 投票数の集計とデータの表示システムを作成した
  • 敗者復活戦という番組の性質上、サービスを絶対に止められない
  • 高い可用性が必要だった

開発当時の状況

  • 大半のシステムがオンプレで動いている
  • そのため、AWSの経験は浅い状態だった
  • 社内の導入事例が無い中、膨大なデータを処理するシステムを手探りで内製開発した
  • 担当エンジニアは2名体制
  • スケジュールが厳しく、1ヶ月半程度しかなかった

システムの概要

  • システムは大きく4つの機能からなる
    • Webサーバ機能
    • 投票データ処理
    • 結果表示
    • 管理機能
  • Webサーバ機能は前段にCloudFront、オリジンにELB、バックエンドにEC2という構成
    • サイトは基本的に静的なものなのでCloudFrontでキャッシュさせている
  • 投票データ処理は前段にKinesis、後段にKinesisのデータを処理するEC2、データストアにDynamoDBという構成
    • この部分が本システムの肝
    • Kinesisというフルマネージドのストリーム処理サービスを利用したことで素早い投票データ処理システムの開発を実現
    • Kinesisに視聴者から送られた投票データをバッファリング
    • 後段のEC2でデータを処理してDynamoDBに格納するという構成
    • DynamoDBの高い拡張性、自動バックアップもとても便利に使えた
  • DynamoDBからデータを取得してEC2で結果表示
    • リアルタイムで番組ディレクターが結果を確認できるようにした
    • DynamoDBのテーブルをscanで定期的に出力し、それをWeb画面から見れるようにしている
  • 管理機能はCloudWatchを利用して、システム運用者が確認

サーバーレスアーキテクチャを採用した理由

  • 実はオンプレにも同じようなシステムはすでにあった
  • このシステムは現在でもさまざまな番組で利用している
    • みんなの家庭の医学、選挙ステーションなど
  • 当初このシステムを今回も利用しようと検討したが見送った
  • M-1グランプリは5年ぶりの復活で注目度が非常に高い
    • 一年に一度だけ開催される重要なイベント
    • 視聴率が非常に高い(関西圏では35%)
  • システムへのアクセスは投票開始直後に急激に伸びる(バーストトラフィック)
  • このバーストトラフィックにオンプレシステムでは耐えられそうにないと判断
    • また、一ヶ月半というスケジュールでは番組放送までにシステム増強は難しい
    • この作業に手を取られるとアプリケーション開発へ人的リソースを投入できなくなる
  • 5年前はまだガラケー利用者が多かったが、スマホが普及した現在、通信量の増大も懸念していた
  • こういった問題に対処するため、AWSのマネージドサービスをフル活用したシステム≒サーバーレスアーキテクチャを採用
  • フルマネージドなのでサービスの可用性/運用面をAWSにまるっとおまかせできる
  • アプリケーション開発という一番重要な作業に時間を投入できることを期待
  • また、AWSはドキュメントやSDKが豊富に揃っているという点もうれしかった
  • AWSは開発者へのサポートが充実している

Kinesis/Kinesis enabled APP on EC2/DynamoDB

  • Kinesisはバースト対策に最適
  • システムへのトラフィックは投票開始直後の1分間に全体の2〜6割を占める
  • このバーストトラフィックの処理がKinesisなら可能
    • 指定したシャード数のトラフィックはきちんと受け止めてくれる
  • 後段のKinesis enabled APP on EC2で処理するデータ量を調整する仕組みを開発した
    • Kinesisへ数万レコードの大量データが届いても、そのデータを一度に処理するのではなく、例えば数千レコードずつ処理するといったことができる
    • 一気に処理してしまうとEC2が高負荷になり、サチってしまう状態を回避
  • データ形式がシンプルだったためRDBMSではなくNoSQLサービスのDynamoDBを採用できた
    • テーブルは2種類だけ
    • 投票データテーブル、投票者と投票先コンビ名を保存
    • 投票数テーブル、コンビ名とその投票数を保存
  • DynamoDBのAtomic Counterを利用した投票数のアップデートを採用
    • 投票データ毎に投票先コンビ名を判定し、 UpdateItem メソッドによって各コンビの得票数を更新
    • データの更新前に投票データテーブルを参照して、データがまだ無い場合に限り投票できる仕組みにした
    • 2重投票や組織票などの不正なデータを排除するため
  • Kinesis enabled APPはオンプレ時代のノウハウも投入している
  • 高速処理、複数スレッドによる並列処理とパラメータの最適化
  • 今回はM-1グランプリ用に開発したが、パラメータを指定して別のシステムでも汎用的に利用できるように実装した

Apache JMeterを利用した負荷試験

  • 負荷試験にはApache JMeterを利用して、事前に何度もテストを実施した
  • 負荷試験システムはEC2が16台で、ELBを挟んでデータ投入スクリプトを実行するEC2(20台)からKinesisへという構成
    • 事情により少し変わった構成になっている
  • 想定アクセスの最大10倍程度の投票リクエストをKinesisに流した
  • 300万件/20分、最大1万件/秒

リージョンレベルのDR対策

  • バージニアリージョンに東京リージョンとほぼ同一のバックアップ用システムを構築した
    • バージニアにした理由はAWS誕生地なので、利用可能なAWSサービスが豊富かつリソースの枯渇が発生しなさそうだったから
  • 東京リージョンのKinesisで受信したデータはバージニアでも集計できるようにデータを流した
    • Kinesis(東京) - Kinesis enabled APP on EC2(東京/バージニア) - DyanmoDB(東京/バージニア) - 結果表示(東京/バージニア)
  • バージニアにもKinesis立ててるが正常時にはトラフィックを流していない
    • 東京リージョンがもしダウンした場合にバージニアリージョンでデータを受ける構成
  • EC2の構築を簡易にするため、起動したリージョンに応じて設定ファイルを自動で書き換えるスクリプトを開発
    • 別リージョン間でもその設定を入れた同一AMIから起動させるようにした
    • リージョン毎に設定ファイルそのものを分けると管理が煩雑になり運用コストが上がるため
    • 他にも例えばDynamoDBのRead/Write Capacityを簡単に変更できるようなスクリプトを作成し、少人数でも運用を回せるような仕組みを投入している
  • Kinesisに流れたデータは後段のEC2以外に、Lambdaで定期的に取得しS3へバックアップするという仕組みを入れた
    • 万が一、KinesisがダウンしたとしてもS3上のデータからリカバリ可能
    • また、S3のデータは放送終了後にデータ解析などで有効利用している

放送当日のアクセス数

  • 投票開始16時15分でトラフィックがピークになった
  • アクセス数は想定したものとほぼ同じ
  • 長年の経験が生きた
  • ちなみに、敗者復活戦で勝ち上がったトレンディエンジェルが決勝戦で見事勝利
  • こういったドラマを陰ながら支えられたことがとてもうれしい

2016年のシステム変更箇所

  • 今年もM-1グランプリ実施する
  • 去年のシステムと異なる部分はAPI Gatewayの導入
    • 前段にCloudFront置いて、オリジンにAPI Gateway、そこからKinesisにデータ流すという構成
  • 去年まではWebからの投票のみだったが、データ放送からも投票可能になったため
  • データ放送はHTTPと比較するとさまざまな制限があるためKinesisにそのままデータを流すことができない
    • データ放送はBroadcast Markup Language(BML)という特殊な形式で記述する
    • スクリプト上で使える関数が限られる
    • POSTのみ可能
    • POSTで送信可能なパラメータが一つだけ
  • Webの投票は以前と同じくKinesis

感想

サーバーレスアーキテクチャは個人的に興味がある分野ということもあり、非常に興味深くセッションを聴講しました。スケジュールが厳しい中、大量のデータを処理するシステムを素早く開発できたのは素直にすごいなと思いました。小南さまを始めとする優秀なエンジニアの方と、AWSが提供している質の高いサービスにより実現した素晴らしい事例だと思います。