俺の Laravel がこんなに速いわけがない! / My Laravel Too Fast
by
Ryo Tomidokoro
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
俺の 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