Slide 1

Slide 1 text

@hanhan1978 Laravel を低速化する技術 PHP Conference 2022

Slide 2

Slide 2 text

@hanhan1978 ● 名前 富所 亮 ● ブログ https://blog.hanhans.net ● Yokohama North AM https://anchor.fm/yokohama-north-am ● Youtube https://www.youtube.com/user/hanhans1978 2

Slide 3

Slide 3 text

Laravel は遅くて有名なのか? 3

Slide 4

Slide 4 text

4 どうも、遅いという評判はありそう

Slide 5

Slide 5 text

仕事上でも聞いたことがある... - WAF は遅い - 生 PHP が一番速い - ORM は悪 5

Slide 6

Slide 6 text

Laravel は、なぜ採用される? - Webアプリに必要な一通りの機能 - 人気ゆえの情報量 - Rapid Application Development 6

Slide 7

Slide 7 text

Laravel は、なぜ採用される? - Webアプリに必要な一通りの機能 - 人気ゆえの情報量 - Rapid Application Development 7

Slide 8

Slide 8 text

(特に)新規開発 - 設定より規約 - ORM - Migration, Worker, Jobキュー 8

Slide 9

Slide 9 text

(特に)新規開発 - 設定より規約 - ORM - Migration, Worker, Jobキュー 9 仕様が次々に変化していく フェーズでは助かる

Slide 10

Slide 10 text

モノゴトにはトレードオフがある 10

Slide 11

Slide 11 text

開発速度が速いなら 動作は遅くてもいい? 11

Slide 12

Slide 12 text

遅いとは? 12

Slide 13

Slide 13 text

13 「遅い」は相対的な評価 https://speakerdeck.com/hanhan1978/web-application-tuning-guildline?slide=16

Slide 14

Slide 14 text

今回の発表における基準 - Webサイトのレスポンスタイム - 200 msec を超えたら「遅い」 14

Slide 15

Slide 15 text

● サンプルウェブアプリケーション ● インフラ視点での低速化 ● アプリケーション視点での低速化 ● まとめ 目次 15

Slide 16

Slide 16 text

● サンプルウェブアプリケーション ● インフラ視点での低速化 ● アプリケーション視点での低速化 ● まとめ 目次 16

Slide 17

Slide 17 text

17 某短文サイト風サンプル

Slide 18

Slide 18 text

テーブル定義書 18

Slide 19

Slide 19 text

データ量 19 10,000 1,000 250,000 50,000

Slide 20

Slide 20 text

マニュアルに忠実なソースコード 20

Slide 21

Slide 21 text

マニュアルに忠実なソースコード 21 名前からユーザーレコードを取得

Slide 22

Slide 22 text

マニュアルに忠実なソースコード 22 フォロワーを取得

Slide 23

Slide 23 text

マニュアルに忠実なソースコード 23 タイムラインに表示する投稿を取得

Slide 24

Slide 24 text

24 初期状態のパフォーマンス

Slide 25

Slide 25 text

25 初期状態のパフォーマンス マニュアル通りの作り方 -> 十分速くなってしまう....

Slide 26

Slide 26 text

速いのはローカル環境でしょ? 26 M2 Mac 24GB メモリだろ?

Slide 27

Slide 27 text

27 残念! EC2 でした!

Slide 28

Slide 28 text

EC2 + RDS - 運用費概算 1万円以内 - 十分な速度がでる - さすが RAD 28 他社 VPS などなら 3000円以内 も夢ではない....

Slide 29

Slide 29 text

もっと遅くせねば! 29

Slide 30

Slide 30 text

高速化の指標 - AWS に siege とかするのはNG - ブラウザリクエスト で確認 - 初期状態 149ms 30

Slide 31

Slide 31 text

● サンプルウェブアプリケーション ● インフラ視点での低速化 ● アプリケーション視点での低速化 ● まとめ 目次 31

Slide 32

Slide 32 text

【作戦1】Preload 無効化 32

Slide 33

Slide 33 text

33 7.4 から追加された機能 https://speakerdeck.com/hanhan1978/preload-and-jit?slide=41

Slide 34

Slide 34 text

34 詳しくは https://speakerdeck.com/hanhan1978/preload-and-jit

Slide 35

Slide 35 text

結果 35

Slide 36

Slide 36 text

【作戦1】Preload 無効化の結果 - 効果無し - 初期状態とほぼ変化なし 145 〜 150ms 36

Slide 37

Slide 37 text

【作戦1】Preload 無効化の結果 - 効果無し - 初期状態とほぼ変化なし 145 〜 150ms 37 CPUバウンドじゃない

Slide 38

Slide 38 text

【作戦2】JIT 無効化 38

Slide 39

Slide 39 text

39 8.0 から追加された機能 https://speakerdeck.com/hanhan1978/preload-and-jit?slide=66

Slide 40

Slide 40 text

40 詳しくは https://speakerdeck.com/hanhan1978/preload-and-jit

Slide 41

Slide 41 text

結果 41

Slide 42

Slide 42 text

【作戦2】Preload 無効化 - 効果無し - 初期状態とほぼ変化なし 140 〜 150ms 42

Slide 43

Slide 43 text

【作戦2】Preload 無効化 - 効果無し - 初期状態とほぼ変化なし 140 〜 150ms 43 CPUバウンドじゃない!!!

Slide 44

Slide 44 text

【作戦3】OPCache 無効化 44

Slide 45

Slide 45 text

45 5.5 から同梱された機能 https://speakerdeck.com/hanhan1978/preload-and-jit?slide=10

Slide 46

Slide 46 text

46 詳しくは https://speakerdeck.com/hanhan1978/preload-and-jit

Slide 47

Slide 47 text

結果 47

Slide 48

Slide 48 text

【作戦3】OPCache 無効化 - 効果は抜群 - 倍程度の性能劣化 250 〜 350ms 48

Slide 49

Slide 49 text

【作戦3】OPCache 無効化 - 効果抜群 - 倍程度の性能劣化 250 〜 350ms 49 手軽に +100〜200ms

Slide 50

Slide 50 text

【作戦4】Xdebug 有効化 50

Slide 51

Slide 51 text

Xdebugとは.... - 開発用のデバッグツール - ステップ実行したり - カバレッジ出したり 51

Slide 52

Slide 52 text

52 詳しくは https://speakerdeck.com/o0h/hello-xdebug

Slide 53

Slide 53 text

結果 53

Slide 54

Slide 54 text

【作戦4】Xdebug 有効化 - 効果抜群 - さらに性能劣化 350 〜 450ms 54

Slide 55

Slide 55 text

【作戦4】Xdebug 有効化 - 効果抜群 - さらに性能劣化 350 〜 450ms 55 何回か、本番で有効になってい るのを見た....

Slide 56

Slide 56 text

おまけ - ばれないように Region を 北米にするとか - RDSだけ ヨーロッパにするとか - アイデアは色々 56

Slide 57

Slide 57 text

おまけ - ばれないように Region を 北米にするとか - RDSだけ ヨーロッパにするとか - アイデアは色々 57 みんなも工夫してね!

Slide 58

Slide 58 text

58 大陸移動はコストがかかる https://speakerdeck.com/hanhan1978/web-application-tuning-guildline?slide=37

Slide 59

Slide 59 text

手軽なインフラ低速化はここまで 59

Slide 60

Slide 60 text

ここまでのまとめ - 500 msec 近くまでは到達 - もっと、目に見えて遅くしたい! 60

Slide 61

Slide 61 text

● サンプルウェブアプリケーション ● インフラ視点での低速化 ● アプリケーション視点での低速化 ● まとめ 目次 61

Slide 62

Slide 62 text

【作戦5】Eager Loading 廃止 62

Slide 63

Slide 63 text

63 Eager Loading とは? https://laravel.com/docs/9.x/eloquent-relationships#eager-loading

Slide 64

Slide 64 text

64 Eager Loading とは? https://laravel.com/docs/9.x/eloquent-relationships#eager-loading N+1問題を解決してくれる

Slide 65

Slide 65 text

65 例えば https://laravel.com/docs/9.x/eloquent-relationships#eager-loading

Slide 66

Slide 66 text

66 例えば https://laravel.com/docs/9.x/eloquent-relationships#eager-loading Loopの1回ごとにSQL発行

Slide 67

Slide 67 text

67 With https://laravel.com/docs/9.x/eloquent-relationships#eager-loading 予めクエリをまとめて発行

Slide 68

Slide 68 text

結果 68

Slide 69

Slide 69 text

【作戦5】Eager Loading 廃止 - 費用対効果が高い(withを削除するだけ) - さらに性能劣化 1.02 〜 1.2s 69

Slide 70

Slide 70 text

【作戦5】Eager Loading 廃止 - 費用対効果が高い(withを削除するだけ) - さらに性能劣化 1.02 〜 1.2s 70 さらに倍!

Slide 71

Slide 71 text

【作戦6】Limit句 廃止 71

Slide 72

Slide 72 text

72 禁断の全件取得 https://laravel.com/docs/9.x/eloquent-relationships#eager-loading

Slide 73

Slide 73 text

73 禁断の全件取得 https://laravel.com/docs/9.x/eloquent-relationships#eager-loading 5万件ゲット

Slide 74

Slide 74 text

結果 74

Slide 75

Slide 75 text

【作戦6】Limit 句 廃止 - 会心の一撃 - さらに性能劣化 3.0 〜 3.5s 75

Slide 76

Slide 76 text

【作戦6】Limit 句 廃止 - 会心の一撃 - さらに性能劣化 3.0 〜 3.5s 76 MySQL は頑張ってる

Slide 77

Slide 77 text

【作戦7】Attribute Casting の悪用 77

Slide 78

Slide 78 text

Attribute Casting とは? - Eloquent Model が property アクセスする際に発火 - DBのカラムに合わせて、property を型変換 78

Slide 79

Slide 79 text

79 公式マニュアル https://laravel.com/docs/9.x/eloquent-mutators#attribute-casting

Slide 80

Slide 80 text

80 一見なんともないコード

Slide 81

Slide 81 text

81 一見なんともないコード 裏で Carbon のインスタンス生 成が発火している

Slide 82

Slide 82 text

結果 82

Slide 83

Slide 83 text

【作戦7】Attribute Casting 悪用 - 会心の一撃 part 2 - さらに性能劣化 6.0 〜 6.5 s 83

Slide 84

Slide 84 text

【作戦7】Attribute Casting 悪用 - 会心の一撃 part 2 - さらに性能劣化 6.0 〜 6.5 s 84 見た目の素朴さが Good !!

Slide 85

Slide 85 text

● サンプルウェブアプリケーション ● インフラ視点での低速化 ● アプリケーション視点での低速化 ● まとめ 目次 85

Slide 86

Slide 86 text

インフラ・初期設定は確認! - OPCache ON 超大事 - Xdebug OFF 超大事 86 実在しましたからね...

Slide 87

Slide 87 text

Laravel はそれほど遅くない - ある程度のデータ量に耐える機能がある - 公式ドキュメントにちゃんと書いてある 87

Slide 88

Slide 88 text

Laravel の注意点 - 便利機能は一歩間違えると痛恨の一撃 - 何でもなさそうなコードが問題を起こす 88

Slide 89

Slide 89 text

最後に - RAD フレームワークは、ちゃんとテストを書くこと! - コントローラー単位でメソッドは短く! - 変なことしても気づきやすいように! 89

Slide 90

Slide 90 text

おまけコンテンツ 90

Slide 91

Slide 91 text

適切なチューニングをした場合 91

Slide 92

Slide 92 text

設定 - OPCache ON - OPCache JIT ON - OPCache Preload 使用 92

Slide 93

Slide 93 text

アプリケーション側 - ユーザーデータキャッシュ - お気に入り件数キャッシュ - 投稿記事検索結果キャッシュ 93 一切の DB 接続をAPCuでしのぐ

Slide 94

Slide 94 text

94 DB 接続をしない場合のレスポンス ほぼ、静的ページ

Slide 95

Slide 95 text

おまけコンテンツ2 95

Slide 96

Slide 96 text

N+1 が混入することを防ぐには? - 教育 - Laravel Debug Bar - N+1 detecter 96

Slide 97

Slide 97 text

97 Laravel Debug Bar https://github.com/barryvdh/laravel-debugbar 10越えたらチェック

Slide 98

Slide 98 text

インフラ周りのチェックどうする? - パターンは多くない - チェックリストを作っておくとよい - 特に OPCache は入れ忘れが多いので注意 98

Slide 99

Slide 99 text

99 php -m でチェック デフォルトでは入ってない

Slide 100

Slide 100 text

パフォーマンスの劣化にはどう気づく - 継続監視 - New Relic, Datadog - curl 使って Slack 通知とかでも気づける - データ量に注意 100

Slide 101

Slide 101 text

101 性能劣化はデータ量に比例 https://www.techscore.com/blog/2016/08/08/開発新卒に捧ぐ、基本のアルゴリズムと計算量 /

Slide 102

Slide 102 text

102 教育

Slide 103

Slide 103 text

@hanhan1978 相談・指摘・その他  下記のTwitterアカウントにどうぞ 103