scaling with event-based webservers

116
Scaling with event– based webservers Morten Siebuhr Open Source Days March 5th 2011 1/66

Upload: morten-siebuhr

Post on 28-May-2015

1.821 views

Category:

Technology


1 download

DESCRIPTION

Slides from my talk at Open Source Days 2011 on Event-based webservers.

TRANSCRIPT

Page 1: Scaling with event-based webservers

Scaling with event–based webserversMorten Siebuhr

Open Source DaysMarch 5th 2011

1/66

Page 2: Scaling with event-based webservers

whoami(1)

Defining “web–server work”

Killing Apache

Event–based servers

Using Node.js

Questions

2/66

Page 3: Scaling with event-based webservers

whoami(1)

3/66

Page 4: Scaling with event-based webservers

Computer Scientist

Distributed Systems / Scientific Computing

(Web–)developer @ One.com

4/66

Page 5: Scaling with event-based webservers

Web–development @ one.com:

Rich Internet Applicationse–mail, calendar, galleries, . . .

+ 900.000 customers

5/66

Page 6: Scaling with event-based webservers

6/66

Page 7: Scaling with event-based webservers

Defining“Web–server work”

7/66

Page 8: Scaling with event-based webservers

Typical web–server work

Serving static files

Talking to databases

Not doing lots of computations

≈ 100→ 1000 connections served ASAP

8/66

Page 9: Scaling with event-based webservers

Typical web–server work

Serving static files

Talking to databases

Not doing lots of computations

≈ 100→ 1000 connections served ASAP

8/66

Page 10: Scaling with event-based webservers

Typical web–server work

Serving static files

Talking to databases

Not doing lots of computations

≈ 100→ 1000 connections served ASAP

8/66

Page 11: Scaling with event-based webservers

Typical web–server work

Serving static files

Talking to databases

Not doing lots of computations

≈ 100→ 1000 connections served ASAP

8/66

Page 12: Scaling with event-based webservers

Typical web–server work

Serving static files

Talking to databases

Not doing lots of computations

≈ 100→ 1000 connections served ASAP

8/66

Page 13: Scaling with event-based webservers

(A)typical web–server work

Persistent connections

=∞ simultaneous connections

≈ 10000 simultaneous connections

(But we don’t care as much about latency. . . )

9/66

Page 14: Scaling with event-based webservers

(A)typical web–server work

Persistent connections

=∞ simultaneous connections

≈ 10000 simultaneous connections

(But we don’t care as much about latency. . . )

9/66

Page 15: Scaling with event-based webservers

(A)typical web–server work

Persistent connections

=∞ simultaneous connections

≈ 10000 simultaneous connections

(But we don’t care as much about latency. . . )

9/66

Page 16: Scaling with event-based webservers

(A)typical web–server work

Persistent connections

=∞ simultaneous connections

≈ 10000 simultaneous connections

(But we don’t care as much about latency. . . )

9/66

Page 17: Scaling with event-based webservers

(A)typical web–server work

Persistent connections

=∞ simultaneous connections

≈ 10000 simultaneous connections

(But we don’t care as much about latency. . . )

9/66

Page 18: Scaling with event-based webservers

waiting...

10/66

Page 19: Scaling with event-based webservers

sleep(1.0)

11/66

Page 20: Scaling with event-based webservers

12/66

Page 21: Scaling with event-based webservers

0 s

5 s

10 s

15 s

20 s

25 s

0 100 200 300 400 500 600 700 800 900 1000

Avera

ge r

esponse tim

e

Concurrent requests

Response time w. sleep(1).

WSGI

13/66

Page 22: Scaling with event-based webservers

0 s

5 s

10 s

15 s

20 s

25 s

0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000

Avera

ge r

esponse tim

e

Concurrent requests

Response time w. sleep(1).

WSGI

14/66

Page 23: Scaling with event-based webservers

Threading

15/66

Page 24: Scaling with event-based webservers

Use threads

16/66

Page 25: Scaling with event-based webservers

Wasted resources!

17/66

Page 26: Scaling with event-based webservers

Add threads

18/66

Page 27: Scaling with event-based webservers

0 s

5 s

10 s

15 s

20 s

25 s

0 100 200 300 400 500 600 700 800 900 1000

Avera

ge r

esponse tim

e

Concurrent requests

Response time w. sleep(1).

WSGIApache

19/66

Page 28: Scaling with event-based webservers

0 s

5 s

10 s

15 s

20 s

25 s

0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000

Avera

ge r

esponse tim

e

Concurrent requests

Response time w. sleep(1).

WSGIApache

20/66

Page 29: Scaling with event-based webservers

21/66

Page 30: Scaling with event-based webservers

22/66

Page 31: Scaling with event-based webservers

23/66

Page 32: Scaling with event-based webservers
Page 33: Scaling with event-based webservers

0 MB

250 MB

500 MB

750 MB

1000 MB

1250 MB

1500 MB

0 100 200 300 400 500 600 700 800 900 1000

Max V

irtu

al M

em

ory

Concurrent requests

Memory usage w. sleep(1).

WSGIApache

25/66

Page 34: Scaling with event-based webservers

0 MB

250 MB

500 MB

750 MB

1000 MB

1250 MB

1500 MB

0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000

Max V

irtu

al M

em

ory

Concurrent requests

Memory usage w. sleep(1).

WSGIApache

26/66

Page 35: Scaling with event-based webservers

A single connection

=

1 thread

=

1 C–stack & kernel data structures

+

Locking & switching overhead &c. . .

27/66

Page 36: Scaling with event-based webservers

A single connection

=

1 thread

=

1 C–stack & kernel data structures

+

Locking & switching overhead &c. . .

27/66

Page 37: Scaling with event-based webservers

A single connection

=

1 thread

=

1 C–stack & kernel data structures

+

Locking & switching overhead &c. . .

27/66

Page 38: Scaling with event-based webservers

A single connection

=

1 thread

=

1 C–stack & kernel data structures

+

Locking & switching overhead &c. . .

27/66

Page 39: Scaling with event-based webservers

28/66

Page 40: Scaling with event-based webservers

Add memory!

Memory is cheap

Except, actually using it isn’t cheap. . .

29/66

Page 41: Scaling with event-based webservers

Add memory!

Memory is cheap

Except, actually using it isn’t cheap. . .

29/66

Page 42: Scaling with event-based webservers

Add memory!

Memory is cheap

Except, actually using it isn’t cheap. . .

29/66

Page 43: Scaling with event-based webservers

Memory Wall

1986→ 2000:

+ 55% CPU speed P/A

+ 10% RAM speed P/A

(Source: http://www.cs.virginia.edu/papers/Hitting_Memory_Wall-wulf94.pdf)

30/66

Page 44: Scaling with event-based webservers

Memory Wall

1986→ 2000:

+ 55% CPU speed P/A

+ 10% RAM speed P/A

(Source: http://www.cs.virginia.edu/papers/Hitting_Memory_Wall-wulf94.pdf)

30/66

Page 45: Scaling with event-based webservers

Memory Wall

1986→ 2000:

+ 55% CPU speed P/A

+ 10% RAM speed P/A

(Source: http://www.cs.virginia.edu/papers/Hitting_Memory_Wall-wulf94.pdf)

30/66

Page 46: Scaling with event-based webservers

31/66

Page 47: Scaling with event-based webservers

Threads and connections mapped 1:1

We use a lot of threads

Which we don’t have the memory bandwidth to move around.

32/66

Page 48: Scaling with event-based webservers

Threads and connections mapped 1:1

We use a lot of threads

Which we don’t have the memory bandwidth to move around.

32/66

Page 49: Scaling with event-based webservers

Threads and connections mapped 1:1

We use a lot of threads

Which we don’t have the memory bandwidth to move around.

32/66

Page 50: Scaling with event-based webservers

Events!

33/66

Page 51: Scaling with event-based webservers

waiting...

34/66

Page 52: Scaling with event-based webservers

35/66

Page 53: Scaling with event-based webservers

36/66

Page 54: Scaling with event-based webservers

Event-basics

Event queue

Event loop

“The Event Loop”

37/66

Page 55: Scaling with event-based webservers

Event-basics

Event queue

Event loop

“The Event Loop”

37/66

Page 56: Scaling with event-based webservers

Event-basics

Event queue

Event loop

“The Event Loop”

37/66

Page 57: Scaling with event-based webservers

Event-basics

Event queue

Event loop

“The Event Loop”

37/66

Page 58: Scaling with event-based webservers

A single connection

=

1 “Event”

=

Some variables & function

=

Hash table & some pointers

+

Queue of events waiting to be processed

38/66

Page 59: Scaling with event-based webservers

A single connection

=

1 “Event”

=

Some variables & function

=

Hash table & some pointers

+

Queue of events waiting to be processed

38/66

Page 60: Scaling with event-based webservers

A single connection

=

1 “Event”

=

Some variables & function

=

Hash table & some pointers

+

Queue of events waiting to be processed

38/66

Page 61: Scaling with event-based webservers

A single connection

=

1 “Event”

=

Some variables & function

=

Hash table & some pointers

+

Queue of events waiting to be processed

38/66

Page 62: Scaling with event-based webservers

A single connection

=

1 “Event”

=

Some variables & function

=

Hash table & some pointers

+

Queue of events waiting to be processed

38/66

Page 63: Scaling with event-based webservers

39/66

Page 64: Scaling with event-based webservers

39/66

Page 65: Scaling with event-based webservers

39/66

Page 66: Scaling with event-based webservers

39/66

Page 67: Scaling with event-based webservers

Why not earlier

Simply not a problem!

Traditional back–end programmers not used to thinking this way

40/66

Page 68: Scaling with event-based webservers

Why not earlier

Simply not a problem!

Traditional back–end programmers not used to thinking this way

40/66

Page 69: Scaling with event-based webservers

Why not earlier

Simply not a problem!

Traditional back–end programmers not used to thinking this way

40/66

Page 70: Scaling with event-based webservers

What we gain

Relatively low memory use

No threading issues

Client-side programmers have no preconditions.

41/66

Page 71: Scaling with event-based webservers

What we gain

Relatively low memory use

No threading issues

Client-side programmers have no preconditions.

41/66

Page 72: Scaling with event-based webservers

What we gain

Relatively low memory use

No threading issues

Client-side programmers have no preconditions.

41/66

Page 73: Scaling with event-based webservers

What we gain

Relatively low memory use

No threading issues

Client-side programmers have no preconditions.

41/66

Page 74: Scaling with event-based webservers

Node.js

42/66

Page 75: Scaling with event-based webservers

Node.js is a set of bindings to the V8 JavaScript enginefor scripting network programs.

— Ryan Dahl

43/66

Page 76: Scaling with event-based webservers

Node.js is a set of bindings to the V8 JavaScript enginefor scripting network programs.

— Ryan Dahl

43/66

Page 77: Scaling with event-based webservers

JavaScript

Built for event-based programming.

Netscape needed something fast. . .. . . JavaScript “designed” and implemented in 14 days

44/66

Page 78: Scaling with event-based webservers

JavaScript

Built for event-based programming.

Netscape needed something fast. . .. . . JavaScript “designed” and implemented in 14 days

44/66

Page 79: Scaling with event-based webservers

JavaScript

Built for event-based programming.

Netscape needed something fast. . .. . . JavaScript “designed” and implemented in 14 days

44/66

Page 80: Scaling with event-based webservers

JavaScript

Built for event-based programming.

Netscape needed something fast. . .

. . . JavaScript “designed” and implemented in 14 days

44/66

Page 81: Scaling with event-based webservers

JavaScript

Built for event-based programming.

Netscape needed something fast. . .. . . JavaScript “designed” and implemented in 14 days

44/66

Page 82: Scaling with event-based webservers

JavaScript

Built for event-based programming.

Netscape needed something fast. . .. . . JavaScript “designed” and implemented in 14 days

44/66

Page 83: Scaling with event-based webservers

Google V8

JIT’ing JavaScript to native machine code

= Compiling server code

45/66

Page 84: Scaling with event-based webservers

Google V8

JIT’ing JavaScript to native machine code

= Compiling server code

45/66

Page 85: Scaling with event-based webservers

Node.js

Non–browser V8–bindings for various libraries

Everything non–blocking

46/66

Page 86: Scaling with event-based webservers

A minimal webserver in Node.js. . .

// Import HTTP package

var http = require(’http’);

// Set up basic server

var server = http.createServer(function (req , res) {

res.writeHead (200, {’Content -Type’: ’text/plain ’});

res.end(’Hello World\n’);

});

// Start the server

server.listen (8124, "127.0.0.1");

console.log(’Server running at http ://127.0.0.1:8124/ ’);

47/66

Page 87: Scaling with event-based webservers

. . . with “database”

// Import HTTP package

var http = require(’http’);

// Set up basic server

var server = http.createServer(function (req , res) {

setTimeout(function () {

res.writeHead (200, {’Content -Type’: ’text/plain ’});

res.end(’Hello World\n’);

}, 1000);

});

// Start the server

server.listen (8124, "127.0.0.1");

console.log(’Server running at http ://127.0.0.1:8124/ ’);

48/66

Page 88: Scaling with event-based webservers

0 s

5 s

10 s

15 s

20 s

25 s

0 100 200 300 400 500 600 700 800 900 1000

Avera

ge r

esponse tim

e

Concurrent requests

Response time w. sleep(1).

WSGIApacheNode.js

49/66

Page 89: Scaling with event-based webservers

0 s

5 s

10 s

15 s

20 s

25 s

0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000

Avera

ge r

esponse tim

e

Concurrent requests

Response time w. sleep(1).

WSGIApacheNode.js

50/66

Page 90: Scaling with event-based webservers

0 MB

250 MB

500 MB

750 MB

1000 MB

1250 MB

1500 MB

0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000

Max V

irtu

al M

em

ory

Concurrent requests

Memory usage w. sleep(1).

WSGIApacheNode.js

51/66

Page 91: Scaling with event-based webservers

Connections in Node.js

=

1 “Event”

=

1 Closure + callback function

=

1 struct + some pointers

+

Event queue operations + function calls

52/66

Page 92: Scaling with event-based webservers

Connections in Node.js

=

1 “Event”

=

1 Closure + callback function

=

1 struct + some pointers

+

Event queue operations + function calls

52/66

Page 93: Scaling with event-based webservers

Connections in Node.js

=

1 “Event”

=

1 Closure + callback function

=

1 struct + some pointers

+

Event queue operations + function calls

52/66

Page 94: Scaling with event-based webservers

Connections in Node.js

=

1 “Event”

=

1 Closure + callback function

=

1 struct + some pointers

+

Event queue operations + function calls

52/66

Page 95: Scaling with event-based webservers

Connections in Node.js

=

1 “Event”

=

1 Closure + callback function

=

1 struct + some pointers

+

Event queue operations + function calls

52/66

Page 96: Scaling with event-based webservers

Alternatives

Well–written thread program!

Erlanghttp://www.erlang.org/

Google GOhttp://golang.org/

Lua Event Machinehttps://github.com/esmil/lem

Nginxhttp://wiki.nginx.org/

Varnishhttp://www.varnish-cache.org/

53/66

Page 97: Scaling with event-based webservers

Alternatives

Well–written thread program!

Erlanghttp://www.erlang.org/

Google GOhttp://golang.org/

Lua Event Machinehttps://github.com/esmil/lem

Nginxhttp://wiki.nginx.org/

Varnishhttp://www.varnish-cache.org/

53/66

Page 98: Scaling with event-based webservers

Alternatives

Well–written thread program!

Erlanghttp://www.erlang.org/

Google GOhttp://golang.org/

Lua Event Machinehttps://github.com/esmil/lem

Nginxhttp://wiki.nginx.org/

Varnishhttp://www.varnish-cache.org/

53/66

Page 99: Scaling with event-based webservers

Alternatives

Well–written thread program!

Erlanghttp://www.erlang.org/

Google GOhttp://golang.org/

Lua Event Machinehttps://github.com/esmil/lem

Nginxhttp://wiki.nginx.org/

Varnishhttp://www.varnish-cache.org/

53/66

Page 100: Scaling with event-based webservers

Alternatives

Well–written thread program!

Erlanghttp://www.erlang.org/

Google GOhttp://golang.org/

Lua Event Machinehttps://github.com/esmil/lem

Nginxhttp://wiki.nginx.org/

Varnishhttp://www.varnish-cache.org/

53/66

Page 101: Scaling with event-based webservers

Alternatives

Well–written thread program!

Erlanghttp://www.erlang.org/

Google GOhttp://golang.org/

Lua Event Machinehttps://github.com/esmil/lem

Nginxhttp://wiki.nginx.org/

Varnishhttp://www.varnish-cache.org/

53/66

Page 102: Scaling with event-based webservers

Alternatives

Well–written thread program!

Erlanghttp://www.erlang.org/

Google GOhttp://golang.org/

Lua Event Machinehttps://github.com/esmil/lem

Nginxhttp://wiki.nginx.org/

Varnishhttp://www.varnish-cache.org/

53/66

Page 103: Scaling with event-based webservers

Working with Node.js

54/66

Page 104: Scaling with event-based webservers

I’m new to JavaScript!

55/66

Page 105: Scaling with event-based webservers

56/66

Page 106: Scaling with event-based webservers

JavaScript WTFs

Always add ;!

Function arguments. . .

this scoped to callee object!

Stacktraces + events sometimes look strange

57/66

Page 107: Scaling with event-based webservers

JSLint

www.crockfordfacts.com

58/66

Page 108: Scaling with event-based webservers

JSLint

www.crockfordfacts.com

58/66

Page 109: Scaling with event-based webservers

Nice code!

def process(user):

user = getAuth(user)

if not user:

return ’Fail’

db = getConnnection(params)

data = db.getUserData(user)

if not data:

return ’Fail’

return data

59/66

Page 110: Scaling with event-based webservers

Boomerang code

function process(user , callback) {

getAuth(req.username , function (err , user) {

if (err) return callback(err);

getDBConnection(params , function(err , db) {

if (err) return callback(err);

db.getUserData(user , function(err , data) {

if (err) return callback(err);

return callback(null , data);

});

});

});

}

60/66

Page 111: Scaling with event-based webservers

NPM

61/66

Page 112: Scaling with event-based webservers

Express.js

var app = require(’express ’).createServer ();

app.get(’/’, function(req , res) {

setTimeout(function () {

res.send(’Hello World ’);

}, 1000);

});

app.listen (3000);

62/66

Page 113: Scaling with event-based webservers

Express.js - Chat server

var app = require(’express ’).createServer (),

chat = [];

app.get(’/’, function(req , res) {

chat.push(res);

});

app.get(’/:msg’, function(req , res) {

chat.forEach(function (conn) {

conn.write(req.params.msg);

});

});

app.listen (3000);

63/66

Page 114: Scaling with event-based webservers

Questions

(The end)

64/66

Page 115: Scaling with event-based webservers

http://nodejs.org/

https://github.com/joyent/node

65/66

Page 116: Scaling with event-based webservers

function process(user , callback) {

var user = null , db = null;

function done_ () {

if (user && db) {

db.getUserData(user , function(err , data) {

if (err) return callback(err);

return callback(null , data);

});

}

}

getAuth(req.username , function (err , retuser) {

if (err) return callback(err);

user = retuser;

done_();

});

getDBConnection(params , function(err , retdb) {

if (err) return callback(err);

db = retdb;

done_();

});

}

66/66