Meet a parallel, asynchronous PHP world

Preview:

Citation preview

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

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

libev libevent

inotify epoll pol event ports kqueue select

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

Recommended