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.7k
同期的なプログラミング言語の視点から非同期処理を理解する/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
集中して作業する技術/how_to_work_deeply
hanhan1978
59
40k
PHPでデータベースを作ってみた/create-data-with-php
hanhan1978
10
8.9k
ADRを一年運用してみた/adr_after_a_year
hanhan1978
8
3.3k
B+木入門:PHPで理解する データベースインデックスの仕組み/b-plus-tree-101
hanhan1978
5
4.4k
ADRを一年運用してみた/our_story_about_adr
hanhan1978
5
1.9k
PHPで学ぶ Session の基本と応用 / web-app-session-101-2024
hanhan1978
12
5.4k
レガシー回避のPHP開発術/avoid_php_legacy
hanhan1978
16
12k
Laravel Collectionの計算量を調べてみた2023/laravel_collection_time_complexity_2023
hanhan1978
1
1.3k
PHP で学ぶ Cache の距離の話 / study_cache_with_php
hanhan1978
7
2.1k
Other Decks in Technology
See All in Technology
Grafana エコシステムの活用事例 on ABEMA
tetsuya28
4
320
Oracle GoldenGate 23ai 導入Tips
oracle4engineer
PRO
1
280
Vespaを利用したテクいベクトル検索
szdr
2
190
LINE-ChatGPT 倫理問題を整理する全力肯定彼氏くん [LuC4]に訪れたサービス開始以来の最大の危機
o_ob
2
160
Slackbot × RAG で実現する社内情報検索の最適化
howdy39
2
340
RAG: from dumb implementation to serious results
glaforge
0
150
KubeVirt Networking ONIC 2024
orimanabu
4
640
Deno Deploy で Web Cache API を 使えるようになったので試した知見
toranoana
1
110
Road to Single Activity Uncovered
yurihondo
0
100
リスクから学ぶKubernetesコンテナセキュリティ/k8s-risk-and-security
mochizuki875
1
330
Kubernetes Meetup Tokyo #67 - KEP-3619: Fine-grained SupplementalGroups Control / k8sjp67-kep-3619
everpeace
0
150
Case Study: Concurrent Counting
ennael
PRO
0
120
Featured
See All Featured
GitHub's CSS Performance
jonrohan
1030
450k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
110
6.9k
How to Ace a Technical Interview
jacobian
275
23k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Product Roadmaps are Hard
iamctodd
PRO
48
10k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
504
140k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Code Reviewing Like a Champion
maltzj
519
39k
Ruby is Unlike a Banana
tanoku
96
11k
Statistics for Hackers
jakevdp
796
220k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
41
9.2k
Robots, Beer and Maslow
schacon
PRO
157
8.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