Page 1
FuzedErlang and Rails, Sittin’ in a Tree
Dave Fayram & Tom Preston-Werner
Page 2
github.com/KirinDave/
fuzed
Page 3
“If humans can land robots on
Mars, then there is no reason
we can’t make a fast Ruby.”
—Evan Phoenix
Page 4
http
://flickr.co
m/p
hoto
s/drb
rain/4
21875792/
Phoenix
Page 5
But no matter how fast Ruby is...
Page 6
...we will always need a way to scale it!
Page 7
Traditional Scaling
Page 9
nginx
internet
mongrel mongrel
mongrel
Page 10
nginx
internet
mongrel
mongrel
mongrel
mongrel
mongrel
mongrel
mongrel
mongrel
mongrel
Page 11
internet
nginx
load
balancer
nginx
Page 12
What happens if a machine fails?
Page 13
What happens if you need to add more
hardware fast?
Page 14
What happens if you have a mixture of very fast and
very slow pages?
Page 15
What do you do about a staging setup?
Page 16
How do you deal with scaling in a flexible cloud
(like EC2)?
Page 17
What happens if you change your environment
(e.g. from EC2 to a colo facility)?
Page 19
Real Time
Cluster
Assembly
Page 22
What happens if a machine fails?
It will automatically be taken out of rotation, and
rejoin once back up.
Page 23
What happens if you need to add more
hardware fast?
No configuration changes necessary.
Just add more nodes.
Page 24
What happens if you have a mixture of very fast and
very slow pages?
Fuzed uses “next available resource”
queuing. Not a problem.
Page 25
What do you do about a staging setup?
Run multiple versions of your app in the same cloud!
Page 26
How do you deal with scaling in a flexible cloud
(like EC2)?
Please. Fuzed was MADE for a dynamic cloud environment.
Page 27
What happens if you change your environment
(e.g. from EC2 to a colo facility)?
Change a few hostnames in startup
commands. Done.
Page 28
Insanely Flexible
or, what I like to call
Multiple Dimensions of Horizontal Scalability
Page 31
faceplate
faceplate
master
Page 32
faceplate
faceplate
master
worker
worker
worker
Page 33
faceplate
faceplate
faceplate
faceplate
master
worker
worker
worker
Page 34
faceplate
faceplate
faceplate
faceplate worker
master
worker
worker
worker
worker
worker
worker
worker
Page 35
Things Fuzed Does Not
Help You With
Page 36
DB
Scaling your Database
DB
DB
DB
Page 37
DB
Scaling your Databasebummer
dude!
DB
DB
DB
Page 38
Raw Speed
SWEETSWEET
Page 39
Basic Fuzed Architecture
Page 42
masterfaceplate resource_manager
Page 43
resource_manager
worker
worker
worker
port
port
port
masterfaceplate
Page 44
details
resource_manager
worker
worker
worker
port
port
port
masterfaceplate
Page 45
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
port
faceplate
Page 46
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
port
faceplate
Page 47
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
port
faceplate
internet
Page 48
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
port
faceplate
internet
Page 49
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
port
faceplate
internet
Page 50
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
faceplate
internet
port
Page 51
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
faceplate
internet
port
Page 52
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
faceplate
internet
port
Page 53
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
faceplate
internet
port
Page 54
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
faceplate
internet
port
Page 55
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
faceplate
internet
port
Page 56
master
resource_manager
worker
worker
worker
port
port
portpool
port
port
port
faceplate
internet
Page 57
ChassisLike the River Styx only
where Erlang is the Earth and Ruby is Hades.
Wait—that came out wrong.
Page 58
class RailsHandler < Chassis
kind "rails"
handle(:handle_request, :request) do |args|
$handler.service(args[:request])
end
end
Rails Chassis
Page 59
class RailsHandler < Chassis
kind "rails"
handle(:handle_request, :request) do |args|
$handler.service(args[:request])
end
end
Rails Chassis
Page 60
Request (rack-style){ "SERVER_NAME" => "frontend_responder", "HTTP_USER_AGENT" => "Mozilla/5.0 Firefox/3.0", "HTTP_ACCEPT_ENCODING" => "gzip,deflate", "PATH_INFO" => "/main/go", "HTTP_HOST" => "localhost:8080", "HTTP_ACCEPT_LANGUAGE" => "en-us,en;q=0.5", "REQUEST_PATH" => "/", "HTTP_KEEP_ALIVE" => "300", "HTTP_VERSION" => "1.1", "HTTP_ACCEPT_CHARSET" => "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "SERVER_PORT" => nil, "Cache-Control" => "max-age=0", "QUERY_STRING" => "", "HTTP_ACCEPT" => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "HTTP_CONNECTION" => "keep-alive", "REQUEST_METHOD" => "GET", "rack.input" => #<StringIO:0x238cc1c>, "rack.errors" => #<IO:0x2f7c4>, "rack.run_once" => false, "rack.url_scheme" => "http", "rack.multiprocess" => false, "rack.multithread" => true, "rack.version" => [0, 1]}
Page 61
[:response,
[[:status, 200], [:allheaders,
[[:header, "Server", "YAWS + Fuzed 0.0.1"], [:header, "Content-Type", "text/html; charset=utf-8"],
[:header, "Cache-Control", "no-cache"], [:header, "Connection", "close"],
[:header, "Content-Length", "4"]]], [:html, "done"]]]
Response (yaws-style)
Page 62
Chassis is a language agnostic construct
Ruby
Python
LispScheme
BefungeC
Page 63
Oh, you need a scalableJSON server too?
Page 66
require 'chassis'
class AdderNode < Chassis kind "calculon"
handle(:add, :arg1, :arg2) do |args| args[:arg1] + args[:arg2] end
handle(:crash) do |args| raise "You asked me to crash, so I did." endend
Page 68
Eliminate the master as a single point of failure
mastermaster
master
master
Page 69
•URL paths
•HTTP headers
•Error handling (flexible strategies)
Additional dispatch details
Page 70
More Chassis ModulesWe love contributions!
http://github.com/KirinDave/fuzed
Page 72
Fuzed is:
Your secret scalability weapon!
Page 73
Thanks to our employer
Powerset