俺の Laravel がこんなに速いわけがない! / My Laravel Too Fast
by
Ryo Tomidokoro
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
俺の Laravel がこんなに速い わけない! 2022-06-22 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 2
Slide 2 text
はじめに Laravel は遅くて有名? Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 3
Slide 3 text
Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 4
Slide 4 text
しかし、実際に簡易ブログを作ってみると... ※ 10000 レコードの中規模想定 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 5
Slide 5 text
Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 6
Slide 6 text
充分速い! これじゃ、評判と違う Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 7
Slide 7 text
低速化 Laravel の実装や実行環境を工夫して、 評判通りに遅くしよう! ※なるべく気づかれないように遅くする技術 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 8
Slide 8 text
アプリの仕様 シンプルなブログアプリ Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 9
Slide 9 text
Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 10
Slide 10 text
データ量 posts 10000 users 1000 post_posts 33864 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 11
Slide 11 text
以後の高速化の指標 siege -t 10s -c 50 -b localhost Transaction Rate (Req/Sec) の3回平均 初期状態は 195.84 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 12
Slide 12 text
1. preload 無効化 zend_extension=opcache.so ;opcache.preload=/var/www/src/preload.php ;opcache.preload_user=www-data 効果なし (CPU バウンドじゃない) 195.39 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 13
Slide 13 text
2. opcache.jit 無効化 zend_extension=opcache.so ;opcache.jit=disable 効果なし (CPU バウンドじゃない) 199.29 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 14
Slide 14 text
3. opcache 無効化 ;zend_extension=opcache.so 抜群の効果 125.00 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 15
Slide 15 text
4. xdebug 有効化 zend_extension=xdebug 地味な一撃 101.90 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 16
Slide 16 text
ここまでの総評 気づかれずにミドルで与える打撃はこのくらい。 もっと過激な手段としては prefork の startServer 1 PHP のバージョンダウン Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 17
Slide 17 text
5. eager loading 廃止 $posts = \App\Models\Post::take(20); //->with('user') //->with('linkPosts') //->with('linkedPosts')->get(); 効果は抜群だ! 22.76 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 18
Slide 18 text
6. limit 句 廃止 $posts = \App\Models\Post::get(); return view(...)->with('posts', $posts->take(20)); mysqlnd の優秀さがわかる 12.83 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 19
Slide 19 text
7. Attribute Casting 乱用 foreach($posts as $post){ $post->created_at; $post->updated_at; $post->created_at; $post->updated_at; } Carbon の生成コストを侮るなかれ 6.5 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 20
Slide 20 text
総評 現場でありえそうなコードでも、50msec -> 1.5 sec 程度に低速化 単体アクセスも遅いが、特に並列化性能は 30 倍程度劣化 ※複雑化したコードベースでは注意しないとすぐ劣化 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 21
Slide 21 text
おまけ カリカリチューニング編 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 22
Slide 22 text
1. apcu キャッシュ apcu_store('key', $posts); メモリキャッシュ最高 865.7 (Req/Sec) Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 23
Slide 23 text
2. var_export して include $posts は stdclass で中身を置き換えた上で file_put_contents('/tmp/posts.php', '
Slide 24
Slide 24 text
3. var_export して preload 上の /tmp/posts.php を preload してしまう 1300 (Req/Sec) Laravel で 5msec の世界 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 25
Slide 25 text
これなら Isucon 勝てる? 単純比較は出来ないが、多分無理。 静的 HTML すると 8000 (Req/Sec) Nginx でやってみると 12000 (Req/Sec) Go は、この1.5 倍くらいなので、18000 と仮定すると、あと13 倍速 くすればワンチャンある。 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 26
Slide 26 text
Octane は? ソース見てないので実測だけだが、単純な高速化において swoole ベースで 、今回の 6 割くらいの性能に収まった。 レースコンディションで問題を起こさないようにするために、どこ かで同期処理が入っているのだと思う。 Laravel.shibuya Ryo Tomidokoro / @hanhan1978
Slide 27
Slide 27 text
じゃあどうしたら? Go を書け Open Swoole と 軽量フレームワークを組み合わせて同期処理を廃 すれば、チャンスはある。 Laravel.shibuya Ryo Tomidokoro / @hanhan1978