varnish cache and django (falcon, flask etc)

42
django acceleration with Varnish

Upload: -

Post on 15-Apr-2017

526 views

Category:

Technology


5 download

TRANSCRIPT

Page 1: Varnish Cache and Django (Falcon, Flask etc)

djangoacceleration with Varnish

Page 2: Varnish Cache and Django (Falcon, Flask etc)

django meets requestIntroduction1.

Page 3: Varnish Cache and Django (Falcon, Flask etc)

django meets requestIntroduction1.

Page 4: Varnish Cache and Django (Falcon, Flask etc)

Django Framework Architecture

RDBMS

ORM

Model

Storage

View

Template

Template Loader

FormsSignals

Middleware

Request

Middleware

URL Resolver

Response

Page 5: Varnish Cache and Django (Falcon, Flask etc)

HTTP Request

GET /wiki/HTTP HTTP/1.1 Host: ru.wikipedia.org Cookie: name=value

Page 6: Varnish Cache and Django (Falcon, Flask etc)

HTTP Request and Response

HTTP/1.1 200 OK Version: HTTP/1.1 Age: 165734 Last-Modified: Wed, 30 Mar 2016 20:48:23 GMT Cache-Control: private, s-maxage=0, max-age=0, must-revalidate Content-Encoding: gzip Content-Language: ru Content-Length: 50565 Content-Type: text/html; charset=UTF-8 Date: Fri, 01 Apr 2016 18:50:51 GMT Server: Apache Status: 200 OK Vary: Accept-Encoding,Cookie,Authorization Via: 1.1 varnish, 1.1 varnish X-Cache: cp1052 miss(0), cp3033 hit(4), cp3032 frontend hit(185) Set-Cookie: name=value

(Body Content)

GET /wiki/HTTP HTTP/1.1 Host: ru.wikipedia.org Cookie: name=value

Page 7: Varnish Cache and Django (Falcon, Flask etc)

Application Architecture

nginx

uWSGI

django-app

database

Request Response

Page 8: Varnish Cache and Django (Falcon, Flask etc)

Application Architecture with Varnish

nginx

uWSGI

django-app

Varnish

uWSGI

django-app

database

GET, HEAD

Request Response

Page 9: Varnish Cache and Django (Falcon, Flask etc)

we meet VarnishAcquaintance2.

Page 10: Varnish Cache and Django (Falcon, Flask etc)

Varnish

Reverse HTTP Proxy In-memory time based cache Varnish cache is key-value store Big “state” machine Load balancing (backend health check)

Page 11: Varnish Cache and Django (Falcon, Flask etc)

By Default

Cacheable methods: GET, HEAD Cacheable response codes:

- 200, 203 - 300, 301, 302 - 404, 410

Requests without cookies Default key: req.url + req.http.host

Page 12: Varnish Cache and Django (Falcon, Flask etc)

Varnish Configuration Language

The VCL is a small domain-specific language designed to be used to define request handling and document caching policies for the Varnish HTTP accelerator.

Page 13: Varnish Cache and Django (Falcon, Flask etc)

Varnish State Machine

request

vcl_recv

vcl_hash

vcl_hit

vcl_pass

vcl_miss

vcl_deliver

response

vcl_backend_fetch

vcl_backend_response

backend

Page 14: Varnish Cache and Django (Falcon, Flask etc)

vcl_recv routine

request

vcl_recv

vcl_hash

vcl_hit

vcl_pass

vcl_miss

vcl_deliver

response

vcl_backend_fetch

vcl_backend_response

backend

Page 15: Varnish Cache and Django (Falcon, Flask etc)

vcl_recv routine

Request normalization Request transformation (GET, Cookies) Document caching policies Load balancing Health checking Access control (synth(403) on BAN from WAN).

Page 16: Varnish Cache and Django (Falcon, Flask etc)

vcl_recv routinesub vcl_recv { unset req.http.User-Agent;

if (req.method != "GET" && req.method != "HEAD") { return (pass); }

if (req.http.Authorization) { return (pass); # Not cacheable by default } // Some people, when confronted with a problem, think // “I know, I'll use regular expressions." - Now they have two problems.

if (req.http.Cookie ~ "sessionid") { set req.http.x-sessionid = regsub( req.http.Cookie,"^.*?sessionid=([^;]*);*.*$" , "\1" ); } }

Page 17: Varnish Cache and Django (Falcon, Flask etc)

vcl_hash routine

request

vcl_recv

vcl_hash

vcl_hit

vcl_pass

vcl_miss

vcl_deliver

response

vcl_backend_fetch

vcl_backend_response

backend

Page 18: Varnish Cache and Django (Falcon, Flask etc)

vcl_hash

# The data on which the hashing will take place sub vcl_hash {

hash_data(req.url);

if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); }

# hash cookies for requests that have them if (req.http.Cookie) { hash_data(req.http.Cookie); } }

Page 19: Varnish Cache and Django (Falcon, Flask etc)

vcl_backend_fetch and vcl_backend_response routines

request

vcl_recv

vcl_hit

vcl_pass

vcl_miss

vcl_deliver

response

vcl_backend_fetch

vcl_backend_response

backend

vcl_hash

Page 20: Varnish Cache and Django (Falcon, Flask etc)

Backend configuration

backend server1 { # Define one backend .host = "127.0.0.1"; # IP or Hostname of backend .port = "80"; # Backend Port .max_connections = 300; # That’s it

.probe = { #.url = "/"; # short easy way (GET /) # We prefer to only do a HEAD / .request = "HEAD / HTTP/1.1" "Host: localhost" "Connection: close" "User-Agent: Varnish Health Probe";

.interval = 5s; # check the health of each backend every 5 seconds .timeout = 1s; # timing out after 1 second. .window = 5; # If 3 out of the last 5 polls succeeded the backend is considered healthy, otherwise it will be marked as sick .threshold = 3; }

.first_byte_timeout = 300s; # How long to wait before we receive a first byte from our backend? .connect_timeout = 1s; # How long to wait for a backend connection? .between_bytes_timeout = 2s; # How long to wait between bytes received from our backend? }

Page 21: Varnish Cache and Django (Falcon, Flask etc)

vcl_backend_fetch and vcl_backend_response routines

sub vcl_backend_response {

if (beresp.http.X-Varnish-TTL) { set beresp.ttl = std.duration( beresp.http.X-Varnish-TTL + "s", 120s); } else { set beresp.uncacheable = true; }

# Add debug info to response set beresp.http.X-Debug-Backend = beresp.backend.name; set beresp.http.X-Debug-Now = now; set beresp.http.X-Debug-TTL = beresp.ttl; set beresp.http.X-Debug-Cookie = beresp.http.Cookie; set beresp.http.X-Debug-Set-Cookie = beresp.http.Set-Cookie;

# Turn on ESI set beresp.do_esi = true; } }

Page 22: Varnish Cache and Django (Falcon, Flask etc)

Varnish State Machine

request

vcl_recv

vcl_hash

vcl_hit

vcl_pass

vcl_miss

vcl_deliver

response

vcl_backend_fetch

vcl_backend_response

backend

Page 23: Varnish Cache and Django (Falcon, Flask etc)

two hard things in CSСache invalidation2.1

Page 24: Varnish Cache and Django (Falcon, Flask etc)

“There are only two hard things in Computer Science: cache invalidation and naming things.

— Phil Karlton

Page 25: Varnish Cache and Django (Falcon, Flask etc)

Cache invalidation

acl admin { # ACL we will use later to allow purges "localhost"; "127.0.0.1"; }

sub vcl_recv { # Purge cache by url if (req.method == "PURGE") { if (client.ip ~ local) { return(purge); } else { return(synth(403, "Forbidden.")); } } }

Page 26: Varnish Cache and Django (Falcon, Flask etc)

Cache invalidation

sub vcl_recv { # Ban cache by pattern if (req.method == "BAN") { if (!client.ip ~ local) { return(synth(403, "Forbidden.")); } ban("obj.http.X-URL ~ " + req.url); # req.url is a regex return(synth(200, "Ban added")); } }

Page 27: Varnish Cache and Django (Falcon, Flask etc)

Cache invalidation

!→ ˜ curl -X PURGE http://worldofwarships.ru/news/itgm-7.html

!→ ˜ curl -X BAN http://worldofwarhips.ru/news/\*

Page 28: Varnish Cache and Django (Falcon, Flask etc)

Cache invalidationdef send_ban(url): """Issue a HTTP request with BAN method to Varnish :param url: a path or regexp to ban (invalidate) :return: None """ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect((varnish_settings.HOST, varnish_settings.PORT)) except socket.error: logger.exception('Varnish not available') else: sock.sendall("BAN %s HTTP/1.1\r\nHost: %s\r\n\r\n" % ( url, varnish_settings.HOST )) http_status, body = response.split("\n", 1) _, status, text = http_status.split(" ", 2) if status == "%s" % httplib.OK: pass finally: sock.close()

Page 29: Varnish Cache and Django (Falcon, Flask etc)

Cookies

By default Varnish don't cache requests with CookiesBut!

Page 30: Varnish Cache and Django (Falcon, Flask etc)

Cookies

request

vcl_recv

vcl_hash

vcl_hit

vcl_pass

vcl_miss

vcl_deliver

response

vcl_backend_fetch

vcl_backend_response

backend

vcl_recv: cookies -> HTTP headers. vcl_hash: add headers to hash vcl_backend_fetch: restore cookie header

Page 31: Varnish Cache and Django (Falcon, Flask etc)

Grace period

Grace in the scope of Varnish means delivering otherwise expired objects when circumstances call for it. This can happen because: - The backend-director selected is down; - A different thread has already made a request to the backend that's not yet finished.

sub vcl_backend_response { set beresp.grace = 1d; }

Page 32: Varnish Cache and Django (Falcon, Flask etc)

ESI

Edge Side Includes language, which allows content assembly by HTTP surrogates

<html> <body> The time is: <esi:include src=“/cgi-bin/date.cgi"/> at this very moment. </body> </html>

#/cgi-bin/date.cgi #!/bin/sh

echo 'Content-type: text/html' echo '' date "+%Y-%m-%d %H:%M"

Page 33: Varnish Cache and Django (Falcon, Flask etc)
Page 34: Varnish Cache and Django (Falcon, Flask etc)

ESI

ESI

Page 35: Varnish Cache and Django (Falcon, Flask etc)

django meets VarnishIntegration3.

Page 36: Varnish Cache and Django (Falcon, Flask etc)

Django Integration

RDBMS

ORM

Model

Storage

View

Template

Template Loader

FormsSignals

Middleware

Response

Middleware

URL Resolver

Request

Page 37: Varnish Cache and Django (Falcon, Flask etc)

Django Integration

Function Based [email protected](cache_timeout=60) def mainpage_view(request, template_name="mainpage/index.html"): return HttpResponse(render_to_string(template_name))

class MainPageView(varnish.CacheControlMixin, TemplateView): cache_timeout = 60 template_name = 'mainpage/index.html'

Class Based View

Page 38: Varnish Cache and Django (Falcon, Flask etc)

Varnish utils4.

Page 39: Varnish Cache and Django (Falcon, Flask etc)

Utils

varnishncsa — presents them in the Apache / NCSA "combined" log format;

varnishstat — general statistics; varnishtop — presents a continuously updated list of

the most commonly occurring log entries; varnishhist — presents a continuously updated

histogram showing the distribution of the last N requests by their processing.

Page 40: Varnish Cache and Django (Falcon, Flask etc)

Varnishhist

Page 41: Varnish Cache and Django (Falcon, Flask etc)

Сonclusion5.

๏ Django ๏ HTTP Request and Response ๏ Varnish Configuration Language ๏ Varnish State Machine ๏ Cache invalidate ๏ Django integration

Page 42: Varnish Cache and Django (Falcon, Flask etc)

Thank you!

Any questions?

You can find me at: @nonamenix [email protected]