Weitere ähnliche Inhalte
Ähnlich wie スタートアップで培ったアーキテクチャ設計ノウハウ (20)
Mehr von Masakazu Matsushita (20)
スタートアップで培ったアーキテクチャ設計ノウハウ
- 34. • 可能な限り安価で
• 管理画面はイヤ
• 開発も運用も面倒
• 引き継ぎなどでドキュメントが必要
• メンバーの誰でもできるように
• 片手間でもできるぐらいの手軽さが欲しい
制約
Case 2: お手軽なCS対応がしたい
- 38. アーキテクチャ
Case 2: お手軽なCS対応がしたい
Admin Server
MySQL
ELB
EC2
EC2
S3
OpsWorks
RDS
EC2
SNS
Socket Server
API Server
CloudWatch SNS Lambda
Slack
プッシュ通知
画像削除
名前変更, BAN,
コイン補填, …
アラート通知
ChatOps!
デプロイ
ビルド
S3
アップロード
APK
IPA
APK
IPA
- 45. WorkDocs
MySQL
ELB
EC2
EC2
S3
OpsWorks
Redis MySQL
SES SNS SQS
EC2
SNS
Route 53
リアルタイム対戦
Socket Server
API Server
Admin Server
CloudWatch SNS Lambda
Google
BigQuery
SNS
SQS
IAM EC2
Localization
Server
Google
Analytics
全体アーキテクチャ
Easy Deployment,
Auto Scale
(Load & Time)
ユーザデータゴースト用
バトルログ
ランキング,
一時データ
プロフィール画像,
言語ファイル, etc
メール送信
メール送信
失敗時
プッシュ通知
device token登録
fabric,
rake tasks
画像削除
名前変更, BAN,
コイン付与, …
Auto Scale
Dynamic
DynamoDB
クラッシュログ
ログ分析
パフォーマンス監視
アラート通知
デプロイ
アクセス分析
DynamoDB
Slack
ChatOps!
ビルド
S3
アップロード
クラッシュ分析
APK
IPA
APK
IPA
- 52. 後日談 1
• 1ヶ月で1,000万DL突破した頃, APIでエラー発生…!
Saved Games API の呼び出し頻度が他社の作品に比べて非常に高く、
Google 側の処理の一部にエラーが発生しております。(中略) 現在担当
チームは対応に苦慮しております。
それだけ流行ったとポジティブに捉えつつ,
慌てて同期頻度を調整してエラーを回避
(正直, こまめに同期しちゃダメとかドキュメントに書いてなかったし…)
Case 4: サーバなしの構成にしたい
- 57. • SNS → SQSでキューイングして非同期処理
• rake tasksでポーリング処理
(当時はVPCの関係でLambdaが使えなかった)
• プレイログは随時DBに反映
• 通報内容は集計処理をかけてSlackに通知
解決策
Case 5: プレイログや通報内容を楽に処理したい
- 60. WorkDocs
ELB
EC2
S3
OpsWorks
Redis MySQL
EC2
SNS
Route 53
API Server
Admin Server
CloudWatch SNS Lambda
Google BigQuery SNSSQS
IAM EC2
Localization
Server
Game Center iCloud KVS
iOS
Google Play
Saved Games
Google Play
Game Services
Android
+
Aurora
SNS SQS
EC2
全体アーキテクチャ
言語ファイル
ステージ
クリアデータ
ステージ
クリアデータ
プロフィール画像, etc
ユーザデータ,
ステージデータ
ステージの
クリア率算出
ランキング
イベントや
オリジナルステージ
利用時のみアクセス
プッシュ通知
device token登録
アイテム付与,
BAN, …
パフォーマンス監視
アラート通知
クラッシュログ
デプロイ
アクセス分析 コンテンツ
アップロード
CognitoGoogle
Analytics
Slack
ChatOps!
ビルド
クラッシュ分析
S3 APK
IPA
APK
IPA
アップロード
Async Worker
rake tasks
- 66. App Server
アーキテクチャ
Case 6: リソースダウンロードの仕組みを最適化したい
S3
<RoutingRules>
<RoutingRule>
<Condition>
<KeyPrefixEquals>resources/master.manifest</KeyPrefixEquals>
</Condition>
<Redirect>
<Protocol>https</Protocol>
<HostName>xxxxxxxx.netdna-ssl.com</HostName>
<ReplaceKeyWith>
resources/master/1560167739/master.manifest</ReplaceKeyWith>
<HttpRedirectCode>302</HttpRedirectCode>
</Redirect>
</RoutingRule>
</RoutingRules>
リダイレクトルール
resources/master.manifest
resources/master/[version#]/master.manifest resources/master/[version#]/master.manifest
ALB EC2
MySQL
(App)
Aurora
API呼び出し時のレスポンスで
リソースの更新を検知
新しいリソースを取得
version#のリソースに
リダイレクト
- 69. • キャラクターのデータは全てS3上で管理
• Rails (unicorn) で扱うにはI/Oがネックになるため,
クライアントから直接S3の一時領域にアップロード
• サーバはトランザクション内でS3間をファイル移動,
DBはS3への参照情報のみを持つ
• ファイルのダウンロードはMaxCDNを経由
解決策
Case 7: 作成されたキャラクターを効率よく管理したい
- 74. • MQTT (EMQ) でリアルタイム通信を処理
• 公称1台のサーバで100万接続をさばける
• マスターレスなクラスター構成を構築
• 再接続時に切断中のデータも取得可能
解決策
Case 8: リアルタイムにバトルデータを処理したい
- 76. • Async Workerがバトルを確実に終了
• バトルの終了時間検知用のSQSをポーリングして
Async Worker起動
• 対象が終了していないバトルの場合は, Mediatorが
追記していたバトルデータをEFSから取得し強制終了
解決策
Case 8: リアルタイムにバトルデータを処理したい
- 83. • 可能な限り安価で
• 処理が重くなりそう
• リーグ確定 (昇降格, 報酬付与, ランキング確定)
• クラン戦 (マッチング, スナップショット作成,
報酬付与, ランキング確定)
• ちゃんと動いていることを通知してほしい
制約
Case 9: 週次のバッチ処理を楽に運用したい
- 84. • Lambda + Step Functionsで並列バッチ処理
• CloudWatchのcronでStep Functionsを起動
• Lambdaを並列実行 (多いものは最大100プロセス),
進捗をRedisに格納してワークフローを制御
• 実行結果はSlackに通知
解決策
Case 9: 週次のバッチ処理を楽に運用したい
- 90. • インフラは落ちる前提, 頑張りすぎない
• SPOFを回避, 影響を最小限に留めて安眠運用
• 障害を許容するアーキテクチャ
• Brain Warsのゴーストバトル(DynamoDB)
• Brain Dotsのオフラインプレイ
(AppleやGoogleのプラットフォーム機能)
インフラに完璧を求めない