PHPDay 2015 – Verona, Italy, May 16th 2015
Meet a Parallel
Asynchronous PHP World
STEVE @MARASPIN
http://www.mvlabs.it/
USE CASE
6
7
AWESOME PHP MUM
How does it work?
9
We have a client…
10
11
What do you
want for lunch?
12
13
Cool. BRB!
PHP Makes I/O Requests…
14
PHP awaits for I/O…
15
I/O Ready
16
Content Delivered
17
DELICIOUS LUNCH!
GOING ENTERPRISE
TROUBLES ARISE
21
22
23
~20s
WHY SO MUCH TIME?
25
26
27
28
29
30
31
What do you
want for lunch?
32
33
34
35
What do you
want for lunch?
Gotta look for
a better strategy…
37
38
What do
you want for
lunch?
39
What do
you want for
lunch?
40
What do
you want for
lunch?
41
42
43
44
45
46
47
48
49
curl_multi_add_handle
50
curl_multi_exec
curl_multi_info_read
curl_multi_getcontent
51
curl_multi_exec
curl_multi_info_read
curl_multi_getcontent
52
curl_multi_exec
curl_multi_info_read
curl_multi_getcontent
53
54
~20s
~2s
55
Ordered Results
56
No More!
Solution #1:
PHP Asynchronous Calls
57
58
• Within PHP
• Easy to use
Pros Cons
• Limited set of
available
commands
VARIETY WANTED
CHEFS TO THE RESCUE
61
Simple Message Queue
Multiple Consumers / Workers
More Decoupling…
JACK OF ALL TRADES
66
Useful if already within stack & simple system – please take a look: http://antirez.com/news/88
67
68
lPush
69
brPop
70
71
72
batch_basic_publish / basic_publish
73
basic_consume
74
75
What do
you want for
lunch?
76
What do
you want for
lunch?
77
What do
you want for
lunch?
78
79
80
81
82
?
Solution #2:
Message Queues
83
84
• Scales well
• Can be made
resilient
• Decoupling
Pros Cons
• Extra software
components
• Lack of Feedback
to invoking
process
85
86
http://gearman.org/
87
addTaskBackground
88
addFunction
89
90
addTaskBackground
91
addTask
92
93
~20s
94
OK, so just
prepare …
95
96
97
98
99
100
101
102
103
OK, so just
prepare …
We need multiple (parallel) workers if we wish to improve performance
Solution #3:
Job Server
104
105
• Scales well
• Decoupling
• Possibly
resilient
• Return Values
Pros Cons
• Extra
software
components
• Extra
processes
PHP FAMILY BUSINESS
107
What do
you want for
lunch?
What do
you want for
lunch?
What do
you want for
lunch?
108
109
110
111
112
Background exec
113
114
What do
you want for
lunch?
115
?
?
?
Same problem as before…
Solution #4:
Exec & Co.
116
117
• Very easy to
implement
Pros Cons
• No return
values
• Extra
processes
PHP THREADS
pthreads
"pthreads requires a build of PHP
with ZTS (Zend Thread Safety)
enabled"
119
pthreads
"pthreads requires a build of PHP
with ZTS (Zend Thread Safety)
enabled"
120
MUM GOT DAUGHTER(S)
122
123
pcntl_fork
124
pcntl_waitpid
125
126
What do
you want for
lunch?
What do
you want for
lunch?
127
128
129
What do
you want for
lunch?
Solution #5:
Forking processes
130
131
• Within PHP
• Allows for
parallelism
• Exploits available
CPU cores
Pros Cons
• Feedback (besides exit
status) difficult to get
• Parallelism bound to #
of available CPU cores
• Not to be used within
Apache or web servers
in general
Latency Comparison Numbers
L1 cache reference 0.5 ns
Branch mispredict 5 ns
L2 cache reference 7 ns
Mutex lock/unlock 25 ns
Main memory reference 100 ns
Send 1K bytes over 1 Gbps network 10,000 ns
Read 4K randomly from SSD* 150,000 ns
Read 1 MB sequentially from memory 250,000 ns
Round trip within same datacenter 500,000 ns
Read 1 MB sequentially from SSD* 1,000,000 ns
Disk seek 10,000,000 ns
Read 1 MB sequentially from disk 20,000,000 ns
Send packet CA->Netherlands->CA 150,000,000 ns
Let's consider these numbers…
Source: https://gist.github.com/jboner/2841832
Latency Comparison Numbers
L1 cache reference 0.5 ns
Branch mispredict 5 ns
L2 cache reference 7 ns
Mutex lock/unlock 25 ns
Main memory reference 100 ns
Send 1K bytes over 1 Gbps network 10,000 ns
Read 4K randomly from SSD 150,000 ns
Read 1 MB sequentially from memory 250,000 ns
Round trip within same datacenter 500,000 ns
Read 1 MB sequentially from SSD 1,000,000 ns
Disk seek 10,000,000 ns
Read 1 MB sequentially from disk 20,000,000 ns
Send packet CA->Netherlands->CA 150,000,000 ns
We got an I/O issue!
Source: https://gist.github.com/jboner/2841832
Blocking I/O happens when…
 Sending an e-mail
 Communicating with Databases
 Communicating with other
services
 Reading/writing data on Disk
 Reading/writing data on Network
 …
136
What do
you want for
lunch?
137
138
What do
you want for
lunch?
139
140
What do
you want for
lunch?
141
142
143
144
145
146
147
148
149
150
EVENTS
DIY TIMER
I/O Multiplexing
154
PHP stream_select
156
Runs the equivalent of the select() system call
on the given arrays of streams with a timeout
specified by tv_sec and tv_usec
157
158
159
Solution #6:
stream_select
160
161
• Within PHP
• Removes I/O
wait overhead
Pros Cons
• Cumbersome
within large
projects
• Performances
could be better
Libevent
• API providing a mechanism to execute
a callback when a specific event
occurs on a file descriptor or after a
timeout
• supports /dev/poll, kqueue(2), event
ports, POSIX select(2), Windows
select(), poll(2), and epoll(4)
notification mechanisms
162
163
164
Solution #7:
libevent
165
166
• Within PHP
• More
performant
than select
Pros Cons
• Cumbersome
within large
projects
• Might behave
differently within
different OSs
WHY A LOUSY OVEN?
WHEN WE COULD USE…
A REACTOR!
Reactor Pattern
event loop
(event1, callback1)
(event2, callback2)
on(event1)  (callback1)
on(event2)  (callback2)
 Implements reactor pattern
 Formerly known as Node.PHP
 Non-blocking I/O
 Event Loop
http://reactphp.org
React
libevlibevent
inotifyepollpolevent portskqueueselect
175
176
Out of loop: Ignored!
177
HTTP
Socket
Stream
Event Loop
179
180
Promise
181
182
Streams
183
184
185
https://bugs.php.net/bug.php?id=64696
"epoll" itself (used by Libevent on Linux)
doesn't support regular files. Epoll expects
whether sockets, or pipes"
186
Libev uninstalled…
187
188
189
Solution #8:
React
190
191
• Wrapper
around many
event handlers
• Good
abstractions
Pros Cons
• Still in 0.x
• New
paradigm
SUMMARIZING THINGS
193
Parallel
194
Asynchronous
195
WHAT'S NEXT?
HACK ASYNC
http://docs.hhvm.com/manual/en/hack.async.php
Node.JS Galore
• https://github.com/chobie/php-uv
198
Node.JS Galore
• https://github.com/JosephMoniz/node.php
199
Interesting resources…
• Ratchet
http://socketo.me/
• Cooperative Multitasking using coroutines
https://nikic.github.io/2012/12/22/Cooperative-
multitasking-using-coroutines-in-PHP.html
• Recoil
https://github.com/recoilphp/recoil
200
THANK YOU!
Picture Credits
Spider: https://www.flickr.com/photos/janajermakova/10616495683/
Table: https://www.flickr.com/photos/turnstonefurniture/5731379672/
Gnocchi: https://www.flickr.com/photos/cookingetc/6864270056/
Skeptical Dog: https://www.flickr.com/photos/jacobyarborough/13564967155/
Kitchen Accident: https://www.flickr.com/photos/aleksiaaltonen/4803518904/
Variety: https://www.flickr.com/photos/gammaman/6135388116/
Chefs: https://www.flickr.com/photos/lesroches/8700412835/
Man in Kitchen: https://www.flickr.com/photos/paullew/4542993694/
Family: https://www.flickr.com/photos/gareth1953/5173076989/
Organize: https://www.flickr.com/photos/7502393@N04/472028888/
Timer: https://www.flickr.com/photos/lucidscience/5079439604/
Oven: https://www.flickr.com/photos/bonedaddy/2889601088
Presentation: https://www.flickr.com/photos/oecd_development_centre/10168550803/
Reactor: https://www.flickr.com/photos/mandj98/2468396121/
Stirring: https://www.flickr.com/photos/nicoleabalde/7191104180/
Table Ready: https://www.flickr.com/photos/thefalcondale/6940598837/
Other pictures by Steve Maraspin, or from Fotolia Archives
202
Stefano Maraspin
@maraspin
s.maraspin@mvlabs.it

Meet a parallel, asynchronous PHP world