Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
© 2022 New Relic, Inc. All rights reserved 推測するな、計測せよ New Relic × Laravel 実践 Yuzuru Ohira & mpyw PHPerKaigi 2023 Day1 (発表時の内容に加筆修正済み)
Slide 2
Slide 2 text
© 2022 New Relic, Inc. All rights reserved 自己紹介 Joe 氏とは以前の職場での知り合い。 最近 PHP を書く機会が激減して少し寂しくなっている… @mpyw PHPerKaigi 初登壇です!
Slide 3
Slide 3 text
パクツイ 登壇しろという圧を感じていたところに 都合よく依頼が飛んできたので便乗
Slide 4
Slide 4 text
© 2022 New Relic, Inc. All rights reserved New Relic の 導入と実演
Slide 5
Slide 5 text
© 2022 New Relic, Inc. All rights reserved New Relic の導入と実演 Ⅰ 題材とする Laravel アプリの簡単な紹介 Ⅱ New Relic Agent を Laravel アプリに導入 Ⅲ New Relic APM の基本的な仕組み Ⅳ New Relic を使った Laravel アプリの改善
Slide 6
Slide 6 text
© 2022 New Relic, Inc. All rights reserved. 題材とする Laravel アプリの簡単な紹介 ● 総務省が提供する Excel 統計データを整形して使用 ● 項目 ○ 全人口, 男性人口, 女性人口, 人口密度, 若年層人口, 高齢者人口, etc… ○ 計 27 項目 ● 自治体 ○ Prefectures (都道府県 + 全国): 48 ○ Cities (市町村 + 東京23区): 1742 ○ Districts (区): 175 大量の人口統計を表示・編集するアプリ 27 × (48+1742+175) = 53055 個
Slide 7
Slide 7 text
© 2022 New Relic, Inc. All rights reserved. 題材とする Laravel アプリの簡単な紹介 バックエンドのテーブル構成
Slide 8
Slide 8 text
© 2022 New Relic, Inc. All rights reserved. クリックすると 展開表示 遅延表示しているだけ 遅延取得はしていない これらを一気に表示・送信する巨大フォーム
Slide 9
Slide 9 text
© 2022 New Relic, Inc. All rights reserved. 題材とする Laravel アプリの簡単な紹介 ● (読込)Eager Loading, Lazy Loading の切り替え ● (更新)Validator の切り替え (デモの都合上)バックエンドの動作を切り替える機能を搭載
Slide 10
Slide 10 text
© 2022 New Relic, Inc. All rights reserved New Relic の導入と実演 Ⅰ 題材とする Laravel アプリの簡単な紹介 Ⅱ New Relic Agent を Laravel アプリに導入 Ⅲ New Relic APM の基本的な仕組み Ⅳ New Relic を使った Laravel アプリの改善
Slide 11
Slide 11 text
© 2022 New Relic, Inc. All rights reserved. New Relic Agent を Laravel アプリに導入 ● ガイドインストール機能! (初心者はとりあえずこれで) ● PHPer の方はだいたい APM → PHP → Docker を 選んでおけばいいと思います ● 時間の都合上ポチポチする部分は省略 具体的な導入手順 https://github.com/mpyw-yattemita/phperkaigi2023-laravel-newrelic-performance 少しアレンジして整備した見本 ↓
Slide 12
Slide 12 text
© 2022 New Relic, Inc. All rights reserved. New Relic Agent を Laravel アプリに導入 ● PHP Agent ○ PHP Extension として関数の 呼び出しなどをトラッキング ○ フレームワークごとの特殊対応も ● PHP Daemon ○ PHP Agent が収集したデータを New Relic に転送する ● Infrastructure ○ リソースの使用状況などを New Relic に転送する ○ 直インストールまたは 特権を付与されたコンテナ 一般的なコンテナ構成 (今回は Kubernetes を使っているため若干異なります )
Slide 13
Slide 13 text
© 2022 New Relic, Inc. All rights reserved New Relic の導入と実演 Ⅰ 題材とする Laravel アプリの簡単な紹介 Ⅱ New Relic Agent を Laravel アプリに導入 Ⅲ New Relic APM の基本的な仕組み Ⅳ New Relic を使った Laravel アプリの改善
Slide 14
Slide 14 text
© 2022 New Relic, Inc. All rights reserved. New Relic APM の基本的な仕組み ● APM ○ バックエンドアプリのパフォーマンス分析 ○ 1 回のリクエストのトレースなどを トランザクションという単位で計測 ○ PHP Extension ゆえに自動記録可能! ● Distributed Tracing ○ ある 1 回のトランザクションの間に, マイクロサービス間で発生したやり取りを すべて連結して記録できる ○ フロントエンドの Web ブラウザ上での 動きも含めて記録できる ○ APM で異常検知されなかった (サンプリングされた)正常系も確認できる New Relic の主要機能 ● Logs ○ JSONL 形式でのログの記録と検索 ○ Logs in Context という機能を使うと トランザクションに紐付けできる ○ PHP Extension ゆえに自動紐付け可能! ● Infrastructure ○ CPU やメモリなどのリソースの 使用状況を監視できる ● Synthetic Monitoring ○ HTTP リクエストを定期的に 飛ばして死活監視
Slide 15
Slide 15 text
© 2022 New Relic, Inc. All rights reserved. AWS Fargate では 大幅性能劣化 ( CPU クロックの相性が悪い ) 8.2 ( 収録時まで 8.1 でしたが, 完了後に対応されました 🎉) 8.x (公式サポートはされていないが概 ね 9.x, 10.x でも動きそう) 自動記録の制約 対応 PHP バージョン 対応 Laravel バージョン PHP × New Relic は自動記録できて便利 …だが? ちょっと惜しいポイントが … EC2 ベースの ECS/EKS を使う💡 手動記録する 🥺 自動記録の対象関数を限定 💡 ← newrelic.transaction_tracer.detail = 0 ← newrelic.transaction_tracer.custom = Foo::x,Bar::y ← Fargate よりはマシというだけで,依然として多少のオーバーヘッドはある IO 遅延がメインの PHP アプリケーションの場合は無視できる程度
Slide 16
Slide 16 text
© 2022 New Relic, Inc. All rights reserved. New Relic APM の基本的な仕組み ● バックエンドからの JavaScript スクリプト注入 ○ PHP Agent が HTML を返却する際, PHP 標準機能にある output_handler を 使って注入している ○ Extension をインストールしていれば 自動的に New Relic の Output Handler が 登録される ● フロントエンドから New Relic に直接通信 ○ デベロッパーツールで通信している 様子を確認できる (参考) Distributed Tracing がフロントエンドを監視する仕組み
Slide 17
Slide 17 text
© 2022 New Relic, Inc. All rights reserved. New Relic APM の実際の画面を確認 時間のかかったトランザクション Laravel デフォルトでは コントローラ名@メソッド がタイトル
Slide 18
Slide 18 text
© 2022 New Relic, Inc. All rights reserved. New Relic APM の実際の画面を確認 時間のかかった SQL ・ テーブル名と操作の種類 ・ どのトランザクションから呼び出されているか ・ (スロークエリ判定された場合)具体的なクエリの内容
Slide 19
Slide 19 text
© 2022 New Relic, Inc. All rights reserved New Relic の導入と実演 Ⅰ 題材とする Laravel アプリの簡単な紹介 Ⅱ New Relic Agent を Laravel アプリに導入 Ⅲ New Relic APM の基本的な仕組み Ⅳ New Relic を使った Laravel アプリの改善
Slide 20
Slide 20 text
© 2022 New Relic, Inc. All rights reserved 大量レコードの 読み込み
Slide 21
Slide 21 text
© 2022 New Relic, Inc. All rights reserved. New Relic を使った Laravel アプリの改善 バックエンドのテーブル構成(再掲) 大量レコードの読み込み
Slide 22
Slide 22 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの読み込み Eloquent Model のリレーションシップ定義
Slide 23
Slide 23 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの読み込み Eloquent Model のカスタム属性定義 親に依存 祖先に依存
Slide 24
Slide 24 text
© 2022 New Relic, Inc. All rights reserved. ● 子要素の Eager Loading 設定の分岐 ○ Eager Loading なし ○ Cities のみ Eager Loading ○ Cities, Districts ともに Eager Loading ● 親要素の Eager Loading 設定の分岐 ○ Eager Loading なし ○ City, Prefecture ともに Eager Loading 大量レコードの読み込み コントローラ
Slide 25
Slide 25 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの読み込み HTTP Resource の toArray() の実装 ● 子要素の Lazy Loading 設定の分岐 ○ Lazy Loading しない ○ Cities のみ Lazy Loading ○ Cities, Districts ともに Lazy Loading whenLoaded() は Eager Loading されている場合のみ表示する機能
Slide 26
Slide 26 text
© 2022 New Relic, Inc. All rights reserved. 実演タイム (時間が無ければカット)
Slide 27
Slide 27 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの読み込み Cities, Districts を Lazy Load した場合の結果 (APM) N+1 がとんでもないことに! Prefecture City City District District
Slide 28
Slide 28 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの読み込み Cities, Districts を Eager Load した場合の結果 (APM) 親に依存している疑似属性での Lazy Loading がボトルネックに Prefecture City City District District
Slide 29
Slide 29 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの読み込み Cities, Districts を Eager Load した場合の結果 (Distributed Tracing) リソース → レスポンスの変換で 時間がかかっているのが分かる
Slide 30
Slide 30 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの読み込み Cities, Districts, Parent を Eager Load した場合の結果 (APM) Prefecture City City District District
Slide 31
Slide 31 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの読み込み 実際のところは… ループ処理中での Lazy Loading を 検知して例外をスローしてくれる
Slide 32
Slide 32 text
© 2022 New Relic, Inc. All rights reserved 大量レコードの更新
Slide 33
Slide 33 text
© 2022 New Relic, Inc. All rights reserved. New Relic を使った Laravel アプリの改善 仕様のおさらい ● フロントエンドから 27 種類のフィールドが自治体の数だけあり, 合計 50000 以上のフィールドが送られる ● 受け取った JSON を編集してそのまま送り返している ↓ prefectures, cities, districts がネストしている 大量レコードの更新
Slide 34
Slide 34 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの更新 種類ごとに 1000 件溜まったらバルクアップデートするコード UPDATE SET x = ELT(FIELD(id, 1, 2, 3, …), ‘a’, ‘b’, ‘c’, …) WHERE id IN (1, 2, 3, …)
Slide 35
Slide 35 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの更新 バリデーションルールの定義(省略あり) ワイルドカードでネストした配列の 子要素を指定する機能がある ● CPU 演算で完結するシンプルなルール群 ● データベースアクセスしないルールのみ
Slide 36
Slide 36 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの更新 バリデーションルールの定義(省略なし)
Slide 37
Slide 37 text
© 2022 New Relic, Inc. All rights reserved. 実演タイム (時間が無ければカット)
Slide 38
Slide 38 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードの更新 ネストした Cities, Districts を Laravel の通常の Validator で更新した場合の結果 (APM) Validator のワイルドカードルール関連が激重 タイムアウトして データベースにアクセスするところまで たどり着いていない…
Slide 39
Slide 39 text
© 2022 New Relic, Inc. All rights reserved. なんでそんなに重いの?
Slide 40
Slide 40 text
© 2022 New Relic, Inc. All rights reserved. New Relic を使った Laravel アプリの改善 Laravel の Validator が重い理由 大量レコードの更新 送られてくるデータは 立体構造やな
Slide 41
Slide 41 text
© 2022 New Relic, Inc. All rights reserved. New Relic を使った Laravel アプリの改善 Laravel の Validator が重い理由 大量レコードの更新 でもルールは 宣言的にこう書きたい
Slide 42
Slide 42 text
© 2022 New Relic, Inc. All rights reserved. New Relic を使った Laravel アプリの改善 Laravel の Validator が重い理由 大量レコードの更新 データ側をいったん フラットしにしてみよう
Slide 43
Slide 43 text
© 2022 New Relic, Inc. All rights reserved. New Relic を使った Laravel アプリの改善 Laravel の Validator が重い理由 大量レコードの更新 完全フラットやと途中階層の バリデーションが出来ひんな
Slide 44
Slide 44 text
© 2022 New Relic, Inc. All rights reserved. New Relic を使った Laravel アプリの改善 Laravel の Validator が重い理由 大量レコードの更新 ルールに対応するところは 途中階層の配列も用意せな
Slide 45
Slide 45 text
© 2022 New Relic, Inc. All rights reserved. New Relic を使った Laravel アプリの改善 Laravel の Validator が重い理由 大量レコードの更新 ヨシッ! あとはルール側の * をデー タの分だけ 複製すればいいわ!
Slide 46
Slide 46 text
© 2022 New Relic, Inc. All rights reserved. New Relic を使った Laravel アプリの改善 Laravel の Validator が重い理由 大量レコードの更新 できた!
Slide 47
Slide 47 text
© 2022 New Relic, Inc. All rights reserved. 変換されたルール 変換されたデータ ルールとデータが1対1対応! シンプルになった✌ 今からループ回すで!
Slide 48
Slide 48 text
© 2022 New Relic, Inc. All rights reserved. 変換されたルール 変換されたデータ ルールとデータが1対1対応! シンプルになった✌ 今からループ回すで! そりゃ重いやろ
Slide 49
Slide 49 text
© 2022 New Relic, Inc. All rights reserved. New Relic を使った Laravel アプリの改善 Validator が重すぎるのでなんとかする ● Laravel の Validator を使わずに自分で何とかする ○ 理論上最速だがやや書くのが大変 ● 「ワイルドカード → 配列インデックス」の置換処理を Laravel に任せずに自前でやる ○ 効果あるか怪しいが …簡単! 大量レコードの 更新 バリデーション
Slide 50
Slide 50 text
© 2022 New Relic, Inc. All rights reserved. すべて自前で書く場合
Slide 51
Slide 51 text
© 2022 New Relic, Inc. All rights reserved. すべて自前で書く場合
Slide 52
Slide 52 text
© 2022 New Relic, Inc. All rights reserved. すべて自前で書く場合
Slide 53
Slide 53 text
© 2022 New Relic, Inc. All rights reserved. ワイルドカード→配列インデックスの置換処理だけ自前で書く場合 $i, $j, $k, … かんたん ♫
Slide 54
Slide 54 text
© 2022 New Relic, Inc. All rights reserved. 実演タイム (時間が無ければカット)
Slide 55
Slide 55 text
© 2022 New Relic, Inc. All rights reserved. タイムアウト 1秒 NewRelic なし: 8〜15秒 New Relic あり: 15〜30秒 Laravel Validator Pure PHP Validator Wildcard-less Laravel Validator 大量レコードのバリデーション ネストした Cities, Districts をバリデーションした場合 … とっさの改修には 意外と耐えられるかも!
Slide 56
Slide 56 text
© 2022 New Relic, Inc. All rights reserved. (参考) Laravel 8.x までと Laravel 9.x からの違い Validator::$excludeUnvalidatedArrayKeys array 要素からバリデーション対象外のキーを排除 ● Laravel 8.x まで false がデフォルト ● Laravel 9.x から true がデフォルト 実行時間が 2倍ぐらいに
Slide 57
Slide 57 text
© 2022 New Relic, Inc. All rights reserved. 大量レコードのバリデーション 実際のところは… ● ワイルドカードルールがネストしまくりのフォーム設計は可能な限りやめましょう ● どうしても避けられないときは … ○ 要素数を Laravel のバリデータを使わずに 現実的な数までに制限しましょう ○ 制限してもなお無視できない量がある場合は,ワイルドカードルールに代わる 解決策を考えましょう
Slide 58
Slide 58 text
© 2022 New Relic, Inc. All rights reserved まとめ
Slide 59
Slide 59 text
© 2022 New Relic, Inc. All rights reserved. まとめ ● New Relic には便利な機能がいっぱい! ○ APM, Distributed Tracing, Logs in Context には特にお世話になることが多そう ● 推測するな,計測せよ ○ PHP でも IO がボトルネックとは限らない ○ 有名 OSS の中にも恐ろしく非効率なコードが紛れていることがある
Slide 60
Slide 60 text
© 2022 New Relic, Inc. All rights reserved 1ユーザー &月間100GB の転送量までなら無料 https://newrelic.com/signup
Slide 61
Slide 61 text
© 2022 New Relic, Inc. All rights reserved Full-Stack Observability テスト開講❗❗ https://learn.newrelic.com/full-stack-observability-exam-jp