Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
同期的なプログラミング言語の視点から非同期処理を理解する/understand async f...
Search
Ryo Tomidokoro
April 10, 2022
Technology
2
1.8k
同期的なプログラミング言語の視点から非同期処理を理解する/understand async from sync
PHPerKaigi 2022 の登壇資料です。
原題は「PHPでEventLoopを書いて非同期処理を完全に理解する」です。
Ryo Tomidokoro
April 10, 2022
Tweet
Share
More Decks by Ryo Tomidokoro
See All by Ryo Tomidokoro
PHPerのための計算量入門/Complexity101 for PHPer
hanhan1978
5
110
集中して作業する技術/how_to_work_deeply
hanhan1978
61
41k
PHPでデータベースを作ってみた/create-data-with-php
hanhan1978
10
9.4k
ADRを一年運用してみた/adr_after_a_year
hanhan1978
8
3.6k
B+木入門:PHPで理解する データベースインデックスの仕組み/b-plus-tree-101
hanhan1978
5
4.7k
ADRを一年運用してみた/our_story_about_adr
hanhan1978
5
2k
PHPで学ぶ Session の基本と応用 / web-app-session-101-2024
hanhan1978
12
5.5k
レガシー回避のPHP開発術/avoid_php_legacy
hanhan1978
16
12k
Laravel Collectionの計算量を調べてみた2023/laravel_collection_time_complexity_2023
hanhan1978
1
1.4k
Other Decks in Technology
See All in Technology
KnowledgeBaseDocuments APIでベクトルインデックス管理を自動化する
iidaxs
1
260
Snykで始めるセキュリティ担当者とSREと開発者が楽になる脆弱性対応 / Getting started with Snyk Vulnerability Response
yamaguchitk333
2
180
サイボウズフロントエンドエキスパートチームについて / FrontendExpert Team
cybozuinsideout
PRO
5
38k
マイクロサービスにおける容易なトランザクション管理に向けて
scalar
0
130
KubeCon NA 2024 Recap: How to Move from Ingress to Gateway API with Minimal Hassle
ysakotch
0
200
5分でわかるDuckDB
chanyou0311
10
3.2k
Qiita埋め込み用スライド
naoki_0531
0
5.1k
KubeCon NA 2024 Recap / Running WebAssembly (Wasm) Workloads Side-by-Side with Container Workloads
z63d
1
250
非機能品質を作り込むための実践アーキテクチャ
knih
5
1.4k
DevOps視点でAWS re:invent2024の新サービス・アプデを振り返ってみた
oshanqq
0
180
[Ruby] Develop a Morse Code Learning Gem & Beep from Strings
oguressive
1
160
小学3年生夏休みの自由研究「夏休みに Copilot で遊んでみた」
taichinakamura
0
150
Featured
See All Featured
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
520
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Optimising Largest Contentful Paint
csswizardry
33
3k
Building Better People: How to give real-time feedback that sticks.
wjessup
365
19k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
We Have a Design System, Now What?
morganepeng
51
7.3k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
247
1.3M
Mobile First: as difficult as doing things right
swwweet
222
9k
Unsuck your backbone
ammeep
669
57k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
Transcript
@hanhan1978 PHPでEventLoopを書いて非同期処理を 完全に理解する PHPerKaigi 2022
@hanhan1978 同期的なプログラミング言語の目線から非 同期処理を理解する PHPerKaigi 2022 とりあえず改題
イベントループは関係なかった 3 すまんな!
@hanhan1978 • 富所 亮 • 所属 株式会社カオナビ Expert • 職業
Webアプリケーションエンジニア • ブログ https://blog.hanhans.net • Yokohama North AM https://anchor.fm/yokohama-north-am 4
前回までのあらすじ 5
2021-11-25 PHP 8.1 Release Fibers が導入される 6
7 「非同期処理が簡単にかけるようになるらしいぜ?」
ここにビジネスチャンスを見出したが.... 非同期沼に突入 分かりにくいプレゼンを行ってしまう 8
9 https://speakerdeck.com/hanhan1978/php-async-programming
3行でまとめると... - 非同期処理はわからん - Fibers もよくわからん - とりあえず、PHPでPHPを動かせ 10 すまんかった
11 リベンジ https://speakerdeck.com/hanhan1978/fiber-and-async-request
3行でまとめると... - なぜ Fibers - イベントループってなに? - なぜ 非同期の仕組みがいまさらPHPに入ってくる? 12
自信作だったが、スライドが荒かった
本日は合体整理版 13
• 非同期処理とは • 2つの視点 • イベントループ • まとめ 目次 14
• 非同期処理とは • 2つの視点 • イベントループ • まとめ 目次 15
同期的なプログラミング 記述したとおりの順番で動作するようなプログラミングモデル 非同期プログラミング 独立して発生するイベントに対する処理を記述するための並行プログラミン グ手法の総称 16 高野祐輝. (2021). 並行プログラミング入門 5章
(初版.). オライリー・ジャパン.
17 PHPアプリケーションは 同期的なBlocking IOが基本
18 よくある MVC フレームワークのコード例
19 プログラムは書いた順番に順次実行され ていく
20 入出力処理が行われると プログラムは結果を待つ
21 DB検索の処理シーケンス クエリ結果が返ってくるまで メインの処理は待つ ブロッキングIOと言う
22 非同期プログラミングの例
23 単純なAPIコールの例
24 ここで処理が待たない
25 IO処理の結果を待たない メインスレッドは、待ち時間の間 に他の処理を行える ノンブロッキングIO という
26 実行順序は直感と反する ① ③ ② 慣れれば分かるんだが ......
入出力処理の結果が、いつ返ってくるか分からないの で、結果が戻ってきたときに実行する処理をコール バックで渡しておく 27
28 非同期プログラミングの利点
29 ブロッキング ノンブロッキング CPUを効率的に利用できる
マルチスレッドは難しすぎたが 非同期プログラミングであれば、普通の人間でもギリギリ許 容できそう。 Promise, Async/Await などを使えば、非同期処理も扱いや すくなる。 30
世の中の潮流としては、マルチコア -> コアの利用効率を上げることで、プログラムの処理効率 を上げる スループットの向上 31
• 非同期処理とは • 2つの視点 • イベントループ • まとめ 目次 32
33 非同期処理を考える時の二つの視点
34 1リクエスト 複数リクエスト(プロセス)
35 1リクエスト単位の視点
36
37 ToDoリストを検索するバックエンドの処理(例) 非同期処理チャンス
38 ToDoリストを検索するバックエンドの処理(例) 2つめのクエリが1つ目のクエリに依存して いる 無邪気に非同期処理を書くと、整合性のある データを取得できない
39 コールバックPHPの仮想コード
40 コールバックPHPの仮想コード 結果出力時には、検索が終わってなければいけ ない。 非同期処理をしてしまうと、データ取得前に結果 出力するはめになる
しょうがないので、全部コールバックにする.... こうして、コールバック地獄が生まれる 41
42 コールバックPHPの仮想コード
43 コールバックPHPの仮想コード 同期的プログラミングのコードのほうがはるかに 見通しが良い。 処理時間も変わらない......
コールバックは、直列に実行され、データが戻ってくるまで待 つことになるので、非同期処理の書き方をしたところで、ス ループットが上がっていない。 ※相互に依存した処理の場合、1リクエスト単位で見ると同 期でも非同期でも処理時間は変わらない 44
Fibers が いわゆる PHP アプリケーション制作において役 に立つ機能ではないと言われるのは、この辺。 45
とはいえ 1リクエスト単位の視点でも非同期処理が役に立ちそうな ケースはある 46
47 例えば、APIリクエストを3回行 う必要がある場合 かつ、それぞれのAPIコールは 相互に依存していない。
48 こんな風に処理をまとめ られたら、効率的
そういった用途には古来より curl_multi というものがある Fibers は別に使わなくても問題ない... 49
しかし、1リクエスト内でIO処理を束ねるようなケースは、そん なに多くない。 レアケースに対して、本気に殴りに行くような改善よりも、もっと 一般的なケースの改善をするほうが意味がある。 50
1リクエスト単位で考えた場合 PHPで非同期プログラミングを行うのは、あまり効果的である とは思えない。 51
52 余談
JavaScript が基本的にノンブロッキングな処理を行う理由は、 ブラウザを操作しているユーザーを待たせないため 53
54 JSのローディングイメージ例 https://webdevtrick.com/lazy-load-images/
ノンブロッキングを徹底することで、ブラウザ利用者の体験に 寄与している。このへんはプログラミング言語の根本の思想に 関わっている 55
56 複数リクエストの視点
話を単純化するために、CPUが1コアでウェブサーバーは1リ クエストずつ処理していくものとする。 57
58 1リクエストを以下のように図示する ※斜線部分は IO 以外の処理を行っているものとする
59 通常の PHP ウェブアプリケーションでは リクエストはそれぞれ独立に直列で処理される
60 いわゆる PHP ウェブサーバーの構成
今までの普通のPHPウェブアプリケーションでは、IO処理が もったいないと感じても、その間の資源を他に割り当てられな かった。 61
62 いわゆる PHP ウェブサーバーの構成 Nginx も PHP-FPM も 個別の PHP
プロセスの処理状況を細かく 監視できない
もし、リクエストをまたいで非同期処理が行えたら、IO待ちの時 に、他のリクエストを処理することで効率的にリクエストをさばく ことができる。 63
64
実際に Fibers が利用が想定されているのは、リクエストをま たいだパターンが多そう リクエストをまたいで、処理の停止・実行を行うためには、全て のリクエスト処理が、PHPのメイン処理から実行されている必 要がある 65
66 私が、PHP が PHP を実行する必要があると 言っていたのはコレ。
この世界観については、すでに Swoole 、 ReactPHP、 AmPHP などで実現されている このように、PHPの主処理が停止せずにリクエストを実行して いくという処理パターンの文脈で イベントループがでてくる 67
68 余談
69 Mastering Swoole PHP - Bruce Dou Swoole 作者による解説著作 全体の2/3がPHPの処理モデル
やIOモデルの説明となっていて、 非同期を取り巻く状況を雑観でき る。
• 非同期処理とは • 2つの視点 • イベントループ • まとめ 目次 70
71 イベントループとは?
72 https://en.wikipedia.org/wiki/Event_loop イベントループの構成要素 Wiki から想像して作図
73 イベントループの構成要素 リクエストはQueueで直列化される (DeMultiplex)
74 イベントループの構成要素 Event Loop 側はシングルスレッドで処理できる (Reactor Pattern)
75 実装はループ処理 例えば、配列にイベントが追加され ループで逐次処理されるのも、立派なイベントループ
イベントループで実行されるEvent が Fiber オブジェクトになっ ていれば Suspend Restart をメインスレッドから抽象的に扱うことができる。 76
77 一番のポイント
フレームワークの利用者側の視点で考えると 同期的プログラミングを継続できる 同期的プログラミングを行ったまま、非同期プログラミングの恩 恵を受けることができる そんな非同期フレームワークを、Fibers を使うことで抽象的に 理解しやすく作れる 78
今後、Promise や Async/Await が PHP にもたらされる可能 性はあるが、そもそも同期的であることに意味がある場合が多 そうなので、利用シーンは限られそう 79
• 非同期処理とは • 2つの視点 • イベントループ • まとめ 目次 80
非同期処理、Fibers、イベントループ この3つのキーワードがセットになって語られることが多いが、 その理由はリクエストをまたいだ非同期処理を行うことが、 PHPウェブアプリケーションにとって、もっとも現実的で徳が多 そうだから 81
82 Fibers を使った Event Loop の例 実装方法はたくさんある
実際は、ev拡張などを利用すれば、現状でもイベントループを 簡単に書くことは出来る。 Fibers はイベントループから実行された処理スレッドの停止・ 再開判断を抽象的に便利に行える機能と考えると分かりやす い 83
84 とはいえ、書いてみないと実感しづらい
85 雑なスライドだが実装サンプルを載せた https://speakerdeck.com/hanhan1978/fiber-and-async-request
APIリクエストの非同期実行を 生PHP -> Generator -> Fiber と抽象化していくサンプル Fibers は、抽象化の道具なんだね!が実感できる 86
@hanhan1978 相談・指摘・その他 下記のTwitterアカウントにどうぞ 87