低速化を学ぶことで、高速化を学ぶ
@hanhan1978Laravel を低速化する技術PHP Conference 2022
View Slide
@hanhan1978● 名前富所 亮● ブログhttps://blog.hanhans.net● Yokohama North AMhttps://anchor.fm/yokohama-north-am● Youtubehttps://www.youtube.com/user/hanhans19782
Laravel は遅くて有名なのか?3
4どうも、遅いという評判はありそう
仕事上でも聞いたことがある...- WAF は遅い- 生 PHP が一番速い- ORM は悪5
Laravel は、なぜ採用される?- Webアプリに必要な一通りの機能- 人気ゆえの情報量- Rapid Application Development6
Laravel は、なぜ採用される?- Webアプリに必要な一通りの機能- 人気ゆえの情報量- Rapid Application Development7
(特に)新規開発- 設定より規約- ORM- Migration, Worker, Jobキュー8
(特に)新規開発- 設定より規約- ORM- Migration, Worker, Jobキュー9仕様が次々に変化していくフェーズでは助かる
モノゴトにはトレードオフがある10
開発速度が速いなら動作は遅くてもいい?11
遅いとは?12
13「遅い」は相対的な評価https://speakerdeck.com/hanhan1978/web-application-tuning-guildline?slide=16
今回の発表における基準- Webサイトのレスポンスタイム- 200 msec を超えたら「遅い」14
● サンプルウェブアプリケーション● インフラ視点での低速化● アプリケーション視点での低速化● まとめ目次15
● サンプルウェブアプリケーション● インフラ視点での低速化● アプリケーション視点での低速化● まとめ目次16
17某短文サイト風サンプル
テーブル定義書18
データ量1910,000 1,000250,00050,000
マニュアルに忠実なソースコード20
マニュアルに忠実なソースコード21名前からユーザーレコードを取得
マニュアルに忠実なソースコード22フォロワーを取得
マニュアルに忠実なソースコード23タイムラインに表示する投稿を取得
24初期状態のパフォーマンス
25初期状態のパフォーマンスマニュアル通りの作り方-> 十分速くなってしまう....
速いのはローカル環境でしょ?26M2 Mac 24GB メモリだろ?
27残念! EC2 でした!
EC2 + RDS- 運用費概算 1万円以内- 十分な速度がでる- さすが RAD28他社 VPS などなら 3000円以内も夢ではない....
もっと遅くせねば!29
高速化の指標- AWS に siege とかするのはNG- ブラウザリクエスト で確認- 初期状態 149ms30
● サンプルウェブアプリケーション● インフラ視点での低速化● アプリケーション視点での低速化● まとめ目次31
【作戦1】Preload 無効化32
337.4 から追加された機能https://speakerdeck.com/hanhan1978/preload-and-jit?slide=41
34詳しくはhttps://speakerdeck.com/hanhan1978/preload-and-jit
結果35
【作戦1】Preload 無効化の結果- 効果無し- 初期状態とほぼ変化なし 145 〜 150ms36
【作戦1】Preload 無効化の結果- 効果無し- 初期状態とほぼ変化なし 145 〜 150ms37CPUバウンドじゃない
【作戦2】JIT 無効化38
398.0 から追加された機能https://speakerdeck.com/hanhan1978/preload-and-jit?slide=66
40詳しくはhttps://speakerdeck.com/hanhan1978/preload-and-jit
結果41
【作戦2】Preload 無効化- 効果無し- 初期状態とほぼ変化なし 140 〜 150ms42
【作戦2】Preload 無効化- 効果無し- 初期状態とほぼ変化なし 140 〜 150ms43CPUバウンドじゃない!!!
【作戦3】OPCache 無効化44
455.5 から同梱された機能https://speakerdeck.com/hanhan1978/preload-and-jit?slide=10
46詳しくはhttps://speakerdeck.com/hanhan1978/preload-and-jit
結果47
【作戦3】OPCache 無効化- 効果は抜群- 倍程度の性能劣化 250 〜 350ms48
【作戦3】OPCache 無効化- 効果抜群- 倍程度の性能劣化 250 〜 350ms49手軽に +100〜200ms
【作戦4】Xdebug 有効化50
Xdebugとは....- 開発用のデバッグツール- ステップ実行したり- カバレッジ出したり51
52詳しくはhttps://speakerdeck.com/o0h/hello-xdebug
結果53
【作戦4】Xdebug 有効化- 効果抜群- さらに性能劣化 350 〜 450ms54
【作戦4】Xdebug 有効化- 効果抜群- さらに性能劣化 350 〜 450ms55何回か、本番で有効になっているのを見た....
おまけ- ばれないように Region を 北米にするとか- RDSだけ ヨーロッパにするとか- アイデアは色々56
おまけ- ばれないように Region を 北米にするとか- RDSだけ ヨーロッパにするとか- アイデアは色々57みんなも工夫してね!
58大陸移動はコストがかかるhttps://speakerdeck.com/hanhan1978/web-application-tuning-guildline?slide=37
手軽なインフラ低速化はここまで59
ここまでのまとめ- 500 msec 近くまでは到達- もっと、目に見えて遅くしたい!60
● サンプルウェブアプリケーション● インフラ視点での低速化● アプリケーション視点での低速化● まとめ目次61
【作戦5】Eager Loading 廃止62
63Eager Loading とは?https://laravel.com/docs/9.x/eloquent-relationships#eager-loading
64Eager Loading とは?https://laravel.com/docs/9.x/eloquent-relationships#eager-loadingN+1問題を解決してくれる
65例えばhttps://laravel.com/docs/9.x/eloquent-relationships#eager-loading
66例えばhttps://laravel.com/docs/9.x/eloquent-relationships#eager-loadingLoopの1回ごとにSQL発行
67Withhttps://laravel.com/docs/9.x/eloquent-relationships#eager-loading予めクエリをまとめて発行
結果68
【作戦5】Eager Loading 廃止- 費用対効果が高い(withを削除するだけ)- さらに性能劣化 1.02 〜 1.2s69
【作戦5】Eager Loading 廃止- 費用対効果が高い(withを削除するだけ)- さらに性能劣化 1.02 〜 1.2s70さらに倍!
【作戦6】Limit句 廃止71
72禁断の全件取得https://laravel.com/docs/9.x/eloquent-relationships#eager-loading
73禁断の全件取得https://laravel.com/docs/9.x/eloquent-relationships#eager-loading5万件ゲット
結果74
【作戦6】Limit 句 廃止- 会心の一撃- さらに性能劣化 3.0 〜 3.5s75
【作戦6】Limit 句 廃止- 会心の一撃- さらに性能劣化 3.0 〜 3.5s76MySQL は頑張ってる
【作戦7】Attribute Casting の悪用77
Attribute Casting とは?- Eloquent Model が property アクセスする際に発火- DBのカラムに合わせて、property を型変換78
79公式マニュアルhttps://laravel.com/docs/9.x/eloquent-mutators#attribute-casting
80一見なんともないコード
81一見なんともないコード裏で Carbon のインスタンス生成が発火している
結果82
【作戦7】Attribute Casting 悪用- 会心の一撃 part 2- さらに性能劣化 6.0 〜 6.5 s83
【作戦7】Attribute Casting 悪用- 会心の一撃 part 2- さらに性能劣化 6.0 〜 6.5 s84見た目の素朴さが Good !!
● サンプルウェブアプリケーション● インフラ視点での低速化● アプリケーション視点での低速化● まとめ目次85
インフラ・初期設定は確認!- OPCache ON 超大事- Xdebug OFF 超大事86実在しましたからね...
Laravel はそれほど遅くない- ある程度のデータ量に耐える機能がある- 公式ドキュメントにちゃんと書いてある87
Laravel の注意点- 便利機能は一歩間違えると痛恨の一撃- 何でもなさそうなコードが問題を起こす88
最後に- RAD フレームワークは、ちゃんとテストを書くこと!- コントローラー単位でメソッドは短く!- 変なことしても気づきやすいように!89
おまけコンテンツ90
適切なチューニングをした場合91
設定- OPCache ON- OPCache JIT ON- OPCache Preload 使用92
アプリケーション側- ユーザーデータキャッシュ- お気に入り件数キャッシュ- 投稿記事検索結果キャッシュ93一切の DB 接続をAPCuでしのぐ
94DB 接続をしない場合のレスポンスほぼ、静的ページ
おまけコンテンツ295
N+1 が混入することを防ぐには?- 教育- Laravel Debug Bar- N+1 detecter96
97Laravel Debug Barhttps://github.com/barryvdh/laravel-debugbar10越えたらチェック
インフラ周りのチェックどうする?- パターンは多くない- チェックリストを作っておくとよい- 特に OPCache は入れ忘れが多いので注意98
99php -m でチェックデフォルトでは入ってない
パフォーマンスの劣化にはどう気づく- 継続監視- New Relic, Datadog- curl 使って Slack 通知とかでも気づける- データ量に注意100
101性能劣化はデータ量に比例https://www.techscore.com/blog/2016/08/08/開発新卒に捧ぐ、基本のアルゴリズムと計算量/
102教育
@hanhan1978相談・指摘・その他 下記のTwitterアカウントにどうぞ103