49
Top Ten List PHP and Web Application Performance Brian DeShong

Top ten-list

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Top ten-list

Top Ten ListPHP and Web Application Performance

Brian DeShong

Page 2: Top ten-list

Who am I?

• CrowdTwist; Director, Back End Development

• 14 years in the industry, 12 of those as a developer

• Primarily PHP, OSS stack

• ~3 years Mac, iOS

Page 3: Top ten-list

Tonight’s show

• I’ve been doing this a long time

• My tips for web application performance

• Some PHP-specific

• Others not

• Special guest stars!

Page 4: Top ten-list

#10

Tweak your realpath cache settings

Page 5: Top ten-list

What’s realpath cache?

• Cache of relative path to absolute path

• require_once ‘foo/bar.php’;• /home/www/lib/foo/bar.php

• Main PHP settings

• realpath_cache_size = “16K”• realpath_cache_ttl = “120”

Page 6: Top ten-list

How do you know it’s low?

$ strace -p [PID of an httpd process]

lstat("/home/web/personal-web/d5gtech.com/api/lib/Slim/Slim.php", {st_mode=S_IFREG|0664, st_size=45840, ...}) = 0lstat("/home/web/personal-web/d5gtech.com/api/lib/Slim", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0lstat("/home/web/personal-web/d5gtech.com/api/lib", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0lstat("/home/web/personal-web/d5gtech.com/api", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0lstat("/home/web/personal-web/d5gtech.com", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0lstat("/home/web/personal-web", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0lstat("/home/web", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0lstat("/home", {st_mode=S_IFLNK|0777, st_size=10, ...}) = 0

open("/mnt/homes/web/personal-web/d5gtech.com/api/lib/Slim/Slim.php", O_RDONLY) = 25fstat(25, {st_mode=S_IFREG|0664, st_size=45840, ...}) = 0fstat(25, {st_mode=S_IFREG|0664, st_size=45840, ...}) = 0fstat(25, {st_mode=S_IFREG|0664, st_size=45840, ...}) = 0mmap(NULL, 45840, PROT_READ, MAP_SHARED, 25, 0) = 0x7ffd5f89d000stat("/mnt/homes/web/personal-web/d5gtech.com/api/lib/Slim/Slim.php", {st_mode=S_IFREG|0664, st_size=45840, ...}) = 0munmap(0x7ffd5f89d000, 45840) = 0close(25) = 0

Page 7: Top ten-list

How to adjust it?

• Call realpath_cache_size()

• Is the value at or near the maximum?

• If so, increase it a bit

• Test again

• If your file paths don’t change often, make TTL value high

Page 8: Top ten-list

Some caveats

• Cache is maintained per-Apache process

• # of workers X cache size = total footprint of realpath cache

• I’ve never had to adjust this until a few months ago

Page 9: Top ten-list

#9

Whenever possible, use offline processing

Page 10: Top ten-list

Batch processing

• Don’t do expensive, error prone stuff in the web server

• Processing images

• Talking to third-party APIs

• Do them asynchronously, somewhere else!

• Low response time == better user experience

Page 11: Top ten-list

How to run them?

• CLI scripts

• Run them with crontab

• Write useful log files

• Gearman, messaging queue

• Allow expensive work to be done concurrently

Page 12: Top ten-list

#8

Write efficient SQL queries

Page 13: Top ten-list

Know your queries!

• Database is always your biggest bottleneck!

• What are queries doing to retrieve data?

• Are you hitting indexes?

• How many rows are you scanning?

• Select only what you need!

• Optimize!

• MySQL slow query log

Page 14: Top ten-list

MySQL: “book” table

mysql> select * from book;+----+----------------+--------------+| id | title | author |+----+----------------+--------------+| 1 | Fahrenheit 451 | Ray Bradbury || 2 | Bossypants | Tina Fey |+----+----------------+--------------+

Page 15: Top ten-list

MySQL: explain plan

mysql> explain select id, title, author from book where author = 'Tina Fey'\G************** 1. row ************** id: 1 select_type: SIMPLE table: book type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 2 Extra: Using where1 row in set (0.01 sec)

Page 16: Top ten-list

MySQL: add index

mysql> create index book_author_idx on book (author);Query OK, 2 rows affected (0.02 sec)Records: 2 Duplicates: 0 Warnings: 0

Page 17: Top ten-list

MySQL: now using index

mysql> explain select id, title, author from book where author = 'Tina Fey'\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: book type: refpossible_keys: book_author_idx key: book_author_idx key_len: 103 ref: const rows: 1 Extra: Using where1 row in set (0.00 sec)

Page 18: Top ten-list

#7

Don’t execute queries in loops

Page 19: Top ten-list

Don’t abuse your database!

• Have some method that runs a query?

• Easy to call it in a loop and forget

• More iterations, more queries!

• If you must, prepare once, bind and execute in a loop

• Next up, how to notice this early!

Page 20: Top ten-list

Example

<?phpclass DataManager{ public function getThingData(Thing $thing) { $sql = ‘select id, name, color from thing where id = :id’;

// execute and return }}

Page 21: Top ten-list

Example

<?php// $things = 50 objects in an array

foreach ($things as $thing){ $data = $dataManager>getThingData($thing);

// do something useful}

Page 22: Top ten-list

Easy to miss!

• ORMs can let you forget about what you’re really doing!

• Use your head -- catch this stuff early!

• If you need many records...

• Pass an array of IDs, etc.

• Perform a SELECT query with an IN clause

Page 23: Top ten-list

#6

Know what your application is doing

Page 24: Top ten-list

Things to keep tabs on

• Database queries that are run

• Cache operations that are performed

• Session / current user data

• System stats

Page 25: Top ten-list

FirePHP

• Log info, warn, error, etc. -- string messages

• Also organize data in tables

• ZF1: Zend_Db_Profiler_Firephp

• ZF2: Zend\Log\Writer\FirePhp

Page 26: Top ten-list

FirePHP

Page 27: Top ten-list

Other options

• Xdebug

• XHProf

• PHP extensions

• http://xdebug.org/

• Xhgui

• https://github.com/preinheimer/xhgui

Page 28: Top ten-list

#5

Use gzip compression on responses

Page 29: Top ten-list

Easy!

• Compresses the response before sending it

• Generally, all browsers support it

• Saves you a lot of bandwidth

• Compress plaintext

• text/html, text/plain, etc.

• Not much gain for binary formats

Page 30: Top ten-list

How to enable it?

Apache: mod_deflate

AddOutputFilterByType DEFLATE text/html text/plain text/xml

nginx: HttpGzipModule, HttpGzipStaticModule

gzip on;gzip_min_length 1000;gzip_proxied expired no-cache no-store private auth;gzip_types text/plain application/xml;

Page 31: Top ten-list

#4

Do not use .htaccess files

Page 32: Top ten-list

Don’t bother

• Apache checks all directories for .htaccess files

• This is not cheap!

• Parsed on every request, too!

• Define your Apache directives in config files

• httpd.conf, VirtualHost config

• Any config file parsed at Apache startup

Page 33: Top ten-list

Apache configuration

<VirtualHost *:80> ServerName foo.example.org DocumentRoot /home/www/public_html

<Directory /home/www/public_html> // AllowOverride AuthConfig AllowOverride None </Directory></VirtualHost>

Page 34: Top ten-list

#3

Cache all the data that you can

Page 35: Top ten-list

Common tools

• Memcached

• Redis

• APC

• MySQL query caching (meh)

Page 36: Top ten-list

Why?

• Avoid round-trips to your database

• Faster to retrieve data directly from RAM

• Still have some network overhead

• Memcached, easy to pool servers to scale

Page 37: Top ten-list

Code: PHP, Memcached

<?phpnamespace User;

class Retriever{ public function getUser($id) { $key = __METHOD__ . “-{$id}”;

if (($user = $this->cache->get($key)) === false) { // Get user data

$this->cache->put($key, $user, 3600); }

return $user; }}

Page 38: Top ten-list

Logical usage

Web server

Database

Internet

Web server

Web server

Load balancer

Memcached

Page 39: Top ten-list

#2

Use a content delivery network

Page 40: Top ten-list

What does a CDN do?

• Caches content on servers around the world

• When user requests content...

• Hits the POP closest to them

• POP serves back the content

• Or retrieves it from origin, if necessary

Page 41: Top ten-list

Services

• Amazon CloudFront

• Akamai SOLA Sphere

• EdgeCast

Page 42: Top ten-list

Infrastructure

Web server

Database

Internet

Web server

Web server

Load balancer

CloudFront

http://tctechcrunch2011.files.wordpress.com/2013/02/harlem-shake-cat-meme.png

Page 43: Top ten-list

#1

Use APC, and set apc.stat = 0

Page 44: Top ten-list

What is APC?

• “Alternative PHP Cache”

• Caches PHP code into bytecode

• Shared memory in Apache, php-fpm, etc.

• Saves you parsing time on requests

• You want this on a highly-trafficked site

• Can also store arbitrary values

Page 45: Top ten-list

Why APC?

• Less work for servers

• Faster response times!

• Happier users

• Cache data in it

• Database result sets

• Configuration settings, etc.

Page 46: Top ten-list

apc.stat = 0

• Set to 1 by default

• Forces APC to stat() the file on disk

• Make sure it hasn’t changed

• You don’t need this in Production!

• Your code should change infrequently

• When it does, purge your APC cache!

Page 47: Top ten-list

How does it help?

• I’ve personally seen 20%+ increases in requests per second

• This is huge!

• Not checking all files

• Makes a big difference under high traffic

Page 48: Top ten-list

That does it!

• We’ve covered a lot!

• I’ve amassed these tips over many years

• You all are (and will) be doing the same

• Share your learnings with the community!

Page 49: Top ten-list

[email protected]

http://www.deshong.net@bdeshong

[email protected]://www.crowdtwist.com/