from lamp to lnnp

28
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

Upload: giorgio-cefaro

Post on 18-May-2015

6.128 views

Category:

Technology


1 download

DESCRIPTION

A Brief overview on how to leave the good old LAMP stack in favour of a Linux Nginx NoSql stack

TRANSCRIPT

Page 1: From LAMP to LNNP

From LAMP to LNNP

A Transition from

Linux Apache Mysql (mod_)PHP

to

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

Giorgio Cefarohttp://giorgiocefaro.com

@giorrrgio

Page 2: From LAMP to LNNP

L → Lfrom Linux to...Linux

Page 3: From LAMP to LNNP

(intentionally blank)

Page 4: From LAMP to LNNP

A → Nfrom Apache to Nginx

Page 5: From LAMP to LNNP

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

Page 6: From LAMP to LNNP
Page 7: From LAMP to LNNP

PHP Hello world benchmarks

Concurrency Level: 10Time taken for tests: 31.796 secondsComplete requests: 50000Failed requests: 0Write errors: 0Keep-Alive requests: 0Total transferred: 8450000 bytesHTML transferred: 550000 bytesRequests per second: 1572.54 [#/sec] (mean)Time per request: 6.359 [ms] (mean)Time per request: 0.636 [ms] (mean, across all concurrent requests)Transfer rate: 259.53 [Kbytes/sec] received

Concurrency Level: 10Time taken for tests: 18.646 secondsComplete requests: 50000Failed requests: 0Write errors: 0Keep-Alive requests: 49509Total transferred: 12928406 bytesHTML transferred: 550000 bytesRequests per second: 2681.54 [#/sec] (mean)Time per request: 3.729 [ms] (mean)Time per request: 0.373 [ms] (mean, across all concurrent requests)Transfer rate: 677.11 [Kbytes/sec] received

Ab -k -n 50000 -c 10 http://10.0.0.3/test.php

Load average: 4.38, 1.29, 0.46 Load average: 3.00, 0.89, 0.32

Page 8: From LAMP to LNNP

PHP Hello world benchmarks

Concurrency Level: 100Time taken for tests: 28.143 secondsComplete requests: 50000Failed requests: 0Write errors: 0Keep-Alive requests: 0Total transferred: 8450000 bytesHTML transferred: 550000 bytesRequests per second: 1776.66 [#/sec] (mean)Time per request: 56.285 [ms] (mean)Time per request: 0.563 [ms] (mean, across all concurrent requests)Transfer rate: 293.22 [Kbytes/sec] received

Concurrency Level: 100Time taken for tests: 18.398 secondsComplete requests: 50000Failed requests: 0Write errors: 0Keep-Alive requests: 49573Total transferred: 12931199 bytesHTML transferred: 550000 bytesRequests per second: 2717.69 [#/sec] (mean)Time per request: 36.796 [ms] (mean)Time per request: 0.368 [ms] (mean, across all concurrent requests)Transfer rate: 686.39 [Kbytes/sec] received

Ab -k -n 50000 -c 100 http://10.0.0.3/test.php

Load average: 13.70, 3.54, 1.20 Load average: 38.49, 10.07, 3.41

Page 9: From LAMP to LNNP

PHP Hello world benchmarks

Concurrency Level: 1000Time taken for tests: 64.339 secondsComplete requests: 50000Failed requests: 474 (Connect: 0, Receive: 0, Length: 474, Exceptions: 0)Write errors: 0Non-2xx responses: 474Total transferred: 8522996 bytesHTML transferred: 626314 bytesRequests 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

Completed 5000 requestsCompleted 10000 requestsCompleted 15000 requestsapr_socket_recv: Connection reset by peer (104)Total of 17522 requests completed

Ab -k -n 50000 -c 1000 http://10.0.0.3/test.php

Load average: 20.50, 7.13, 2.64 Load average: 36.86, 9.02, 3.03

Page 10: From LAMP to LNNP

Static HTML benchmarks

Concurrency Level: 10Time taken for tests: 14.023 secondsComplete requests: 50000Failed requests: 0Write errors: 0Total transferred: 10650000 bytesHTML transferred: 250000 bytesRequests per second: 3565.47 [#/sec] (mean)Time per request: 2.805 [ms] (mean)Time per request: 0.280 [ms] (mean, across all concurrent requests)Transfer rate: 741.65 [Kbytes/sec] received

Concurrency Level: 10Time taken for tests: 11.887 secondsComplete requests: 50000Failed requests: 0Write errors: 0Total transferred: 13950000 bytesHTML transferred: 250000 bytesRequests per second: 4206.43 [#/sec] (mean)Time per request: 2.377 [ms] (mean)Time per request: 0.238 [ms] (mean, across all concurrent requests)Transfer rate: 1146.09 [Kbytes/sec] received

ab -n 50000 -c 10 http://10.0.0.3/test.html

Page 11: From LAMP to LNNP

Static HTML benchmarks

Concurrency Level: 100Time taken for tests: 12.785 secondsComplete requests: 50000Failed requests: 0Write errors: 0Total transferred: 10650000 bytesHTML transferred: 250000 bytesRequests per second: 3910.97 [#/sec] (mean)Time per request: 25.569 [ms] (mean)Time per request: 0.256 [ms] (mean, across all concurrent requests)Transfer rate: 813.51 [Kbytes/sec] received

Concurrency Level: 100Time taken for tests: 11.875 secondsComplete requests: 50000Failed requests: 0Write errors: 0Total transferred: 13950000 bytesHTML transferred: 250000 bytesRequests per second: 4210.42 [#/sec] (mean)Time per request: 23.751 [ms] (mean)Time per request: 0.238 [ms] (mean, across all concurrent requests)Transfer rate: 1147.17 [Kbytes/sec] received

ab -n 50000 -c 100 http://10.0.0.3/test.html

Page 12: From LAMP to LNNP

Static HTML benchmarks

Concurrency Level: 100Time taken for tests: 12.785 secondsComplete requests: 50000Failed requests: 0Write errors: 0Total transferred: 10650000 bytesHTML transferred: 250000 bytesRequests per second: 3910.97 [#/sec] (mean)Time per request: 25.569 [ms] (mean)Time per request: 0.256 [ms] (mean, across all concurrent requests)Transfer rate: 813.51 [Kbytes/sec] received

Concurrency Level: 100Time taken for tests: 11.875 secondsComplete requests: 50000Failed requests: 0Write errors: 0Total transferred: 13950000 bytesHTML transferred: 250000 bytesRequests per second: 4210.42 [#/sec] (mean)Time per request: 23.751 [ms] (mean)Time per request: 0.238 [ms] (mean, across all concurrent requests)Transfer rate: 1147.17 [Kbytes/sec] received

ab -n 50000 -c 100 http://10.0.0.3/test.html

Page 13: From LAMP to LNNP

Static HTML benchmarks

Concurrency Level: 1000Time taken for tests: 4.915 secondsComplete requests: 10000Failed requests: 0Write errors: 0Total transferred: 2130000 bytesHTML transferred: 50000 bytesRequests per second: 2034.45 [#/sec] (mean)Time per request: 491.533 [ms] (mean)Time per request: 0.492 [ms] (mean, across all concurrent requests)Transfer rate: 423.18 [Kbytes/sec] received

Completed 1000 requestsCompleted 2000 requestsCompleted 3000 requestsCompleted 4000 requestsCompleted 5000 requestsCompleted 6000 requestsCompleted 7000 requestsCompleted 8000 requestsCompleted 9000 requestsapr_socket_recv: Connection reset by peer (104)Total of 9561 requests completed

ab -n 10000 -c 1000 http://10.0.0.3/test.html

Page 14: From LAMP to LNNP
Page 15: From LAMP to LNNP

M → Nfrom MySQL to NoSQL

Page 16: From LAMP to LNNP

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

Page 17: From LAMP to LNNP

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

Page 18: From LAMP to LNNP

P → Pfrom mod_Php to PHP-FPM

Page 19: From LAMP to LNNP

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

Page 20: From LAMP to LNNP

...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

Page 21: From LAMP to LNNP

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

Page 22: From LAMP to LNNP

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

Page 23: From LAMP to LNNP

Wanna try?Let's get our hands dirty

Page 24: From LAMP to LNNP

Hot to install Nginx + PHP-FPM on Ubuntu

sudo add-apt-repository ppa:nginx/stable

sudo apt-get update

sudo apt-get install nginx

sudo apt-get install php5-fpm php5-cgi

● Version 1.1.19 of nginx is included in the standard ubuntu 12.04 repo

● Unofficial PPA for current stable and development versions

Page 25: From LAMP to LNNP

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; }}

Page 26: From LAMP to LNNP

Installing MongoDB

● Available through the standard Ubuntu repo● 10gen repositories have fresher stable versions

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

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

#add to /etc/apt/sources.listdeb 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

Page 27: From LAMP to LNNP

Using Mongo: a simple example

Source: http://www.php.net/manual/en/mongo.tutorial.php

Page 28: From LAMP to LNNP

Useful links

Nginx:http://wiki.nginx.org/

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

PHP-FPMhttp://php-fpm.org/about/#why

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

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

PhpMoAdminhttp://www.phpmoadmin.com/

Mongohttp://php.net/manual/en/book.mongo.php