Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Laravel を低速化する技術 / how to slow laravel

Ryo Tomidokoro
September 24, 2022

Laravel を低速化する技術 / how to slow laravel

低速化を学ぶことで、高速化を学ぶ

Ryo Tomidokoro

September 24, 2022
Tweet

More Decks by Ryo Tomidokoro

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  12. 遅いとは?
    12

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  18. テーブル定義書
    18

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  27. 27
    残念! EC2 でした!

    View Slide

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

    View Slide

  29. もっと遅くせねば!
    29

    View Slide

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

    View Slide

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

    View Slide

  32. 【作戦1】Preload 無効化
    32

    View Slide

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

    View Slide

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

    View Slide

  35. 結果
    35

    View Slide

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

    View Slide

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

    View Slide

  38. 【作戦2】JIT 無効化
    38

    View Slide

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

    View Slide

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

    View Slide

  41. 結果
    41

    View Slide

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

    View Slide

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

    View Slide

  44. 【作戦3】OPCache 無効化
    44

    View Slide

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

    View Slide

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

    View Slide

  47. 結果
    47

    View Slide

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

    View Slide

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

    View Slide

  50. 【作戦4】Xdebug 有効化
    50

    View Slide

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

    View Slide

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

    View Slide

  53. 結果
    53

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  62. 【作戦5】Eager Loading 廃止
    62

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  68. 結果
    68

    View Slide

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

    View Slide

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

    View Slide

  71. 【作戦6】Limit句 廃止
    71

    View Slide

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

    View Slide

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

    View Slide

  74. 結果
    74

    View Slide

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

    View Slide

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

    View Slide

  77. 【作戦7】Attribute Casting の悪用
    77

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  82. 結果
    82

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  90. おまけコンテンツ
    90

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  95. おまけコンテンツ2
    95

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  102. 102
    教育

    View Slide

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

    View Slide