
【レポート】ロマサガRSの大規模トラフィックを捌くAmazon ECS & Docker 運用の知見 #AWSSummit
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは。サービスグループの武田です。
プレイしてますか?ロマサガRS。私はやってます。総戦闘力はもうすぐ95万くらいです。メインスタ半にSSスタイル2倍キャンペーンなど、ハーフアニバーサリーのイベントで毎日忙しいですよね。AWS Summitに参加している場合じゃないですよ!いや参加している場合ですけども。
2019年6月12日(水)から14日(金)の3日間、千葉県幕張メッセにてAWS Summit Tokyo 2019が開催されています。こちらで講演されたセッション「I3-04 ロマサガRSの大規模トラフィックを捌くAmazon ECS & Docker 運用の知見」を聴講しましたのでレポートします。
AWS Summitでは全セッションで撮影が基本NGということですので、文字だけでお届けします。
概要
ロマンシング サガ リ・ユニバースではローンチ直後、想定の数倍以上のトラフィックに恵まれましたが、大きな障害を起こさずに運用できました。本セッションではロマンシング サガ リ・ユニバースが採用したAWSアーキテクチャ、運用について解説します。
・ロマンシング サガ リ・ユニバースのAWSアーキテクチャ
・大規模トラフィックをさばくための準備
・Amazon ECS & Docker を継続的に運用するためのパイプライン、工夫これらのキーワードに興味をお持ちの方は、ぜひご参加ください。
スピーカー
- 株式会社アカツキ エンジニア
- 駒井 祐人
 
 
(※敬称略)
レポート
- アジェンダ
- 0.ゲームシステムの特性
 - 1.アーキテクチャ編
 - 2.負荷対策編
 - 3.運用の工夫編
 
 
0.ゲームシステムの特性
- トラフィック量の増減の例
- お昼休みにアクセスが増える
- お昼休みにゲームをする人が多い
 
 - 翌日は前日の2倍のアクセス量
- 新しいイベントをリリースした日などはアクセスが集中する
 
 - こういったアクセスパターンはゲームではよくある
 
 - お昼休みにアクセスが増える
 - 最大ピークが読みづらく、スケールするシステムが求められる
 
1.アーキテクチャ編
アーキテクチャの全体像、構成要素を紹介。
- ロマサガRSの紹介
- 2019/12 スクウェア・エニックスからリリース
 - 23年ぶりのロマサガ完全新作
 - ロマサガ3の300年後の世界
 - シリーズの枠を超えてキャラが登場
 - リリース1ヵ月以内に、10,000,000ダウンロード達成
 - ゲームシステム上、一人のユーザーが継続的にAPIサーバーにアクセスする
 
 - アーキテクチャ全体像
- 静的ファイルはCloudFront + S3
 - お知らせサーバー、ゲームサーバー、認証サーバーがフロントサーバーとして存在する
- お知らせ用のサーバーは独立している
 - ゲームサーバーはダメージ計算などゲームのロジックを返すサーバー
- バックエンドにAuroraとElastiCacheがあり、プレイヤーデータの保存およびsession/cacheの保存をしている
 
 - 認証サーバーはそのまま認証用のサーバー
- 認証データはDynamoDBに保存
 
 
 - フロントサーバーはすべてECSで構成
- 技術要素としてはnginx、Fluentd、Jenkinsなど
 
 
 - サーバーサイド言語にはElixirを採用
- 並列性が高く、十分に高速
 - API数100以上、リクエストサンプル数3000K以上をグラフにプロットすると、ほぼ50msを切る性能
 - ロマサガRS における Elixir サーバー開発実践 ~生産性を上げてゲームの面白さに注力~ - Speaker Deck
 
 
インフラ構成管理
- 99%のAWSリソースをCloudFormationで管理
- オペミスは0
 - 複数環境でも差分がない
 - 新しい開発環境も1コマンドでできる
 
 - kumogata/kumogata2でコード管理
- Ruby製のCloudFormationラッパーツール
 - 条件分岐などのコードが書ける
 - 秘匿情報を環境変数化してSSMから取得など
 
 
プロセス構成管理
- 100%Docker運用 
- 構成管理するプロセスはすべてDocker化している
 - 安定したデプロイ
- デプロイ/スケーリングトラブルはリリース後一度もない
 
 - デプロイしているものと同じImageをローカルで起動
 
 - オーケストレーションはECSを採用
- デプロイ/デプロイロールバック
 - オートスケーリング
 - オートヒーリング
 - 本番リリース時は、EKSはまだ東京GAではなかった
 
 
Fargateは?
- 一部のプロダクション環境で使っていたがEC2/ECSに戻した
 - Pros(メリット)
- サーバーレス
 - 簡単にスケールする
 
 - Cons(デメリット)
- スケール時間があまり早くない
- EC2のスケール時間と変わらない
 
 - ロギング
- 当時はCloudWatch Logsのみサポートだった
 
 
 - スケール時間があまり早くない
 
ロギング
- CloudWatch Logs
- エラーのみフィルターしたアプリケーション/ミドルウェアログ(infoとかは落としてる)
 
 - Datadog
- エラーのみのミドルウェアログ
 
 - S3
- アクセスログなど、Athena分析
 
 - その他
- 行動ログ
 - ここでは言えないデータ
 
 
監視
- CloudWatch
 - Datadog Infrastructure
 - Datadog APM(Application Performance Management)
 - Datadog Log Management
 - Sentry
 
分析
- Redashでダッシュボード作成、可視化
 - ログの総量は150TB
 - 200 Queries
 - 90 Graph
 
ロギングや監視は各種サービスを導入し、足りない機能を補っている。
2.負荷対策編
- 負荷テストの心得
- 大前提として負荷テスト&改善フェーズは必ず確保する
- ギリギリに実施すると間に合わない可能性
 
 - テストごとの目的/ゴールを設定する
- 負荷テストをして負荷を確認することが目的ではない
 
 
 - 大前提として負荷テスト&改善フェーズは必ず確保する
 - 負荷テストツール
- Locustを採用
 - シナリオのメンテナンス性を重視
- Pythonでシンプルに書ける
 - 多くのエンジニアが読み書きできる
 
 - Locust自体もDocker化
- 1コマンドでスケール
 - 数十コア巨漢インスタンスなどで簡単に立ち上げられる
 
 - さらっと10000req/sとか出せる
 
 
目的ごとにさまざまな負荷テストを実施。
単性能テスト
- アプリケーション特性をAPMで分析&改善
- 改善の繰り返し
 
 - 低負荷でOK
- N+1クエリ検出などが狙い
 
 
過負荷テスト
- 各コンポーネントに過負荷をかける
- EC2だけ過負荷、RDSだけ過負荷など
 - 負荷テストシナリオに沿って負荷をかける
 
 - ボトルネック、エラーになる箇所、原因を特定し修正
- (例)EC2のCPUUtilization 70%ぐらいからエラーが出始める
 - → どこかのパラメーターの制約に引っかかっていないか?
 
 
高負荷テスト
- スケールアウトの確認
- EC2/ECSスケールアウト確認
 - DB/ElastiCacheの垂直/水平分割の確認
 
 - シナリオごとの負荷特性を確認
- リセマラシナリオ
 - 特定の更新APIを大量に引くシナリオ
 
 - システムサイジング
 
障害テスト
- 一部のコンポーネントに意図的に障害を起こして、サービスが継続するか確認する
- (例)負荷テスト中にAuroraをfailoverさせる
- Cluster EndpointのDNS切り替えが未完了時に再接続すると、Reader側のDNSをキャッシュしてしまう問題などを検知
 
 
 - (例)負荷テスト中にAuroraをfailoverさせる
 
長時間テスト
- 文字通り一晩中など、長時間かける
- メモリリークやfd枯渇などを検知できる可能性
 - 時間とともにCPUUtilizationが右肩上がりになったりすると危険信号
 - CloudWatch Logsの料金の肌感覚
 
 
負荷テストのPDCAを高速化する工夫
- 素早くスケールする負荷テストツール
 - プレイヤー資産を付与するデバッグAPI
- データインポートなどを都度しないといけないとPDCAが遅れる
 - データを用意する必要がなくなり気軽に負荷テストがかけられる
 - プレイヤー資産がないとN+1も検知しづらい
 
 - 何度でも壊して作り直せるインフラ
- CloudFormation
 
 - メトリクス監視のCloudWatchダッシュボード
 
実際にテストしたからこそ発見できた問題
- N+1問題
 - DBのパラメータ上限
 - 長時間負荷によるスロークエリ
 - 巨大レスポンスによるネットワーク帯域圧迫
 - Aurora failoverのキャッシュ問題
 
なおリリース後の実績として、最大700コンテナ、100%の可用性を達成。
ECSスケーリングの工夫
- ECS Application AutoScalingの課題
- スケールアウト
- スケールアウトするにはEC2リソースが用意されていることが前提
 - EC2とECSの2つのAutoScalingを設定
 
 - スケールイン
- スケールインするEC2上のECSを停止させたいが、停止するEC2とECSタスクが一致する保証はない
 
 
 - スケールアウト
 - 具体的な解決方法
- ※具体的な設定を解説されていましたがあまりメモできませんでした
 - 次の記事とおおむね同じ構成だったかと思われます(thank you, yuto.komai)
 - Amazon ECS におけるコンテナ インスタンス ドレイニングの自動化方法 | Amazon Web Services ブログ
 
 - 工夫についてまとめ
- スケールアウト時間は2分ほどで完了
 - トラブルなし
 - 繰り返し実施できるしくみが大事
 
 
3.運用の工夫編
デリバリーパイプライン
- GitHub、CodeBuild、ECR、ECS、CloudWatch Events、Lambdaを組み合わせて実現
 - ビルド環境:CodeBuild
- 並列性が高い
 - コスト
- 従量課金で安い
 
 - その他
- SSMパラメーター連携など便利
 
 
 - 100 build/day 以上
 - $100/month
 - インスタンスタイプはmidiumを利用
 
サーバーレス運用の工夫
- バッチ
- バッチ処理を行いたい場合、EC2を使うとコスト高になりがち
 - CodeBuildでビルドしたイメージをECRにpush後、次のCodeBuildでpullして処理するアーキテクチャを採っている
 
 - メリット
- ビルド/コンパイル済みのアプリケーションを再利用可能
 - サーバーレスバッチの実現
 - コスト減(c5.xlarge相当を想定)
- EC2:$154/month
 - CodeBuild:$9/month
 
 
 - デメリット
- プロビジョニングに30~40秒余計な時間
 
 - 実際に使っている例
- アイテムドロップシミュレータ
- 5~8min
 
 - DB並列マイグレーション
- 10min * 並列数
 
 
 - アイテムドロップシミュレータ
 
自動復旧
- システムが巨大なら自動復旧は必須
- Datadog、SNS、Lambda、ECS、Slackを組み合わせて実現
 - Datadog infrastructureがAlartを検知
 - SNSにメッセージ飛ばす
 - Lambdaでparse → EC2特定
 - 対象のEC2インスタンス上のECSタスクのみ再起動
 - Slackに通知
 
 - Auroraのfailoverキャッシュ問題も同じしくみで解決している
- ローリングアップデートの命令をECSに飛ばすことでキャッシュクリアする
 
 
まとめ
- CloudFormationとDockerで本番環境でのトラブル0
 - 目的に合わせ、さまざまな負荷テストを実施
 - デリバリーパイプラインやバッチなどコストを抑えた運用
 - 自動復旧は必須
 
最後に
ロマサガRSがリリースされて約半年ですが、継続して安定運用されているすばらしいサービスです。その安定運用の裏側ではこんなことがされているんだなと知れて、とてもおもしろく聴講できました。悪いことはいわないから、白薔薇姫は引いておこ?な?







