Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
From LAMP to LNNP
1. 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
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
6.
7. 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
8. 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
9. 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
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
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
19. 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
20. ...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
21. 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
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
24. 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
25. 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;
}
}
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: a simple example
Source: http://www.php.net/manual/en/mongo.tutorial.php