cache money business

76
Cache Money Business Mark Jaquith “JAKE-with” @markjaquith [email protected] markjaquith.com @markjaquith #wcldn

Upload: mark-jaquith

Post on 14-Jul-2015

2.008 views

Category:

Software


0 download

TRANSCRIPT

Cache Money Business

Mark Jaquith“JAKE-with”

@markjaquith [email protected] markjaquith.com

@markjaquith #wcldn

@markjaquith #wcldn

@markjaquith #wcldn

@markjaquith #wcldn

$CA£ING@markjaquith #wcldn

Caching storing data for future use

@markjaquith #wcldn

More Cache Fewer Problems

@markjaquith #wcldn

Caching Principles

@markjaquith #wcldn

DO LESS WORK

@markjaquith #wcldn

DO LESS WORK

@markjaquith #wcldn

WORK LESS OFTE

N

WORK LESS OFTEN

$TTL = 5400; $TTL = 900;

@markjaquith #wcldn

MAKE GENERIC OUTPUT

@markjaquith #wcldn

Cache the whole page

@markjaquith #wcldn

Batcache

@markjaquith #wcldn

W3 Total Cache

@markjaquith #wcldn

WP Super Cache

@markjaquith #wcldn

Varnish or Nginx

@markjaquith #wcldn

CDN —

Content Distribution

Network

@markjaquith #wcldn

Nginx Cache Purging

labs.frickle.com/nginx_ngx_cache_purge/

@markjaquith #wcldn

location ~ \.php$ {

}

@markjaquith #wcldn

set $no_cache_set 0;set $no_cache_get 0;

@markjaquith #wcldn

if ( $http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) { set $no_cache_set 1; set $no_cache_get 1;}

@markjaquith #wcldn

# X-Nginx-Cache-Purge: 1# header will skip the cache!

if ( $http_x_nginx_cache_purge ) { set $no_cache_get 1;}

@markjaquith #wcldn

fastcgi_no_cache $no_cache_set;

fastcgi_cache_bypass $no_cache_get;

@markjaquith #wcldn

function nginx_purge_url( $url ) { wp_remote_get( $url, array( 'reject_unsafe_urls' => false, 'timeout' => 0.01, 'blocking' => false, 'headers' => array( 'X-Nginx-Cache-Purge' => '1' ) ));}

@markjaquith #wcldn

add_action( 'transition_post_status', 'nginx_purge_post', 10, 3);

function nginx_purge_post( $new, $old, $post ) { if ( 'publish' === $old || 'publish' === $new ) {

nginx_purge_url( get_permalink( $post ) ); }}

@markjaquith #wcldn

Variable cache lengths +

Proactive cache refreshing

@markjaquith #wcldn

add_action( 'template_redirect', 'cache_home_page_length);

function cache_home_page_length() { if ( ! is_user_logged_in() && is_home() ) { header( 'Cache-Control: public, max-age=300' ); }}

@markjaquith #wcldn

Logged in = no page caching?

@markjaquith #wcldn

¥€$@markjaquith #wcldn

How does the page vary?

@markjaquith #wcldn

1. Toolbar 2. Inline edit links 3. User's private posts 4. Moderated comments shown 5. Comment form

@markjaquith #wcldn

Remove these things —OR—

Make them generic

@markjaquith #wcldn

Comment form HIDE

@markjaquith #wcldn

Toolbar GONE

@markjaquith #wcldn

Inline edit links GONE

@markjaquith #wcldn

User's private posts GONE

@markjaquith #wcldn

Moderated comments GONE

@markjaquith #wcldn

Compare:

10 editors and 1000 subscribers view 5 pages

each

@markjaquith #wcldn

Caching skipped for logged in users:

5,050 dynamic views

@markjaquith #wcldn

Caching skipped for Editors and up only:

50 dynamic views 5000 cached views

@markjaquith #wcldn

Less than 1% of the workload as before!

@markjaquith #wcldn

What if the page really DOES need per user

customization?

e.g. "Howdy $username"

@markjaquith #wcldn

1. Load 2. Ajax if logged in 3. Customize

@markjaquith #wcldn

Um… cookies

@markjaquith #wcldn

1. Set JS-readable cookies 2. Get rid of the normal

ones 3. Populate the form with

JavaScript

@markjaquith #wcldn

Good news…

@markjaquith #wcldn

Cache Buddy github.com/markjaquith/cache-buddy

@markjaquith #wcldn

Cache WordPress

Objects

@markjaquith #wcldn

APCu (single server only)

— Memcache

— Redis

@markjaquith #wcldn

APCu WordPress.org/plugins/apc

— Memcache

WordPress.org/plugins/memcached

— Redis

WordPress.org/plugins/wp-redis

@markjaquith #wcldn

wp-content/object-cache.php

@markjaquith #wcldn

W3 Total Cache +

Batcache

@markjaquith #wcldn

Using Transients and the Object Cache

@markjaquith #wcldn

Transients vs

Object Caching

@markjaquith #wcldn

Transients use object caching, if available

Otherwise, the options table

@markjaquith #wcldn

The Object Cache API uses an object caching

backend, if available

Otherwise, in-process PHP memory

@markjaquith #wcldn

Transient API set_transient( $key, $data, $ttl )

get_transient( $key )

@markjaquith #wcldn

Object Cache API wp_cache_get( $key, $group )

wp_cache_set( $key, $data, $group, $ttl )

@markjaquith #wcldn

Avoiding Cache Stampedes and

Cold Caches

@markjaquith #wcldn

$item = get_transient('footer_item');if ( ! $item ) { // Some poor person has to WAIT $get = wp_remote_get( get_option( 'footer_url' ) ); if ( ! is_wp_error( $get ) ) { $item = wp_remote_retrieve_body( $get ); wp_set_transient( 'footer_item', $item, 300 ); } }echo $item;

@markjaquith #wcldn

TLC Transients —

bit.ly/tlc-transients

@markjaquith #wcldn

function fetch_footer_item() { $get = wp_remote_get( get_option( 'footer_url' ) ); if ( ! is_wp_error( $get ) ) { return wp_remote_retrieve_body( $get ); } else { return false; }}

echo tlc_transient('footer_item') ->update_with('fetch_footer_item') ->expires_in(300) ->background_only() ->get();

@markjaquith #wcldn

Cache HTML Fragments

— bit.ly/fragment-cache

@markjaquith #wcldn

$fragment = new CWS_Fragment_Cache( 'unique-key', 3600);

if ( ! $fragment->output() ) { // START functions_that_do_stuff_live(); these_should_echo(); // END $fragment->store();}

@markjaquith #wcldn

In review

@markjaquith #wcldn

Caching for speed —

Caching for scale

@markjaquith #wcldn

Less work —

Generic output

@markjaquith #wcldn

Cache the whole page

@markjaquith #wcldn

Think Nginx and Varnish, not PHP caching solutions

@markjaquith #wcldn

Check out my whacky new plugin

github.com/markjaquith/cache-buddy

@markjaquith #wcldn

Use Object Caching

@markjaquith #wcldn

Leverage Transients (or maybe the Object Cache directly)

@markjaquith #wcldn

Stampedes are bad

@markjaquith #wcldn

Cache expensive, reusable HTML

fragments

@markjaquith #wcldn

Q A(if we have time, which we probably do not)

&@markjaquith #wcldn