Slide 1

Slide 1 text

サーバー基盤グループ PE チーム 工藤 剛 コロプラは なぜゲームアプリケーションで PHP を使い続けるのか

Slide 2

Slide 2 text

2 2017 年新卒として入社、運用タイトルのサーバーエンジニアを経て SRE チームを経て PE (Platform Engineering) チームへ 主にミドルウェアの更新対応やアプリケーションの保守性向上などに 取り組んでいる PHP おじさん 氏名  : 部署名 : 自己紹介 工藤 剛 技術基盤本部 第 3 バックエンドエンジニア部 サーバー基盤グループ PE チーム

Slide 3

Slide 3 text

コロプラにおけるサーバーサイド構成図 3 引用: 大規模ゲームインフラとしての Kubernetes とノーメンテナンス運用 https://speakerdeck.com/toversus/da-gui-mo-kemuinhuratositefalse-kubernetes-tofalsementenansuyun-yong

Slide 4

Slide 4 text

4 コロプラにおける Server たち ● API Server ○ ステートレスに行える処理 ■ プレイ開始・終了 ■ データの取得・生成・永続化 ○ を採用 ● Game (Real Time) Server ○ ステートフルな処理 ■ PvP, PvE におけるリレー通信 ■ Live Streaming における一対多・多対多通信 ○ を主に使用

Slide 5

Slide 5 text

なぜ Web 用の言語である PHP をゲームに使うのか? 5 よくある疑問

Slide 6

Slide 6 text

なぜ Web 用の言語である PHP をゲームに使うのか? スケールが容易でステートレスな サーバーサイド実装に最適な言語だから 6 よくある疑問

Slide 7

Slide 7 text

PHP は求められる要件をほとんど満たしている ● スクラップアンドビルドのサイクルを高速化できること ○ 高速なイテレーションこそが高品質な製品を産むという考え ● ステートレスであること ○ ステートを持たず、並列化することで容易にスケールアウトできること ● 負荷が予測可能であること ○ ガベージコレクションなどがほぼ発生せず、常に安定したパフォーマンスで 動作できること ● パフォーマンスが良いこと ○ 実行効率に優れ、莫大なリクエストを正しく処理できること ● 言語レベルの実装を理解できること ○ 何かあれば言語の実装を確認し、問題の原因追求ができること 7 コロプラで求められるアーキテクチャ

Slide 8

Slide 8 text

コードを書き換えて保存するだけで即時実行することができる コンパイラ型・トランスパイラ型の言語ではどうしても待ちが発生する (インタプリタ型でも機械語へのコンパイルは発生するが、オンデマンドなので待ち時間は短い) 8 スクラップアンドビルドの高速化 実 行 開 始 Java ☕ (bytecode)

Slide 9

Slide 9 text

とはいいつつも、現状に見合わない部分も... ● K8s 環境下では結局コンテナイメージのビルド待ちが発生する ● 他言語のコンパイルにかかる時間が大幅に高速化されてきている ○ AOT で直接バイナリコードを吐く言語 (Go 等) が優秀 ● opcache.validate_timestamps=0 環境下では単に書き換えるだけではダメ 正直なところ、開発サイクルの高速化というメリットは だいぶ弱くなってきている印象... 9 スクラップアンドビルドの高速化

Slide 10

Slide 10 text

Request1 End 一般的な SAPI*1 (apache2handler, fpm, cgi 等) ではリクエストごとにステートが破棄される 前回実行した結果に依存した処理は PHP だけでは原理的に実装できない*2 ため、 基本的に実装がステートレスになりスケーラビリティを担保しやすい 10 ステートレス性 Zend Engine + Extension Request1 Start Free Zend Engine + Extension Request1 Working Memory Free Request2 Start Zend Engine + Extension Free Request2 End Zend Engine + Extension Request2 Working Memory Free *1: Server Side API: PHP の実行形態 *2: Extension の導入や常駐化、サードパーティ SAPI などを行えば可能

Slide 11

Slide 11 text

負荷見積もりにおける理想の姿は "常に一定のスループットを維持" してくれる形 ただし、様々な理由からそのようなことにはならない ● API ごとのリソース特性の違い (I/O bound, CPU bound, etc…) ● キャッシュされていないデータへのアクセスによる待機時間 ● 実行環境のハードウェアに起因するスループットの変化 "詰まり" (スパイク) が発生すると負荷が一部に偏りユーザー体験に影響を 及ぼす恐れがあるため、ワーストケースに合わせてサービス影響が出ないような 構成を取る必要が生じる (≒ コスト増加) 11 負荷の予測可能性

Slide 12

Slide 12 text

Node.js アプリケーションにて GC (Full GC) でスパイクが発生している図 (縦軸はレイテンシ) 12 負荷の予測可能性

Slide 13

Slide 13 text

PHP は他言語に比べ、比較的負荷予測が容易 ● スパイク (詰まり) が起きにくい ○ "特定の状況下でのみ発生するパフォーマンス劣化" が原理的に起きにくい ■ パフォーマンスに大きな影響を与える循環参照 GC をほぼ考慮しなくて良い ■ "リクエストが詰まる" ようなことが少なく、 DB など特定のコンポーネントへ 突然負荷が集中する状況が起きにくい ● リクエストを受けてから実行までの時間にばらつきが少ない ○ 仮想マシンのフットプリントが小さく、リクエストを処理可能になるまでの時間が短い ● パフォーマンスチューニングが容易 ○ 負荷試験結果からある程度適切な割当リソース量を見積もりやすい 13 負荷の予測可能性

Slide 14

Slide 14 text

PHP はインタプリタの中でもかなりパフォーマンスの良い言語 Node.js (V8) には敵わないものの、 JIT を有効にすれば匹敵する性能 とはいえここまで CPU バウンドな処理は実際のワークロードにはほぼない 14 良好なパフォーマンス "一般的なコード" でテストするため 実装コードは ChatGPT (GPT-4) で生成 コードの手直しや最適化は一切なし 40 x 80 で 8192 回走査

Slide 15

Slide 15 text

OPcache 拡張機能を利用することで実行効率を大幅に向上可能 ● コードパス解析による最適化 ● OPcode コンパイル結果の共有メモリ (shm) へのキャッシュ ● 定数配列のメモリへのキャッシュ (PHP 7.0 以降) ○ 詳細は hnw さんの記事が詳しいです https://hnw.hatenablog.com/entry/2020/08/12/212433 ● preload (実行前事前ロード) (PHP 7.4 以降) ● Just-in-Time Compiler (PHP 8.0 以降) ○ 実際のワークロードで 10% 程度効率改善を確認 15 良好なパフォーマンス FPM PM OPcache shm worker worker worker script script

Slide 16

Slide 16 text

APCu 拡張を利用することで、 OPcache 同様 shm 領域を簡易的な KVS として 利用することができる 実際にマスタデータキャッシュ用途で利用しており パフォーマンスの改善とデータベースの負荷低減に役立っている store / fetch 時に serialize / unserialize コストがかかるので注意 16 良好なパフォーマンス FPM PM APCu shm worker worker worker DB

Slide 17

Slide 17 text

PHP 自体は C 言語で実装されており、乱雑とはしているが コードの雰囲気を読み取る程度は (HHVM 等に比べて) 比較的容易 ビルドツールチェーンやデバッグ関連機能も整備が行き届いており gdb や lldb を使ったデバッグや Valgrind, LLVM Sanitizer を使った メモリチェックなども快適で、良い意味で枯れている 17 言語実装の明瞭性

Slide 18

Slide 18 text

"何かあった時に自前でなんとかできる" 安心感が PHP にはある! サイボウズさんではパッチを当ててビルドした PHP を使用 (!) ● https://speakerdeck.com/akamah/20nian-mononoju-da-regasipurodakut owo-php-8-dot-0niatupudetositaji-nodui-ce-tode-raretazhi-jian コロプラでも PHP Extension を作成・保守しています (OSS) ● https://blog.colopl.dev/entry/2023/07/06/110000 ○ 奇しくもサイボウズさんとほぼ同じものを作っていました 18 言語実装の透明性

Slide 19

Slide 19 text

PHP はステートレスなサーバーサイド言語として未だ有望! もちろん解決したい問題がないわけではない ● より実行効率を追求したい ○ リクエスト単位での初期化を部分的にやめる (RoadRunner, Swoole, FrankenPHP,...) ● コンテナ環境での使い勝手を改善したい ○ 現状 HTTP サーバーが別途必要 ● もっと型安全にコードを書きたい ● etc... 次の PHP Innovator は君だ!!! 19 まとめ