From LAMP to LNNP
              A Transition from

     Linux Apache Mysql (mod_)PHP
                     to

 Linux (what else?) Nginx Nosql PHP(-FPM)


              Giorgio Cefaro
           http://giorgiocefaro.com
                     @giorrrgio
L→L
from Linux to...Linux
(intentionally blank)
A→N
from Apache to Nginx
Vs



                            From Wikipedia:

Nginx uses an asynchronous event-driven approach to handling requests
    which can provide more predictable performance under high loads,
 in contrast to the Apache HTTP server model that defaults to a threaded
            or process-oriented approach to handling requests
PHP Hello world benchmarks
        Ab -k -n 50000 -c 10 http://10.0.0.3/test.php




Concurrency Level:      10               Concurrency Level:      10
Time taken for tests:   31.796 seconds   Time taken for tests:   18.646 seconds
Complete requests:      50000            Complete requests:      50000
Failed requests:        0                Failed requests:        0
Write errors:           0                Write errors:           0
Keep-Alive requests:    0                Keep-Alive requests:    49509
Total transferred:      8450000 bytes    Total transferred:      12928406 bytes
HTML transferred:       550000 bytes     HTML transferred:       550000 bytes
Requests per second:    1572.54          Requests per second:    2681.54
[#/sec] (mean)                           [#/sec] (mean)
Time per request:       6.359 [ms]       Time per request:       3.729 [ms]
(mean)                                   (mean)
Time per request:       0.636 [ms]       Time per request:       0.373 [ms]
(mean, across all concurrent requests)   (mean, across all concurrent requests)
Transfer rate:          259.53           Transfer rate:          677.11
[Kbytes/sec] received                    [Kbytes/sec] received


Load average: 4.38, 1.29, 0.46           Load average: 3.00, 0.89, 0.32
PHP Hello world benchmarks
        Ab -k -n 50000 -c 100 http://10.0.0.3/test.php




Concurrency Level:      100              Concurrency Level:      100
Time taken for tests:   28.143 seconds   Time taken for tests:   18.398 seconds
Complete requests:      50000            Complete requests:      50000
Failed requests:        0                Failed requests:        0
Write errors:           0                Write errors:           0
Keep-Alive requests:    0                Keep-Alive requests:    49573
Total transferred:      8450000 bytes    Total transferred:      12931199 bytes
HTML transferred:       550000 bytes     HTML transferred:       550000 bytes
Requests per second:    1776.66          Requests per second:    2717.69
[#/sec] (mean)                           [#/sec] (mean)
Time per request:       56.285 [ms]      Time per request:       36.796 [ms]
(mean)                                   (mean)
Time per request:       0.563 [ms]       Time per request:       0.368 [ms]
(mean, across all concurrent requests)   (mean, across all concurrent requests)
Transfer rate:          293.22           Transfer rate:          686.39
[Kbytes/sec] received                    [Kbytes/sec] received


Load average: 13.70, 3.54, 1.20          Load average: 38.49, 10.07, 3.41
PHP Hello world benchmarks
        Ab -k -n 50000 -c 1000 http://10.0.0.3/test.php




Concurrency Level:      1000             Completed 5000 requests
Time taken for tests:   64.339 seconds   Completed 10000 requests
Complete requests:      50000            Completed 15000 requests
Failed requests:        474              apr_socket_recv: Connection reset by
   (Connect: 0, Receive: 0, Length:      peer (104)
474, Exceptions: 0)                      Total of 17522 requests completed
Write errors:           0
Non-2xx responses:      474
Total transferred:      8522996 bytes
HTML transferred:       626314 bytes
Requests per second:    777.13 [#/sec]
(mean)
Time per request:       1286.778 [ms]
(mean)
Time per request:       1.287 [ms]
(mean, across all concurrent requests)
Transfer rate:          129.37
[Kbytes/sec] received

Load average: 20.50, 7.13, 2.64          Load average: 36.86, 9.02, 3.03
Static HTML benchmarks
        ab -n 50000 -c 10 http://10.0.0.3/test.html




Concurrency Level:      10               Concurrency Level:      10
Time taken for tests:   14.023 seconds   Time taken for tests:   11.887 seconds
Complete requests:      50000            Complete requests:      50000
Failed requests:        0                Failed requests:        0
Write errors:           0                Write errors:           0
Total transferred:      10650000 bytes   Total transferred:      13950000 bytes
HTML transferred:       250000 bytes     HTML transferred:       250000 bytes
Requests per second:    3565.47          Requests per second:    4206.43
[#/sec] (mean)                           [#/sec] (mean)
Time per request:       2.805 [ms]       Time per request:       2.377 [ms]
(mean)                                   (mean)
Time per request:       0.280 [ms]       Time per request:       0.238 [ms]
(mean, across all concurrent requests)   (mean, across all concurrent requests)
Transfer rate:          741.65           Transfer rate:          1146.09
[Kbytes/sec] received                    [Kbytes/sec] received
Static HTML benchmarks
        ab -n 50000 -c 100 http://10.0.0.3/test.html




Concurrency Level:      100              Concurrency Level:      100
Time taken for tests:   12.785 seconds   Time taken for tests:   11.875 seconds
Complete requests:      50000            Complete requests:      50000
Failed requests:        0                Failed requests:        0
Write errors:           0                Write errors:           0
Total transferred:      10650000 bytes   Total transferred:      13950000 bytes
HTML transferred:       250000 bytes     HTML transferred:       250000 bytes
Requests per second:    3910.97          Requests per second:    4210.42
[#/sec] (mean)                           [#/sec] (mean)
Time per request:       25.569 [ms]      Time per request:       23.751 [ms]
(mean)                                   (mean)
Time per request:       0.256 [ms]       Time per request:       0.238 [ms]
(mean, across all concurrent requests)   (mean, across all concurrent requests)
Transfer rate:          813.51           Transfer rate:          1147.17
[Kbytes/sec] received                    [Kbytes/sec] received
Static HTML benchmarks
        ab -n 50000 -c 100 http://10.0.0.3/test.html




Concurrency Level:      100              Concurrency Level:      100
Time taken for tests:   12.785 seconds   Time taken for tests:   11.875 seconds
Complete requests:      50000            Complete requests:      50000
Failed requests:        0                Failed requests:        0
Write errors:           0                Write errors:           0
Total transferred:      10650000 bytes   Total transferred:      13950000 bytes
HTML transferred:       250000 bytes     HTML transferred:       250000 bytes
Requests per second:    3910.97          Requests per second:    4210.42
[#/sec] (mean)                           [#/sec] (mean)
Time per request:       25.569 [ms]      Time per request:       23.751 [ms]
(mean)                                   (mean)
Time per request:       0.256 [ms]       Time per request:       0.238 [ms]
(mean, across all concurrent requests)   (mean, across all concurrent requests)
Transfer rate:          813.51           Transfer rate:          1147.17
[Kbytes/sec] received                    [Kbytes/sec] received
Static HTML benchmarks
        ab -n 10000 -c 1000 http://10.0.0.3/test.html




Concurrency Level:      1000             Completed 1000 requests
Time taken for tests:   4.915 seconds    Completed 2000 requests
Complete requests:      10000            Completed 3000 requests
Failed requests:        0                Completed 4000 requests
Write errors:           0                Completed 5000 requests
Total transferred:      2130000 bytes    Completed 6000 requests
HTML transferred:       50000 bytes      Completed 7000 requests
Requests per second:    2034.45          Completed 8000 requests
[#/sec] (mean)                           Completed 9000 requests
Time per request:       491.533 [ms]     apr_socket_recv: Connection reset by
(mean)                                   peer (104)
Time per request:       0.492 [ms]       Total of 9561 requests completed
(mean, across all concurrent requests)
Transfer rate:          423.18
[Kbytes/sec] received
M→N
from MySQL to NoSQL
NoSQL?
●   SQL, tables, relations, JOINS...

●   Just documents, graphs, key-value pairs.

●   Really useful when working with a huge quantity of data

●   Really useful when working with data that you want not staticly
    structured


●   Really useful for statistical or real-time analyses for growing list
    of elements
My NoSql choice: MongoDB
●    Data in MongoDB is stored in JSON-like documents

●    horizontal scalability, auto-sharding to distribute data across many
     nodes (auto balancing, easy scaling)

●    full consistency and transactional updates

●    Data integrity is guaranteed through journalling and replication

●    Supported by Doctrine2 through Mongo

●    Warning: not fully ACID* compliant (missing some transactional use
     cases)


    * atomicity, consistency, isolation, durability
P→P
from mod_Php to PHP-FPM
Apache with modphp works
               but...
●   Every apache forked process is fat with all its modules
    loaded, though before-fork code is shared among processes

●   PHP is part of the apache process itself

●   You have to load PHP even when you serve static files
    (server memory footprint)

●   You have to rely on a unique PHP version for all you apps
...we can do better: FastCGI PHP
●   Multiple versions of PHP, each executed by a different user

●   Reduces the memory footprint of your web server for static
    files

●   PHP can be executed on a separate machine
We can do even better! PHP-
               FPM
●   FastCGI Process Manager
●   PHP daemonization
    pid file, log file, setsid(), setuid(), setgid(), chroot()
●   Adaptive process spawning
    Dynamic number of processes, depending on the load
●   Worker level configuration
    uid/gid/chroot/environment and different php.ini for each worker
●   Logging stdout and stderr
●   Forcing the completion of process if set_time_limit() fails
Workers, Daemons, WTF?
●   At startup a configurable number of workers ar launched,
    waiting for requests

●   Once requests arrive if needed workers are spawned

●   Each worker serves a request

●   You can fine tune the behaviour to adapt it to your machine
Wanna try?
 Let's get our hands dirty
Hot to install Nginx + PHP-FPM on
                    Ubuntu
●   Version 1.1.19 of nginx is included in the standard ubuntu
    12.04 repo
●   Unofficial PPA for current stable and development versions




sudo add-apt-repository ppa:nginx/stable

sudo apt-get update

sudo apt-get install nginx

sudo apt-get install php5-fpm php5-cgi
A simple nginx host
                 configuration
#/etc/nginx/sites-available/default

server {
  listen          80;
  server_name     localhost;
  index           index.php;
  root            /var/www;
  location ~* .php$ {
     #prevent cgi.fix_pathinfo=1 security hole
    if (!-f $request_filename) {
      return 404;
    }
    fastcgi_pass 127.0.0.1:9000;
    include      fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param SERVER_NAME $host;
  }
}
Installing MongoDB
●   Available through the standard Ubuntu repo
●   10gen repositories have fresher stable versions

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10

#add to /etc/apt/sources.list
deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen

sudo apt-get update

sudo apt-get install mongodb-10gen

sudo apt-get install php5-mongo



●   Mongo is the 10gen-supported PHP driver for MongoDB
●   Missing phpMyAdmin? Try phpMoAdmin :-)
Using Mongo: a simple example




Source: http://www.php.net/manual/en/mongo.tutorial.php
Useful links
Nginx:
http://wiki.nginx.org/

Apache vs Nginx – deathmatch
http://www.discusswire.com/apache-vs-nginx-deathmatch/

PHP-FPM
http://php-fpm.org/about/#why

http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/

MongoDB
http://www.mongodb.org/display/DOCS/Ubuntu+and+Debian+packages

PhpMoAdmin
http://www.phpmoadmin.com/

Mongo
http://php.net/manual/en/book.mongo.php

From LAMP to LNNP

  • 1.
    From LAMP toLNNP A Transition from Linux Apache Mysql (mod_)PHP to Linux (what else?) Nginx Nosql PHP(-FPM) Giorgio Cefaro http://giorgiocefaro.com @giorrrgio
  • 2.
  • 3.
  • 4.
  • 5.
    Vs From Wikipedia: Nginx uses an asynchronous event-driven approach to handling requests which can provide more predictable performance under high loads, in contrast to the Apache HTTP server model that defaults to a threaded or process-oriented approach to handling requests
  • 7.
    PHP Hello worldbenchmarks Ab -k -n 50000 -c 10 http://10.0.0.3/test.php Concurrency Level: 10 Concurrency Level: 10 Time taken for tests: 31.796 seconds Time taken for tests: 18.646 seconds Complete requests: 50000 Complete requests: 50000 Failed requests: 0 Failed requests: 0 Write errors: 0 Write errors: 0 Keep-Alive requests: 0 Keep-Alive requests: 49509 Total transferred: 8450000 bytes Total transferred: 12928406 bytes HTML transferred: 550000 bytes HTML transferred: 550000 bytes Requests per second: 1572.54 Requests per second: 2681.54 [#/sec] (mean) [#/sec] (mean) Time per request: 6.359 [ms] Time per request: 3.729 [ms] (mean) (mean) Time per request: 0.636 [ms] Time per request: 0.373 [ms] (mean, across all concurrent requests) (mean, across all concurrent requests) Transfer rate: 259.53 Transfer rate: 677.11 [Kbytes/sec] received [Kbytes/sec] received Load average: 4.38, 1.29, 0.46 Load average: 3.00, 0.89, 0.32
  • 8.
    PHP Hello worldbenchmarks Ab -k -n 50000 -c 100 http://10.0.0.3/test.php Concurrency Level: 100 Concurrency Level: 100 Time taken for tests: 28.143 seconds Time taken for tests: 18.398 seconds Complete requests: 50000 Complete requests: 50000 Failed requests: 0 Failed requests: 0 Write errors: 0 Write errors: 0 Keep-Alive requests: 0 Keep-Alive requests: 49573 Total transferred: 8450000 bytes Total transferred: 12931199 bytes HTML transferred: 550000 bytes HTML transferred: 550000 bytes Requests per second: 1776.66 Requests per second: 2717.69 [#/sec] (mean) [#/sec] (mean) Time per request: 56.285 [ms] Time per request: 36.796 [ms] (mean) (mean) Time per request: 0.563 [ms] Time per request: 0.368 [ms] (mean, across all concurrent requests) (mean, across all concurrent requests) Transfer rate: 293.22 Transfer rate: 686.39 [Kbytes/sec] received [Kbytes/sec] received Load average: 13.70, 3.54, 1.20 Load average: 38.49, 10.07, 3.41
  • 9.
    PHP Hello worldbenchmarks Ab -k -n 50000 -c 1000 http://10.0.0.3/test.php Concurrency Level: 1000 Completed 5000 requests Time taken for tests: 64.339 seconds Completed 10000 requests Complete requests: 50000 Completed 15000 requests Failed requests: 474 apr_socket_recv: Connection reset by (Connect: 0, Receive: 0, Length: peer (104) 474, Exceptions: 0) Total of 17522 requests completed Write errors: 0 Non-2xx responses: 474 Total transferred: 8522996 bytes HTML transferred: 626314 bytes Requests per second: 777.13 [#/sec] (mean) Time per request: 1286.778 [ms] (mean) Time per request: 1.287 [ms] (mean, across all concurrent requests) Transfer rate: 129.37 [Kbytes/sec] received Load average: 20.50, 7.13, 2.64 Load average: 36.86, 9.02, 3.03
  • 10.
    Static HTML benchmarks ab -n 50000 -c 10 http://10.0.0.3/test.html Concurrency Level: 10 Concurrency Level: 10 Time taken for tests: 14.023 seconds Time taken for tests: 11.887 seconds Complete requests: 50000 Complete requests: 50000 Failed requests: 0 Failed requests: 0 Write errors: 0 Write errors: 0 Total transferred: 10650000 bytes Total transferred: 13950000 bytes HTML transferred: 250000 bytes HTML transferred: 250000 bytes Requests per second: 3565.47 Requests per second: 4206.43 [#/sec] (mean) [#/sec] (mean) Time per request: 2.805 [ms] Time per request: 2.377 [ms] (mean) (mean) Time per request: 0.280 [ms] Time per request: 0.238 [ms] (mean, across all concurrent requests) (mean, across all concurrent requests) Transfer rate: 741.65 Transfer rate: 1146.09 [Kbytes/sec] received [Kbytes/sec] received
  • 11.
    Static HTML benchmarks ab -n 50000 -c 100 http://10.0.0.3/test.html Concurrency Level: 100 Concurrency Level: 100 Time taken for tests: 12.785 seconds Time taken for tests: 11.875 seconds Complete requests: 50000 Complete requests: 50000 Failed requests: 0 Failed requests: 0 Write errors: 0 Write errors: 0 Total transferred: 10650000 bytes Total transferred: 13950000 bytes HTML transferred: 250000 bytes HTML transferred: 250000 bytes Requests per second: 3910.97 Requests per second: 4210.42 [#/sec] (mean) [#/sec] (mean) Time per request: 25.569 [ms] Time per request: 23.751 [ms] (mean) (mean) Time per request: 0.256 [ms] Time per request: 0.238 [ms] (mean, across all concurrent requests) (mean, across all concurrent requests) Transfer rate: 813.51 Transfer rate: 1147.17 [Kbytes/sec] received [Kbytes/sec] received
  • 12.
    Static HTML benchmarks ab -n 50000 -c 100 http://10.0.0.3/test.html Concurrency Level: 100 Concurrency Level: 100 Time taken for tests: 12.785 seconds Time taken for tests: 11.875 seconds Complete requests: 50000 Complete requests: 50000 Failed requests: 0 Failed requests: 0 Write errors: 0 Write errors: 0 Total transferred: 10650000 bytes Total transferred: 13950000 bytes HTML transferred: 250000 bytes HTML transferred: 250000 bytes Requests per second: 3910.97 Requests per second: 4210.42 [#/sec] (mean) [#/sec] (mean) Time per request: 25.569 [ms] Time per request: 23.751 [ms] (mean) (mean) Time per request: 0.256 [ms] Time per request: 0.238 [ms] (mean, across all concurrent requests) (mean, across all concurrent requests) Transfer rate: 813.51 Transfer rate: 1147.17 [Kbytes/sec] received [Kbytes/sec] received
  • 13.
    Static HTML benchmarks ab -n 10000 -c 1000 http://10.0.0.3/test.html Concurrency Level: 1000 Completed 1000 requests Time taken for tests: 4.915 seconds Completed 2000 requests Complete requests: 10000 Completed 3000 requests Failed requests: 0 Completed 4000 requests Write errors: 0 Completed 5000 requests Total transferred: 2130000 bytes Completed 6000 requests HTML transferred: 50000 bytes Completed 7000 requests Requests per second: 2034.45 Completed 8000 requests [#/sec] (mean) Completed 9000 requests Time per request: 491.533 [ms] apr_socket_recv: Connection reset by (mean) peer (104) Time per request: 0.492 [ms] Total of 9561 requests completed (mean, across all concurrent requests) Transfer rate: 423.18 [Kbytes/sec] received
  • 15.
  • 16.
    NoSQL? ● SQL, tables, relations, JOINS... ● Just documents, graphs, key-value pairs. ● Really useful when working with a huge quantity of data ● Really useful when working with data that you want not staticly structured ● Really useful for statistical or real-time analyses for growing list of elements
  • 17.
    My NoSql choice:MongoDB ● Data in MongoDB is stored in JSON-like documents ● horizontal scalability, auto-sharding to distribute data across many nodes (auto balancing, easy scaling) ● full consistency and transactional updates ● Data integrity is guaranteed through journalling and replication ● Supported by Doctrine2 through Mongo ● Warning: not fully ACID* compliant (missing some transactional use cases) * atomicity, consistency, isolation, durability
  • 18.
  • 19.
    Apache with modphpworks but... ● Every apache forked process is fat with all its modules loaded, though before-fork code is shared among processes ● PHP is part of the apache process itself ● You have to load PHP even when you serve static files (server memory footprint) ● You have to rely on a unique PHP version for all you apps
  • 20.
    ...we can dobetter: FastCGI PHP ● Multiple versions of PHP, each executed by a different user ● Reduces the memory footprint of your web server for static files ● PHP can be executed on a separate machine
  • 21.
    We can doeven better! PHP- FPM ● FastCGI Process Manager ● PHP daemonization pid file, log file, setsid(), setuid(), setgid(), chroot() ● Adaptive process spawning Dynamic number of processes, depending on the load ● Worker level configuration uid/gid/chroot/environment and different php.ini for each worker ● Logging stdout and stderr ● Forcing the completion of process if set_time_limit() fails
  • 22.
    Workers, Daemons, WTF? ● At startup a configurable number of workers ar launched, waiting for requests ● Once requests arrive if needed workers are spawned ● Each worker serves a request ● You can fine tune the behaviour to adapt it to your machine
  • 23.
    Wanna try? Let'sget our hands dirty
  • 24.
    Hot to installNginx + PHP-FPM on Ubuntu ● Version 1.1.19 of nginx is included in the standard ubuntu 12.04 repo ● Unofficial PPA for current stable and development versions sudo add-apt-repository ppa:nginx/stable sudo apt-get update sudo apt-get install nginx sudo apt-get install php5-fpm php5-cgi
  • 25.
    A simple nginxhost configuration #/etc/nginx/sites-available/default server { listen 80; server_name localhost; index index.php; root /var/www; location ~* .php$ { #prevent cgi.fix_pathinfo=1 security hole if (!-f $request_filename) { return 404; } fastcgi_pass 127.0.0.1:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SERVER_NAME $host; } }
  • 26.
    Installing MongoDB ● Available through the standard Ubuntu repo ● 10gen repositories have fresher stable versions sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10 #add to /etc/apt/sources.list deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen sudo apt-get update sudo apt-get install mongodb-10gen sudo apt-get install php5-mongo ● Mongo is the 10gen-supported PHP driver for MongoDB ● Missing phpMyAdmin? Try phpMoAdmin :-)
  • 27.
    Using Mongo: asimple example Source: http://www.php.net/manual/en/mongo.tutorial.php
  • 28.
    Useful links Nginx: http://wiki.nginx.org/ Apache vsNginx – deathmatch http://www.discusswire.com/apache-vs-nginx-deathmatch/ PHP-FPM http://php-fpm.org/about/#why http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/ MongoDB http://www.mongodb.org/display/DOCS/Ubuntu+and+Debian+packages PhpMoAdmin http://www.phpmoadmin.com/ Mongo http://php.net/manual/en/book.mongo.php