Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
7年間運用したソーシャルゲームをAmazon EC2構成からAmazon ECS構成へと乗り換えた話
Search
こもじゅん
January 29, 2025
Programming
69
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
7年間運用したソーシャルゲームをAmazon EC2構成からAmazon ECS構成へと乗り換えた話
YAPC2022での発表スライドです
こもじゅん
January 29, 2025
More Decks by こもじゅん
See All by こもじゅん
甲子園ポケットの思い出を残そう
commojun
0
37
長年運用されている Web サービスと 通信をするクライアントを Go で作ってみた話
commojun
0
1.1k
XWalkViewを利用したクロスプラットフォームアプリの開発
commojun
0
940
Other Decks in Programming
See All in Programming
Webフレームワークの ベンチマークについて
yusukebe
0
160
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
240
dRuby over BLE
makicamel
2
330
A2UI という光を覗いてみる
satohjohn
1
130
Spring Security 実践 ─ GraphQL APIで実務に役立つ 認証・認可 を学ぶ
wagyu
0
230
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
2
620
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
340
CSC307 Lecture 17
javiergs
PRO
0
320
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
190
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
AIで効率化できた業務・日常
ochtum
0
130
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
3.7k
Featured
See All Featured
Designing for Performance
lara
611
70k
Side Projects
sachag
455
43k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
140
How to build a perfect <img>
jonoalderson
1
5.6k
A designer walks into a library…
pauljervisheath
211
24k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
300
KATA
mclloyd
PRO
35
15k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
AI: The stuff that nobody shows you
jnunemaker
PRO
8
710
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
180
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Music & Morning Musume
bryan
47
7.2k
Transcript
7 年間運用したソーシャルゲームを Amazon EC2 構成からAmazon ECS 構成へと 乗り換えた話 1
自己紹介 大澤 純 (@commojun) 2016~ サーバサイドエンジニア@KAYAC 2
アホみたいなことをつぶやいたり 3
バカゲーを作ってリリースしちゃったりしています https://twitter.com/kayac_inc/status/1434804351336255491 4
今日のお話 ぼくらの甲子園! ポケットという長期運用ゲームをコンテナベースのシステムへ移行した 長期運用特有・もしくはこのゲーム特有の事情に合わせた工夫点だったと思う箇所 専門的な内容でも理解を得ながら仕事を進めることの重要性 5
目次 ぼくらの甲子園! ポケットについて EC2 時代のサーバ構成 なぜECS に乗り換えるか ホコリかぶったPerl とモジュールのバージョンアップ 時代に乗ったデプロイ方法にする
ゲームの心臓なのにSPOF になっていたバッチサーバの冗長化作戦 非エンジニアに仕事をわかってもらう 6
目次 ぼくらの甲子園! ポケットについて EC2 時代のサーバ構成 なぜECS に乗り換えるか ホコリかぶったPerl とモジュールのバージョンアップ 時代に乗ったデプロイ方法にする
ゲームの心臓なのにSPOF になっていたバッチサーバの冗長化作戦 非エンジニアに仕事をわかってもらう 7
ぼくらの甲子園! ポケットは2014 年から運用を続けているソーシャルゲームタイトルです。 おかげさまで2021 年10 月で7 周年を迎えることができました。 https://koshien-pocket.kayac.com/ 8
ぼくらの甲子園! ポケットの特徴 ユーザは監督ではなく、選手である ユーザが9 人集まらないと試合すらできない チームメイトの一人ひとりがユーザ ユーザは選手になって甲子園を目指すため、青春を追体験できる 9
ぼくらの甲子園! ポケットの特徴 2 週間に1 回の甲子園大会に出場するためにリーグ戦を繰り返す 甲子園大会はトーナメント戦で1 日かけて行う 優勝すると、優勝チームの要望に応えた新聞を運営が作成し、ゲーム内に掲載する 10
ぼくらの甲子園! ポケットの特徴 リーグ戦の試合は毎日定刻に開始 参加するには決まった時間にログインしなければならない 作戦会議中にスキルを発動したり、仲間にエールを送ったりする 作戦会議が終了すると完全オートで試合が進行する 複雑なアクションは無く、戦況に応じてどのスキルを使うかが重要 打席・試合の結果は全てサーバのバッチ実行によって決定する 11
目次 ぼくらの甲子園! ポケットについて EC2 時代のサーバ構成 なぜECS に乗り換えるか ホコリかぶったPerl とモジュールのバージョンアップ 時代に乗ったデプロイ方法にする
ゲームの心臓なのにSPOF になっていたバッチサーバの冗長化作戦 非エンジニアに仕事をわかってもらう 12
ぼくらの甲子園! ポケットは2014 年9 月12 日リリース 当然開発はそれよりも前に開始していた。その頃の時流に乗ったサーバ構成 13
役割に応じたEC2 インスタンスがあり、必要に応じてオートスケールをしたりする Aurora MySQL や、Elasticache (Redis )などマネジメントされた物を利用 batch サーバ上でcrond が常駐して、定刻の試合開始を行っている
14
目次 ぼくらの甲子園! ポケットについて EC2 時代のサーバ構成 なぜECS に乗り換えるか ホコリかぶったPerl とモジュールのバージョンアップ 時代に乗ったデプロイ方法にする
ゲームの心臓なのにSPOF になっていたバッチサーバの冗長化作戦 非エンジニアに仕事をわかってもらう 15
1, Amazon Linux のサポート終了 EC2 上で利用しているOS のサポートが2020 年末に終了するため 何かしら手を打たなければならなかった 後継OS
Amazon Linux2 への乗り換えという選択肢もあるが… https://aws.amazon.com/jp/blogs/news/update-on-amazon-linux-ami-end-of-life/ 16
2, コンテナを利用したサーバ構築が当たり前になりつつある 他のゲームタイトルやサービスで、Amazon ECS を使った サーバ構成について社内に知見が貯まっていた 17
3, このゲームの運用を10 年続けたい! 長期運用タイトルにする意思がチームの総意としてあった リリース時から時代が変わっているので、将来性のある構成に乗り換えよう! 18
目次 ぼくらの甲子園! ポケットについて EC2 時代のサーバ構成 なぜECS に乗り換えるか ホコリかぶったPerl とモジュールのバージョンアップ 時代に乗ったデプロイ方法にする
ゲームの心臓なのにSPOF になっていたバッチサーバの冗長化作戦 非エンジニアに仕事をわかってもらう 19
運用が続くとゲーム体験に関係のある部分に関心が向きがち 20
言語のバージョンとモジュールのバージョンも長らくメンテされていなかった 21
Perl 5.16 👉 Perl 5.30 エイヤで言語バージョンを上げてみる 22
@INC 問題 23
Perl 5.26 での変更点 特にテストコードが影響を受けた https://perldoc.jp/docs/perl/5.26.0/perl5260delta.pod perl バイナリは @INC にパスのデフォルト集合を含んでいます。歴史的に、汚染モード (perl
- T) が有効でない限り、最終的なエントリとして カレントディレクトリ (".") も含んでいまし た。 これは便利ですが、セキュリティ上の問題がありました: 例えば、 カレントディレクト リが(/tmp のように) 信頼できない場合、 スクリプトが追加のモジュールを読み込もうとする と、そのディレクトリの下から コードを読み込んで実行する可能性があります。 v5.26 から、"." は汚染モードの場合だけではなく、 常にデフォルトで 除去されるようになり ました。 これはモジュールのインストールとスクリプトの実行に大きな影響を与えます。 use t::Util; use strict; 1 use warnings; 2 use utf8; 3 4 use Test::More; 5 ... 6 24
@inc のドットに頼ったモジュールはそう多くなかったので、引っ越して対応 Before After https://perldoc.jp/docs/perl/5.26.0/perl5260delta.pod @inc からドットが除去されたことによるテストの問題を修正するとき、 @inc にドットを再挿 入するのは慎重に行うべきです、
これも実行時コードの実際の問題を抑制するかもしれない からです。 可能な限り、明示的な絶対/ 相対パスを使うという前述した手法を適用するか、 必要なファイルをサブディレクトリに再配置して、代わりに そのサブディレクトリを @inc に 追加することを勧めます。 /repository_root |--t |--Util.pm |--testa.t |--testb.t /repository_root |--t |--lib | |--t | |--Util.pm |--testa.t |--testb.t perl -Ilib -It/lib 25
コンパイルエラーしまくる 26
Perl 5.24 での変更点 こういうのがダメ https://perldoc.jp/docs/perl/5.24.0/perl5240delta.pod (autoderef 機能は取り除かれました) 実験的な autoderef 機能
(push, pop, shift, unshift, splice, keys, values, each をスカラ引数で呼び出せ るようにする) は失敗と 判断されました。 これは削除されました; この機能を use しようとす ると ( または以前は 引き起こされていた experimental::autoderef 警告を無効にしようとすると) 例外が発生するようになりました。 my $arrayref = [1,2,3]; while (my $num = shift $arrayref) { # NG! ... } 27
@ をつけて回る作業 ↓ my $item_dic = { one => "hoge",
two => "fuga", three => "piyo", }; for my $item (keys $item_dic) { # NG! ... } for my $item (keys @$item_dic) { # OK my $item_dic = { 1 one => "hoge", 2 two => "fuga", 3 three => "piyo", 4 }; 5 6 ... 7 } 8 28
長いときはpostderef 機能に積極的に頼った ↓ https://perldoc.jp/docs/perl/5.24.0/perl5240delta.pod 接尾辞デリファレンスは実験的ではなくなりました postderef 機能と postderef_qq 機能を使っても警告が発生しなくなりました。 以前使われてい
た、experimental::postderef 警告カテゴリを無効にしている 既存のコードはそのまま動作しま す。 postderef 機能は何の効果もありません; 全ての Perl コードは、スコープ内でどの機能が宣 言されているかに関わらず、接尾辞デリファレンスを使えます。 5.24 機能バンドルは postderef_qq 機能を含むようになりました。 my $arrayref_by_name = { one => [2,3,4], two => [5,6,7], }; while (my $num = shift $arrayref_by_name->{one}){ # NG! ... } while (my $num = shift $arrayref_by_name->{one}->@*){ # postderefに頼る my $arrayref_by_name = { 1 one => [2,3,4], 2 two => [5,6,7], 3 }; 4 5 ... 6 } 7 29
テストが運で落ちたり通ったりする 30
Perl 5.18 ハッシュのランダム化のあおりを受ける keys や values を使って取り出した配列を使ってfor 文を回すような箇所で、 配列の順番に依存したテストが落ちていた https://perldoc.jp/docs/perl/5.18.0/perl5180delta.pod#Hash32randomization
Perl のハッシュ関数が使う種はランダムになりました。 これは、keys(), values(), each() のよう な関数が返すキー/ 値の 順序は実行毎に異なるということです。 my %tests = ( testa => sub { return "aaa" }, testb => sub { return "bbb" }, ); my @expected = ["aaa", "bbb"]; for my $test (values %tests) { is, $test(), shift @expected; # testa から実行されるとは限らない! } 31
モジュールのバージョンを上げてみる 32
蓋を開けてみると見えた問題 そもそも cpanfile.snapshot でのバージョン管理がなされていなかった 後方互換の無いモジュールバージョンアップがうっかり混入してあわてて固定する運用 モンキーパッチを当てたせいでバージョンを上げられない 日本語を含んだJSON のリクエストがどうしても上手くさばけない 33
2 つのOSS にPR を出させていただきました ネストされたJSON リクエストの中に日本語があると正しくエンコードされない問題 ネストされたJSON リクエストが正しくデコードされない問題 https://github.com/kazeburo/HTTP-Entity-Parser/pull/13 https://github.com/moznion/Plack-Request-WithEncoding/pull/3
34
目次 ぼくらの甲子園! ポケットについて EC2 時代のサーバ構成 なぜECS に乗り換えるか ホコリかぶったPerl とモジュールのバージョンアップ 時代に乗ったデプロイ方法にする
ゲームの心臓なのにSPOF になっていたバッチサーバの冗長化作戦 非エンジニアに仕事をわかってもらう 35
EC2 構成からECS 構成へ コンテナベースのシステムへの転換 36
最も恩恵があるのがデプロイまわり 最も変化があるのがデプロイまわり 37
EC2 構成のデプロイ方法 strecher というOSS によるpull 型のデプロイツール デプロイサーバがリポジトリから配布物を取得する デプロイサーバが配布物を全て一つのアーカイブにまとめてAmazon S3 に保存する
各ホストがAmazon S3 から配布物を取得する https://techblog.kayac.com/10_stretcher.html 38
ECS 構成のデプロイ方法 とにかくコンテナイメージをビルドしてリポジトリに収める デプロイ = コンテナインスタンスの入れ替え 39
EC2 構成でのデプロイ方法の利点 Github 上でデプロイ用のブランチが準備できれば、その先のデプロイが迅速 そのスピード感に頼ってデプロイの頻度が多い運用となっていた 40
ビルドが長い ブランチの準備ができてから、ビルドする時間がかかる 41
circleci にビルドさせる ブランチにコミットさえすればビルドされる ECR へのPUSH までのパイプライン 42
2 階建て作戦 base イメージとapp イメージに分ける 夜中に依存パッケージ、モジュール、ツール類をbase イメージでインストール リリース用ブランチへのコミットがある度、アプリケーションコードをコンテナにコピー する Dockerfile.base
Dockerfile 運用上必要な箇所のみにコンテナイメージビルドの時間をかける FROM perl:5.30.0-buster RUN apt-get install 必要なソフトウェア ... $ docker build -t app:base . FROM app:base COPY ./ /home/user/repo/ ... $ docker build -t app . 43
目次 ぼくらの甲子園! ポケットについて EC2 時代のサーバ構成 なぜECS に乗り換えるか ホコリかぶったPerl とモジュールのバージョンアップ 時代に乗ったデプロイ方法にする
ゲームの心臓なのにSPOF になっていたバッチサーバの冗長化作戦 非エンジニアに仕事をわかってもらう 44
とにかくバッチサーバが命 試合進行というゲームの最重要要素が1 台のバッチサーバ(crontab) にかかっていた 45
batch サーバが突然死したときのバックアップ策が存在しなか った(!) ECS 移行を機に冗長化できないか? 46
他プロジェクトでの冗長化事例 CloudWatch Event + SQS + sqsjkr 作戦 47
CloudWatch Event( 今はEventBridge) + SQS + sqsjkr 作戦 CloudWatch Event:
定刻のイベント発火をマネジメントサービス化 SQS: 発火したジョブをキューイング sqsjkr: SQS からジョブを取得し実行する( 排他制御機能があり、冗長化可能) https://techblog.kayac.com/2017/04/10/090000 https://github.com/kayac/sqsjkr 48
ぼくらの甲子園! ポケットでは… crontab.txt cron 書式のテキストファイルで管理している テキストを解析して日時や内容の整合性をチェックするテストが作り込まれている 100 以上のエントリがあるのでCloudWatch Event の上限に引っかかる
運用上、頻繁に書き換える必要がある このフォーマットは維持したい… 10 00 * * * perl script/batch_aaa.pl 12 00 * * * perl script/batch_bbb.pl 16 00 * * * perl script/batch_ccc.pl ... 49
sqsjfr + SQS + sqsjkr 作戦 50
sqsjfr + SQS + sqsjkr 作戦 sqsjfr: crond と同様にスケジューラの役割を果たし、実行すべきジョブをSQS に送り込む
SQS FIFO キュー: 同一メッセージを削除しながらジョブをキューイングする sqsjfr: SQS からジョブを取得し実行する SQS FIFO キューの重複削除機能によって、sqsjfr の冗長化ができる sqsjfr がcron 書式を解釈できるためcron 書式がそのまま使える! https://github.com/kayac/sqsjfr 51
目次 ぼくらの甲子園! ポケットについて EC2 時代のサーバ構成 なぜECS に乗り換えるか ホコリかぶったPerl とモジュールのバージョンアップ 時代に乗ったデプロイ方法にする
ゲームの心臓なのにSPOF になっていたバッチサーバの冗長化作戦 非エンジニアに仕事をわかってもらう 52
ECS 構成への移行作業の意義を非エンジニアの人にわかってもらうのは難しい 53
「ECS 作業はユーザにとってどのようなメリットになりますか?」 54
「ええと…Amazon Linux のサポートが切れるからやらないとダメなんですよ… 」 55
これでわかってもらえる職場は果たして存在するだろうか?(反語) 56
ユーザに直接的なメリットははっきり言って無い でも長く運用するなら必要なこと 説明してわかってもらう必要がある! 57
エンジニアとしての背景知識が必要な専門用語を使っていたら理解してもらえない 58
受け手と伝え手が共に持っている共通言語を使った例えをうまく使う 59
Amazon Linux のサポート切れ Amazon Linux -> Windows に言い換えるととたんに実感がわく 60
なぜECS 構成に移行するのか? ECS (コンテナ技術)とはなにか? なぜわざわざAmazon Linux2 ではなくECS を選ぶのか? 61
それぞれのバックグラウンドを持つが 62
みんなゲーマーという点は共通だった 63
ゲーム機の時代変遷で例えて説明してみる ゲームカセット ≒ コンテナ コンテナの便利さと、いかに当たり前になったかを感じてもらえた https://ja.wikipedia.org/wiki/ ホーム・ポン https://ja.wikipedia.org/wiki/ ファミリーコンピュータ 64
コンテナ技術が当たり前だと訴える 65
66
ECS 移行を理解してもらうことの意義 準備作業はほぼサーバサイドエンジニアだけでやる仕事 それを運用中のサービスに適用するとなると、やはり運用メンバー全員の協力が必要 移行メンテナンスも一筋縄ではいかず、不具合もいくつか起こしてしまった それでも運用メンバー全員がその難易度と重要性を理解していたので 足並みを揃えて問題に対処し、移行作業を完了できた 67
エンジニアの説明責任? 諦めず工夫して説明すれば、高度に背景知識が必要なことも理解してもらえる 専門的すぎるからと非エンジニアの人に仕事の意義を理解してもらうことを怠ると 最終的に新しい技術への新陳代謝ができない組織になり、成長の可能性を閉ざしてしまう 一線級のエンジニアが現役のまま経営も兼ねている組織でもない限りは このような説明責任も担えるエンジニアが重宝されるのではないだろうか? 68
さいごに 69
泥臭い作業 この発表で紹介したことは、いわゆる 作戦がきれいにハマった 箇所にすぎない 環境変数の使われかたを正す config の場当たり的な書き方を正す 修正が必要そうな箇所の洗い出し(勘と経験と気合で) 結局、ホコリかぶっていた負債を全部見て回って全部直すパワープレイが必要 飽きずに長く運用やって全体把握できる人間じゃないと
たぶん無理 70
ありがとうございました 71