220 likes | 361 Views
Making WordPress Scale . Mike “Wink” Van winkle wink@ wpengine.com www.wpengine.com www.mikevanwinkle.com @ mpvanwinkle. Who Dat ? . PHP Developer Not a sysadmin Former Freelancer Former Hobbiest Beer Enthusiast Cubs Fan. What is “scaling”?. What is Scaling?.
E N D
Making WordPress Scale Mike “Wink” Van winkle wink@wpengine.com www.wpengine.com www.mikevanwinkle.com @mpvanwinkle
Who Dat? PHP Developer Not a sysadmin Former Freelancer Former Hobbiest Beer Enthusiast Cubs Fan
What is Scaling? My Definition: Handling rapid traffic growth without feeling like Luke. Maintaining performance at various levels of usage? Achieving resource elasticity?
Vertical / Horizontal / WTF Primarily a topic for organization with lots of resources Vertical scaling focuses on increasing the server(s) dedicated to requests Horizontal scaling focuses on distributing different requests to different servers/configurations You need to do both.
When Do I Worry About Scale? Question: How big is big? When will my site break? Answer: “Depends”
Scaling Secret Crappy Code Doesn’t Scale! Just because you love your code doesn’t mean it’s code that will scale Mission Creep
Of Course Sometimes … SELECT wp_posts.* FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) INNER JOIN wp_postmeta AS mt2 ON (wp_posts.ID = mt2.post_id) INNER JOIN wp_postmeta AS mt3 ON (wp_posts.ID = mt3.post_id) INNER JOIN wp_postmeta AS mt4 ON (wp_posts.ID = mt4.post_id) INNER JOIN wp_postmeta AS mt5 ON (wp_posts.ID = mt5.post_id) INNER JOIN wp_postmeta AS mt6 ON (wp_posts.ID = mt6.post_id) INNER JOIN wp_postmeta AS mt7 ON (wp_posts.ID = mt7.post_id) INNER JOIN wp_postmeta AS mt8 ON (wp_posts.ID = mt8.post_id) INNER JOIN wp_postmeta AS mt9 ON (wp_posts.ID = mt9.post_id) INNER JOIN wp_postmeta AS mt10 ON (wp_posts.ID = mt10.post_id) INNER JOIN wp_postmeta AS mt11 ON (wp_posts.ID = mt11.post_id) INNER JOIN wp_postmeta AS mt12 ON (wp_posts.ID = mt12.post_id) INNER JOIN wp_postmeta AS mt13 ON (wp_posts.ID = mt13.post_id) INNER JOIN wp_postmeta AS mt14 ON (wp_posts.ID = mt14.post_id) INNER JOIN wp_postmeta AS mt15 ON (wp_posts.ID = mt15.post_id) INNER JOIN wp_postmeta AS mt16 ON (wp_posts.ID = mt16.post_id) INNER JOIN wp_postmeta AS mt17 ON (wp_posts.ID = mt17.post_id) INNER JOIN wp_postmeta AS mt18 ON (wp_posts.ID = mt18.post_id) INNER JOIN wp_postmeta AS mt19 ON (wp_posts.ID = mt19.post_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (5) ) AND wp_posts.post_type = ’category' AND (wp_posts.post_status = 'publish') AND ( (wp_postmeta.meta_key = 'cp_year' AND CAST(wp_postmeta.meta_value AS CHAR) BETWEEN '1999' AND '2000') AND (mt1.meta_key = 'cp_year' AND CAST(mt1.meta_value AS CHAR) BETWEEN '1999' AND '2000') AND (mt2.meta_key = 'cp_year' AND CAST(mt2.meta_value AS CHAR) BETWEEN '1999' AND '2000') … [ more stuff ] AND (mt19.meta_key = 'cp_year' AND CAST(mt19.meta_value AS CHAR) BETWEEN '1999' AND '2000') ) AND post_content LIKE '%%' GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC
Something’s Don’t Scale • Something’s work well on a small scale but not so well on a bigger one • query_posts(“s=s”); • wp_list_categories(); • query_posts(array(meta_query => array( ten different meta/key pairs)); • BuddyPress
Scaling Secrets • It’s impossible to scale “seemlessly” • You will have to make sacrifices • You will have to make mistakes • Scaling is not a plugin. • Scaling is not a formula.
Scaling Tricks? There aren’t any … not entirely true Scaling takes resources. Servers are important but no server environment is going to save you from your self.
CDN’s Rock Content Delivery Network Doesn’t Just Help with Speed Reduces the number of requests that have to be made to YOUR server. Can get expensive though.
Caching is a Must functionget_template_part_cached($slug,$name, $key = null, $group = ‘posts’, $ttl = 3600) { if( !$output = wp_cache_get($key, $group)) { ob_start(); get_template_part(‘loop’,’index’); $output = ob_end_clean(); ob_end_clean(); wp_cache_set( $key, $output, $group, $ttl ); } echo $output; } Caching must be something you think about in every line of code you write Cache raw html …
Caching is a Must get_template_part(‘index’,’loop’); Becomes … get_template_part_cached(‘index’,’loop’,’home-query’,’posts’, 6000); Caching must be something you think about in every line of code you write Cache raw html …
Scaling Secret • Leverage the object cache • Non-file based if possible • APC, xCache for dedicate servers • Memcached for multiple server environment
Know Your Content Know your content! Every site has some content that can be heavily cached and other content that cannot Even highly dynamic BuddyPress sites still have some opportunities for caching … member profiles … group listings
Know Your Plugins • How many plugins do you have installed? How many do you really NEEEEEEED. • Look out for plugins that have to query on every page load. • WP Post Views is a GREAT plugin until you’re getting several hundred an hour. • Look out for related-post plugins and “smart tags”.
NGINX NGINX is an HTTP server that handle basic delivery of Images, Documents and HTML with greater efficiency than Apache. Can be configured to run with Apache to handle back end requests http://kbeezie.com/view/apache-with-nginx/
Share the load • Fragmentation • Third Party Services where possible • Jetpack • Google-Analytics • nRelate for Related Posts • Google Custom Search !!! • Smush.It • CDN
Reduce Queries Cache as much as you can Use HyperDB to distribute database read and write functions to masters and slaves (requires MySQL replication) DB Cache Reloaded Plugin W3 Total Cache DB Cache Log-slow-queries = /var/log/mysql/slow-queries.log
Caching Plugins W3 Total Cache – Probably the most used Mark Jaquith’s APC Object Cache Batcache WP Super Cache
Other Resources Blitz.io http://www.wpengine.com/speedtest https://developers.google.com/speed/pagespeed/ http://developer.yahoo.com/yslow/