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
Cheating Your Way to Webscale
Search
Matt Robenolt
May 02, 2014
Programming
13
1.4k
Cheating Your Way to Webscale
Python Nordeste, May 2nd 2014
Matt Robenolt
May 02, 2014
Tweet
Share
More Decks by Matt Robenolt
See All by Matt Robenolt
Everything is broken and I don't know why.
mattrobenolt
0
44
I am bad at my job.
mattrobenolt
0
200
Everything is broken, and I don't know why. Python edition.
mattrobenolt
1
200
Everything is broken, and I don't know why. Python edition.
mattrobenolt
2
580
Varnish: How We Do It
mattrobenolt
1
220
Everything is broken, and I don't know why.
mattrobenolt
7
1.5k
HTTP for Great Good
mattrobenolt
85
200k
Caching is Hard: Varnish @ Disqus
mattrobenolt
52
2.1M
Developing & Deploying "Large" Scale Web Applications
mattrobenolt
25
1.3k
Other Decks in Programming
See All in Programming
Pull-Requestの内容を1クリックで動作確認可能にするワークフロー
natmark
2
520
ソフトウェア設計の実践的な考え方
masuda220
PRO
4
600
iOSエンジニア向けの英語学習アプリを作る!
yukawashouhei
0
200
実践Claude Code:20の失敗から学ぶAIペアプログラミング
takedatakashi
15
5.5k
Claude CodeによるAI駆動開発の実践 〜そこから見えてきたこれからのプログラミング〜
iriikeita
0
290
monorepo の Go テストをはやくした〜い!~最小の依存解決への道のり~ / faster-testing-of-monorepos
convto
2
500
いま中途半端なSwift 6対応をするより、Default ActorやApproachable Concurrencyを有効にしてからでいいんじゃない?
yimajo
2
440
はじめてのDSPy - 言語モデルを『プロンプト』ではなく『プログラミング』するための仕組み
masahiro_nishimi
2
600
私達はmodernize packageに夢を見るか feat. go/analysis, go/ast / Go Conference 2025
kaorumuta
2
600
開発生産性を上げるための生成AI活用術
starfish719
3
1.3k
Le côté obscur des IA génératives
pascallemerrer
0
150
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
230
Featured
See All Featured
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
How STYLIGHT went responsive
nonsquared
100
5.8k
Facilitating Awesome Meetings
lara
56
6.6k
Practical Orchestrator
shlominoach
190
11k
The Cost Of JavaScript in 2023
addyosmani
55
9k
Embracing the Ebb and Flow
colly
88
4.9k
A better future with KSS
kneath
239
18k
Raft: Consensus for Rubyists
vanstee
140
7.1k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.5k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.4k
Build your cross-platform service in a week with App Engine
jlugia
232
18k
KATA
mclloyd
PRO
32
15k
Transcript
Python Nordeste May 2nd 2014 Matt Robenolt Cheating Your Way
to #webscale
Hello < me irl
Lead Operations Engineer
Core Contributor
So what is #webscale?
10 million requests per second 4ms mean response time asynchronous
io mongodb
10 million requests per second 4ms mean response time asynchronous
io mongodb NOPE
Disqus only does 150 req/s per web server. * we
also write some bad code
150 12,960,000 388,800,000 per second per day per month real
world #webscale
Scale is about hiding the fact that your application is
actually really slow.
If your application feels fast, then it’s probably good enough.
Users hate waiting for shit.
So how do we do it?
Cheating 101
When a user asks for new data, let’s give them
old data instead.
When a user asks for new data, let’s give them
old data instead. Caching
When telling us to do something, let’s say we did
and maybe do it later.
When telling us to do something, let’s say we did
and maybe do it later. Queueing
Rule #1 Don’t get caught.
Rule #2 Don’t get caught.
Rule #3 Don’t get caught.
HTTP Caching
Introducing
tl;dr Varnish sits between your application and your users Internet
Let’s talk about HTTP. Hypertext Transport Protocol
$ curl -v disqus.com
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Request
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Method
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Path
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Version
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Headers
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Response
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Status
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Headers
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 For 300 seconds, all users will get the same response without talking to our application.
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 With power comes great responsibility.
GET / INTERNET Varnish Web servers
GET / INTERNET Varnish Web servers CACHED! “Cache-Control: max-age=300”
GET / INTERNET Varnish Web servers
GET / INTERNET Varnish Web servers CACHED!
BUT WAIT… THERE’S MORE
COLLAPSING REQUEST
GET / INTERNET Varnish Web servers
INTERNET Varnish Web servers GET /
INTERNET Varnish Web servers GET / If multiple users request
the same object, Varnish makes one fetch and returns to all users.
Queueing
Do as little work as possible, and return a promise
that this work will be done.
INTERNET Web servers Task workers Slow/Fast Data store Queue POST
/foo
INTERNET Web servers Task workers Slow/Fast Data store Queue POST
/foo
INTERNET Web servers Task workers Slow/Fast Data store Queue POST
/foo Workers can rate limit, debounce, increment counters, generate a fast materialized view, etc.
INTERNET Web servers Task workers Slow/Fast Data store Queue POST
/foo Make sure your tasks finish before a user tries to read the data back.
Final Thoughts
Understand your application. Where can you cheat without disrupting user
experience? Is seeing a few seconds old data going to damage a product?
Cheating should only enhance user experience.
Cheat any way you can, just don’t get caught.
Django & Varnish & RabbitMQ & Celery & PostgreSQL &
Redis & Cassandra & Riak Thanks
Questions? I have answers. ^ github.com/mattrobenolt @mattrobenolt some