Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scalability Issues: Cure now, prevent later

Thijs Feryn
November 29, 2012

Scalability Issues: Cure now, prevent later

Slides for my Future Of Web Apps talk about scalability in Prague.

Thijs Feryn

November 29, 2012
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

  1. rt_sigaction(SIGQUIT,  {0x7f11489295f0,  [QUIT],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [QUIT],  NULL,  8)  =

     0 rt_sigprocmask(SIG_BLOCK,  [TERM],  NULL,  8)  =  0 rt_sigaction(SIGTERM,  {0x7f11489295f0,  [TERM],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [TERM],  NULL,  8)  =  0 rt_sigprocmask(SIG_BLOCK,  [XCPU],  NULL,  8)  =  0 rt_sigaction(SIGXCPU,  {0x7f11489295f0,  [XCPU],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [XCPU],  NULL,  8)  =  0 rt_sigprocmask(SIG_BLOCK,  [XFSZ],  NULL,  8)  =  0 rt_sigaction(SIGXFSZ,  {0x7f11489295f0,  [XFSZ],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [XFSZ],  NULL,  8)  =  0 open("/proc/meminfo",  O_RDONLY)                  =  3 fstat(3,  {st_mode=S_IFREG|0444,  st_size=0,  ...})  =  0 mmap(NULL,  4096,  PROT_READ|PROT_WRITE,  MAP_PRIVATE|MAP_ANONYMOUS,  -­‐1,  0)  =  0x7f115022 read(3,  "MemTotal:                2097152  kB\nMemFr"...,  1024)  =  560 close(3)                                                                =  0 munmap(0x7f1150225000,  4096)                        =  0 getrlimit(RLIMIT_NOFILE,  {rlim_cur=1024,  rlim_max=1024})  =  0 brk(0x1ae1000)                                                    =  0x1ae1000 brk(0x1b02000)                                                    =  0x1b02000 socket(PF_FILE,  SOCK_STREAM,  0)                  =  3 fcntl(3,  F_SETFL,  O_RDWR|O_NONBLOCK)        =  0 connect(3,  {sa_family=AF_FILE,  path="/var/run/nscd/socket"...},  110)  =  -­‐1  ECONNREFUSE close(3)                                                                =  0 socket(PF_FILE,  SOCK_STREAM,  0)                  =  3 fcntl(3,  F_SETFL,  O_RDWR|O_NONBLOCK)        =  0 connect(3,  {sa_family=AF_FILE,  path="/var/run/nscd/socket"...},  110)  =  -­‐1  ECONNREFUSE close(3)                                                                =  0 open("/etc/services",  O_RDONLY|O_CLOEXEC)  =  3 fstat(3,  {st_mode=S_IFREG|0644,  st_size=18480,  ...})  =  0 System calls
  2. rt_sigaction(SIGQUIT,  {0x7f11489295f0,  [QUIT],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [QUIT],  NULL,  8)  =

     0 rt_sigprocmask(SIG_BLOCK,  [TERM],  NULL,  8)  =  0 rt_sigaction(SIGTERM,  {0x7f11489295f0,  [TERM],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [TERM],  NULL,  8)  =  0 rt_sigprocmask(SIG_BLOCK,  [XCPU],  NULL,  8)  =  0 rt_sigaction(SIGXCPU,  {0x7f11489295f0,  [XCPU],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [XCPU],  NULL,  8)  =  0 rt_sigprocmask(SIG_BLOCK,  [XFSZ],  NULL,  8)  =  0 rt_sigaction(SIGXFSZ,  {0x7f11489295f0,  [XFSZ],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [XFSZ],  NULL,  8)  =  0 open("/proc/meminfo",  O_RDONLY)                  =  3 fstat(3,  {st_mode=S_IFREG|0444,  st_size=0,  ...})  =  0 mmap(NULL,  4096,  PROT_READ|PROT_WRITE,  MAP_PRIVATE|MAP_ANONYMOUS,  -­‐1,  0)  =  0x7f115022 read(3,  "MemTotal:                2097152  kB\nMemFr"...,  1024)  =  560 close(3)                                                                =  0 munmap(0x7f1150225000,  4096)                        =  0 getrlimit(RLIMIT_NOFILE,  {rlim_cur=1024,  rlim_max=1024})  =  0 brk(0x1ae1000)                                                    =  0x1ae1000 brk(0x1b02000)                                                    =  0x1b02000 socket(PF_FILE,  SOCK_STREAM,  0)                  =  3 fcntl(3,  F_SETFL,  O_RDWR|O_NONBLOCK)        =  0 connect(3,  {sa_family=AF_FILE,  path="/var/run/nscd/socket"...},  110)  =  -­‐1  ECONNREFUSE close(3)                                                                =  0 socket(PF_FILE,  SOCK_STREAM,  0)                  =  3 fcntl(3,  F_SETFL,  O_RDWR|O_NONBLOCK)        =  0 connect(3,  {sa_family=AF_FILE,  path="/var/run/nscd/socket"...},  110)  =  -­‐1  ECONNREFUSE close(3)                                                                =  0 open("/etc/services",  O_RDONLY|O_CLOEXEC)  =  3 fstat(3,  {st_mode=S_IFREG|0644,  st_size=18480,  ...})  =  0
  3. Frontend Backend Data   cache Opcode   cache Page  

    cache APC Memcached SQLite File Redis +more +more
  4. APC

  5. backend default { .host = "127.0.0.1"; .port = "8080"; }

    acl purge { "localhost"; "127.0.0.1"; "some.host.name.com"; "1.2.3.4"; }
  6. sub vcl_recv { if (req.request == "PURGE") { if (!client.ip

    ~ purge) { error 405 "Not allowed: " + client.ip; } return(lookup); } if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") { return (pipe); }
  7. if (req.request != "GET" && req.request != "HEAD") { return

    (pass); } if (req.http.Accept-Encoding) { if (req.url ~ "\.(gif|jpg|jpeg|swf|flv|mp3|mp4| pdf|ico|png|gz|tgz|bz2)(\?.*|)$") { remove req.http.Accept-Encoding; } else if (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } else if (req.http.Accept-Encoding ~ "deflate"){ set req.http.Accept-Encoding = "deflate"; } else { remove req.http.Accept-Encoding; } }
  8. if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3| mp4|pdf|ico|png)(\?.*|)$") { unset req.http.cookie; set req.url

    = regsub(req.url, "\?.*$", ""); return (lookup); } if (req.url ~ "\?(utm_(campaign|medium|source|term)| adParams|client|cx|eid|fbid|feed|ref(id|src)?|v(er| iew))=") { set req.url = regsub(req.url, "\?.*$", ""); } if (req.http.cookie ~ "^ *$") { unset req.http.cookie; }
  9. sub vcl_fetch { if (req.url ~ "wp-(login|admin)" || req.url ~

    "preview=true" || req.url ~ "xmlrpc.php") { return (hit_for_pass); } if ( (!(req.url ~ "(wp-(login|admin)|login)"))) { unset beresp.http.set-cookie; set beresp.ttl = 1h; } if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3| mp4|pdf|ico|png)(\?.*|)$") { set beresp.ttl = 365d; } }
  10. sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache

    = "HIT"; } else { set resp.http.X-Cache = "MISS"; } } sub vcl_hit { if (req.request == "PURGE") { purge; set obj.ttl = 0s; error 200 "OK"; } } sub vcl_miss { if (req.request == "PURGE") { purge; error 200 "OK"; } }
  11. Blocking var  results  =  db.query("SELECT  *  FROM  tablename"); //use  results

      Non-­‐blocking db.query("SELECT  *  FROM  tablename"  ,  function  (results)  {   //use  results   });   //do  something  else  
  12. Example var  http  =  require('http'); http.createServer(function  (req,  res)  {  

     res.writeHead(200,  {'Content-­‐Type':  'text/plain'});    res.end('Hello  World\n'); }).listen(1337,  '127.0.0.1'); console.log('Server  running  at  http://127.0.0.1:1337/');
  13. Example <?php require 'vendor/autoload.php'; $app = function ($request, $response) {

    $response->writeHead(200, array('Content- Type' => 'text/plain')); $response->end("Hello World\n"); }; $loop = React\EventLoop\Factory::create(); $socket = new React\Socket\Server($loop); $http = new React\Http\Server($socket, $loop); $http->on('request', $app); echo "Server running at http://127.0.0.1:1337\n"; $socket->listen(1337); $loop->run();
  14. Websockets var conn = new WebSocket('ws:// some.host'); conn.onmessage = function(e)

    { console.log(e.data); }; conn.send('Hello World!'); Client
  15. <?php namespace MyApp; use Ratchet\MessageComponentInterface; use Ratchet\ConnectionInterface; class Chat implements

    MessageComponentInterface { protected $clients; public function __construct() { $this->clients = new \SplObjectStorage; } public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); } public function onMessage(ConnectionInterface $from, $msg) { foreach ($this->clients as $client) { if ($from !== $client) { $client->send('Response: '.$msg); } } } public function onClose(ConnectionInterface $conn) { $this->clients->detach($conn); } public function onError(ConnectionInterface $conn, \Exception $e) { echo "An error has occurred: {$e->getMessage()}\n"; $conn->close(); } }
  16. <?php require __DIR__.'/vendor/autoload.php'; require 'chat.php'; use Ratchet\WebSocket\WsServer; use Ratchet\Server\IoServer; use

    MyApp\Chat; $ws = new WsServer(new Chat()); $ws->disableVersion(0); $server = IoServer::factory($ws,80,'1.2.3.4'); $server->run();
  17. [www] listen = 9000 user = www-data group = www-data

    pm = dynamic pm.max_children = 10 pm.start_servers = 4 pm.max_spare_servers = 6 pm.max_requests = 500 php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f [email protected] php_flag[display_errors] = off php_admin_value[error_log] = /var/log/fpm-php.www.log php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 32M
  18. upstream fpm { server php1.server.com:9000; server php2.server.com:9000; } upstream memcached

    { server memcached1.server.com:11211; server memcached2.server.com:11211; } server { root /var/www; index index.php index.html index.htm; server_name nginx.server.com; location / { try_files $uri $uri/ /index.php; } location @php { fastcgi_pass fpm; fastcgi_index index.php; include fastcgi_params; }
  19. location ~ \.php$ { set $memcached_key $request_uri; memcached_pass memcached; memcached_next_upstream

    not_found; default_type text/html; error_page 404 405 502 = @php; } location ~* \.(?:ico|css|js|gif|jpe?g|png)$ { expires max; add_header Pragma public; add_header Cache-Control "public, must- revalidate, proxy-revalidate"; } }
  20. # Reverse Worker Code $worker= new GearmanWorker(); $worker->addServer(); $worker->addFunction("reverse", "my_reverse_function");

    while ($worker->work()); function my_reverse_function($job) { return strrev($job->workload()); } # Reverse Client Code $client= new GearmanClient(); $client->addServer(); print $client->do("reverse", "Hello World!");