Caching and tuning fun for high scalability

6,746 views

Published on

Caching has been a 'hot' topic for a few years. But caching takes more than merely taking data and putting it in a cache : the right caching techniques can improve performance and reduce load significantly. But we'll also look at some major pitfalls, showing that caching the wrong way can bring down your site.

If you're looking for a clear explanation about various caching techniques and tools like Memcached, Nginx and Varnish, as well as ways to deploy them in an efficient way, this talk is for you.

Published in: Technology
0 Comments
11 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,746
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
0
Comments
0
Likes
11
Embeds 0
No embeds

No notes for slide

Caching and tuning fun for high scalability

  1. 1. Caching and tuning fun for high scalability Wim Godden Cu.be Solutions
  2. 2. Notes about this presentation <ul>This presentation was presented at Dyncon 2011. It was designed to be presented live and as a result, many of the slides may seem odd when just looking at them without the spoken explanations. Also, the presentation had live benchmarks, which are ofcourse not present in the slides. </ul>
  3. 3. Who am I ? <ul><li>Wim Godden (@wimgtr)
  4. 4. Owner of Cu.be Solutions (http://cu.be)
  5. 5. PHP developer since 1997
  6. 6. Developer of OpenX
  7. 7. Zend Certified Engineer
  8. 8. Zend Framework Certified Engineer
  9. 9. MySQL Certified Developer </li></ul>
  10. 10. Who are you ? <ul><li>Developers ?
  11. 11. System/network engineers ?
  12. 12. Managers ?
  13. 13. Caching experience ? </li></ul>
  14. 14. Caching and tuning fun for high scalability Wim Godden Cu.be Solutions
  15. 15. Goals of this tutorial <ul><li>Everything about caching and tuning
  16. 16. A few techniques </li><ul><li>How-to
  17. 17. How-NOT-to </li></ul><li>-> Increase reliability, performance and scalability
  18. 18. 5 visitors/day -> 5 million visitors/day
  19. 19. (Don't expect miracle cure !) </li></ul>
  20. 20. LAMP
  21. 21. LAMP
  22. 22. Architecture
  23. 23. Our test site
  24. 24. Our base benchmark <ul><li>Apachebench = useful enough
  25. 25. Result ? </li></ul>
  26. 26. Caching
  27. 27. What's caching ?
  28. 28. What is caching ? select * from article join user on article.user_id = user.id order by created desc limit 10
  29. 29. Caching goals <ul><li>Source of information : </li><ul><li>Reduce # of request
  30. 30. Reduce the load </li></ul><li>Latency : </li><ul><li>Reduce for visitor
  31. 31. Reduce for Webserver load </li></ul><li>Network : </li><ul><li>Send less data to visitor
  32. 32. Hey, that's frontend ! </li></ul></ul>
  33. 33. Theory of caching DB
  34. 34. Theory of caching DB
  35. 35. Caching techniques <ul>#1 : Store entire pages <li>Company Websites
  36. 36. Blogs
  37. 37. Full pages that don't change
  38. 38. Render -> Store in cache -> retrieve from cache </li></ul>
  39. 39. Caching techniques <ul>#1 : Store entire pages </ul>
  40. 40. Caching techniques <ul>#2 : Store parts of a page <li>Most common technique
  41. 41. Usually a small block in a page
  42. 42. Best effect : reused on lots of pages </li></ul>
  43. 43. Caching techniques <ul>#2 : Store parts of a page </ul>
  44. 44. Caching techniques <ul>#3 : Store SQL queries <li>↔ SQL query cache </li><ul><ul><li>Limited in size </li></ul></ul></ul>
  45. 45. Caching techniques <ul>#3 : Store SQL queries <li>↔ SQL query cache </li><ul><ul><li>Limited in size
  46. 46. Resets on every insert/update/delete
  47. 47. Server and connection overhead </li></ul></ul><li>Goal : </li><ul><li>not to get rid of DB
  48. 48. free up DB resources for more hits ! </li></ul></ul>
  49. 49. Caching techniques <ul>#3 : Store SQL queries </ul>
  50. 50. Caching techniques <ul>#4 : Store complex processing results <li>Not just calculations
  51. 51. CPU intensive tasks : </li><ul><li>Config file parsing
  52. 52. XML file parsing
  53. 53. Loading CSV in an array </li></ul><li>Save resources -> more resources available </li></ul>
  54. 54. Caching techniques <ul>#4 : Store complex processing results </ul>
  55. 55. Caching techniques <ul>#xx : Your call Only limited by your imagination ! When you have data, think : <li>Creating time ?
  56. 56. Modification frequency ?
  57. 57. Retrieval frequency ? </li></ul>
  58. 58. How to find cacheable data <ul><li>New projects : start from 'cache everything'
  59. 59. Existing projects : </li><ul><li>Look at MySQL slow query log
  60. 60. Make a complete query log (don't forget to turn it off !)
  61. 61. Check page loading times </li></ul></ul>
  62. 62. Caching storage - MySQL query cache <ul><li>Use it
  63. 63. Don't rely on it
  64. 64. Good if you have : </li><ul><li>lots of reads
  65. 65. few different queries </li></ul><li>Bad if you have : </li><ul><li>lots of insert/update/delete
  66. 66. lots of different queries </li></ul></ul>
  67. 67. Caching storage - Disk <ul><li>Data with few updates : good
  68. 68. Caching SQL queries : preferably not
  69. 69. DON'T use NFS or other network file systems </li><ul><li>especially for sessions
  70. 70. high latency
  71. 71. locking issues ! </li></ul></ul>
  72. 72. Caching storage - Disk / ramdisk <ul><li>Overhead : filesystem access
  73. 73. Limited number of files per directory </li><ul><li>-> Subdirectories </li></ul><li>Local </li><ul><li>5 Webservers -> 5 local caches
  74. 74. -> Hard to scale
  75. 75. How will you keep them synchronized ? </li><ul><li>-> Don't say NFS or rsync ! </li></ul></ul></ul>
  76. 76. Caching storage - Memcache <ul><li>Facebook, Twitter, Slashdot, … -> need we say more ?
  77. 77. Distributed memory caching system
  78. 78. Multiple machines ↔ 1 big memory-based hash-table
  79. 79. Key-value storage system </li><ul><li>Keys - max. 250bytes
  80. 80. Values - max. 1Mbyte </li></ul></ul>
  81. 81. Caching storage - Memcache <ul><li>Facebook, Twitter, Slashdot, … -> need we say more ?
  82. 82. Distributed memory caching system
  83. 83. Multiple machines ↔ 1 big memory-based hash-table
  84. 84. Key-value storage system </li><ul><li>Keys - max. 250bytes
  85. 85. Values - max. 1Mbyte </li></ul><li>Extremely fast... non-blocking, UDP (!) </li></ul>
  86. 86. Memcache - where to install
  87. 87. Memcache - where to install
  88. 88. Memcache - installation & running it <ul><li>Installation </li><ul><li>Distribution package
  89. 89. PECL
  90. 90. Windows : binaries </li></ul><li>Running </li><ul><li>No config-files
  91. 91. memcached -d -m <mem> -l <ip> -p <port>
  92. 92. ex. : memcached -d -m 2048 -l 127.0.0.1 -p 11211 </li></ul></ul>
  93. 93. Caching storage - Memcache - some notes <ul><li>Not fault-tolerant </li><ul><li>It's a cache !
  94. 94. Lose session data
  95. 95. Lose shopping cart data
  96. 96. ... </li></ul></ul>
  97. 97. Caching storage - Memcache - some notes <ul><li>Not fault-tolerant </li><ul><li>It's a cache !
  98. 98. Lose session data
  99. 99. Lose shopping cart data
  100. 100. … </li></ul><li>Different libraries </li><ul><li>Original : libmemcache
  101. 101. New : libmemcached (consistent hashing, UDP, binary protocol, …) </li></ul><li>Firewall your Memcache port ! </li></ul>
  102. 102. Caching in PHP <?php $memcache = new Memcache(); $memcache->addServer( '172.16.0.1' , 11211); $memcache->addServer( '172.16.0.2' , 11211); $myData = $memcache->get( 'myKey' ); if ($myData === false ) { $myData = GetMyDataFromDB(); // Put it in Memcache as 'myKey', without compression, with no expiration $memcache->set( 'myKey' , $myData, false , 0); } echo $myData;
  103. 103. Let's give that a go ! /** * Retrieves the 10 highest rated articles * @return array List of highest rated articles */ static public function getTopRatedArticleList () { if (!$articleList = $cache->load( 'topRatedArticleList' )) { $articleList = self :: getTopRatedArticleListUncached (); $cache->save($articleList, 'topRatedArticleList' ); } return $articleList; }
  104. 104. Where's the data ? <ul><li>Memcache client decides (!)
  105. 105. 2 hashing algorithms : </li><ul><li>Traditional </li><ul><li>Server failure -> all data must be rehashed </li></ul><li>Consistent </li><ul><li>Server failure -> 1/x of data must be rehashed (x = # of servers) </li></ul></ul><li>No replication ! </li></ul>
  106. 106. Memcache slabs <ul>(or why Memcache says it's full when it's not) <li>Multiple slabs of different sizes : </li><ul><li>Slab 1 : 400 bytes
  107. 107. Slab 2 : 480 bytes (400 * 1.2)
  108. 108. Slab 3 : 576 bytes (480 * 1.2) (and so on...) </li></ul><li>Multiplier (1.2 here) can be configured
  109. 109. Each larger slab has room for fewer items (chunks)
  110. 110. -> Store a lot of very large objects
  111. 111. -> Large slabs might be full
  112. 112. -> Rest of slabs might be free
  113. 113. -> Try to store more -> eviction of data ! </li></ul>
  114. 114. Memcache - Is it working ? <ul><li>Connect to it using telnet </li><ul><li>&quot;stats&quot; command ->
  115. 115. Use Cacti or other monitoring tools </li></ul></ul>STAT pid 2941 STAT uptime 10878 STAT time 1296074240 STAT version 1.4.5 STAT pointer_size 64 STAT rusage_user 20.089945 STAT rusage_system 58.499106 STAT curr_connections 16 STAT total_connections 276950 STAT connection_structures 96 STAT cmd_get 276931 STAT cmd_set 584148 STAT cmd_flush 0 STAT get_hits 211106 STAT get_misses 65825 STAT delete_misses 101 STAT delete_hits 276829 STAT incr_misses 0 STAT incr_hits 0 STAT decr_misses 0 STAT decr_hits 0 STAT cas_misses 0 STAT cas_hits 0 STAT cas_badval 0 STAT auth_cmds 0 STAT auth_errors 0 STAT bytes_read 613193860 STAT bytes_written 553991373 STAT limit_maxbytes 268435456 STAT accepting_conns 1 STAT listen_disabled_num 0 STAT threads 4 STAT conn_yields 0 STAT bytes 20418140 STAT curr_items 65826 STAT total_items 553856 STAT evictions 0 STAT reclaimed 0
  116. 116. Memcache - backing up
  117. 117. Memcache - deleting <?php $memcache = new Memcache(); $memcache->delete( 'myKey' ); $myData = $memcache->get( 'myKey' ); // $myData === false
  118. 118. Memcache - tip <ul>Page with multiple blocks ? -> use Memcached::getMulti() Warning : what if you get some hits and some misses ? </ul>
  119. 119. Naming your keys <ul><li>Key names must be unique
  120. 120. Prefix / namespace your keys !
  121. 121. Only letters, numbers and underscore
  122. 122. md5() is useful </li><ul><li>-> BUT : harder to debug </li></ul><li>Use clear names
  123. 123. Document your key names ! </li></ul>
  124. 124. Updating data
  125. 125. Updating data
  126. 126. Adding/updating data $memcache->delete( 'ArticleDetails__Toshiba_32C100U_32_Inch' ); $memcache->delete( 'Homepage_Popular_Product_List' );
  127. 127. Adding/updating data
  128. 128. Adding/updating data - Why it crashed
  129. 129. Adding/updating data - Why it crashed
  130. 130. Adding/updating data - Why it crashed
  131. 131. Cache stampeding elePHPants
  132. 132. Cache stampeding
  133. 133. Memcache code ? DB
  134. 134. Cache warmup scripts <ul><li>Used to fill your cache when it's empty
  135. 135. Run it before starting Webserver !
  136. 136. 2 ways : </li><ul><li>Visit all URLs </li><ul><li>Error-prone
  137. 137. Hard to maintain </li></ul><li>Call all cache-updating methods </li></ul><li>Make sure you have a warmup script ! </li></ul>
  138. 138. Cache stampeding - what about locking ? <ul>Seems like a nice idea, but... <li>Lock in place
  139. 139. -> lots of new connections
  140. 140. -> memory spike
  141. 141. What if the process that created the lock fails ? </li></ul>
  142. 142. Quick word about expiration <ul><li>General rule : don't let things expire
  143. 143. Exception to the rule : things that have an end date (calendar items) </li></ul>
  144. 144. So... <ul>DON'T DELETE FROM CACHE (and don't expire unless usefull) </ul>
  145. 145. Time for... <ul>a break (15 min) After the break : Nginx Varnish Frontend caching Various tuning top tips </ul>
  146. 146. LAMP... <ul>-> LAMMP -> LANMMP </ul>
  147. 147. Nginx <ul><li>Web server
  148. 148. Reverse proxy
  149. 149. Lightweight, fast
  150. 150. 7.5% of all Websites </li></ul>
  151. 151. Nginx <ul><li>No threads, event-driven
  152. 152. Uses epoll / kqueue
  153. 153. Low memory footprint
  154. 154. 10000 active connections = normal </li></ul>
  155. 155. Nginx - a true alternative to Apache ? <ul><li>Not all Apache modules </li><ul><li>mod_auth_*
  156. 156. mod_dav*
  157. 157. … </li></ul><li>Basic modules are available
  158. 158. Some 3 rd party modules (needs recompilation !) </li></ul>
  159. 159. Nginx - Installation <ul><li>Packages
  160. 160. Win32 binaries
  161. 161. Build from source (./configure; make; make install) </li></ul>
  162. 162. Nginx - Configuration server { listen 80; server_name www.domain.ext *.domain.ext; index index.html; root /home/domain.ext/www; } server { listen 80; server_name photo.domain.ext; index index.html; root /home/domain.ext/photo; }
  163. 163. Nginx - phase 1 <ul><li>Move Apache to a different port (8080)
  164. 164. Put Nginx at port 80
  165. 165. Nginx serves all statics (images, css, js, …)
  166. 166. Forward dynamic requests to Apache </li></ul>
  167. 167. Nginx for static files only server { listen 80; server_name www.domain.ext; location ~* ^.*.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|pdf|ppt|txt|tar|rtf|js)$ { expires 30d; root /home/www.domain.ext; } location / { proxy_pass http://www.domain.ext:8080; proxy_pass_header Set-Cookie; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
  168. 168. Nginx - let's give that a go !
  169. 169. Nginx for PHP ? <ul>LANMMP to... LNMPP (ok, this is getting ridiculous) </ul>
  170. 170. Nginx with PHP <ul><li>In the past : spawn-fcgi (from Lighttpd)
  171. 171. Now : PHP-FPM (in PHP 5.3.3 !)
  172. 172. Runs on port 9000
  173. 173. Nginx connects using fastcgi method </li></ul>location / { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param SCRIPT_FILENAME /home/www.phpbenelux.eu/$fastcgi_script_name; fastcgi_param SERVER_NAME $host; fastcgi_intercept_errors on; }
  174. 174. Nginx + PHP-FPM features <ul><li>Graceful upgrade
  175. 175. Spawn new processes under high load
  176. 176. Chroot
  177. 177. Slow request log ! </li></ul>
  178. 178. Nginx + PHP-FPM features <ul><li>Graceful upgrade
  179. 179. Spawn new processed under high load
  180. 180. Chroot
  181. 181. Slow request log !
  182. 182. fastcgi_finish_request() -> offline processing </li></ul>
  183. 183. Nginx + PHP-FPM - performance ?
  184. 184. LAMP
  185. 185. Varnish <ul><li>Not just a load balancer
  186. 186. Reverse proxy cache / http accelerator / …
  187. 187. Caches (parts of) pages in memory
  188. 188. Careful : </li><ul><li>uses threads
  189. 189. Nginx is faster (but doesn't have VCL) </li></ul></ul>
  190. 190. Varnish - Installation & configuration <ul><li>Installation </li><ul><li>Packages
  191. 191. Source : ./configure && make && make install </li></ul><li>Configuration </li><ul><li>/etc/default/varnish
  192. 192. /etc/varnish/*.vcl </li></ul></ul>
  193. 193. Varnish - backends + load balancing backend server1 { .host = &quot;192.168.0.10&quot;; } backend server2{ .host = &quot;192.168.0.11&quot;; } director example_director round-robin { { .backend = server1; } { .backend = server2; } }
  194. 194. Varnish - backends + load balancing backend server1 { .host = &quot;192.168.0.10&quot;; .probe = { .url = &quot;/&quot;; .interval = 5s; .timeout = 1 s; .window = 5; .threshold = 3; } }
  195. 195. Varnish - VCL <ul><li>Varnish Configuration Language
  196. 196. DSL (Domain Specific Language) </li><ul><li>-> compiled to C </li></ul><li>Hooks into each request
  197. 197. Defines : </li><ul><li>Backends (web servers)
  198. 198. ACLs
  199. 199. Load balancing strategy </li></ul><li>Can be reloaded while running </li></ul>
  200. 200. Varnish - whatever you want <ul><li>Real-time statistics (varnishtop, varnishhist, ...)
  201. 201. ESI </li></ul>
  202. 202. Varnish - ESI <ul>Perfect for caching pages </ul>In your article page output : <esi:include src=&quot;/latest-news&quot;/>
  203. 203. Varnish with ESI - hold on tight !
  204. 204. Varnish - what can/can't be cached ? <ul><li>Can : </li><ul><li>Static pages
  205. 205. Images, js, css
  206. 206. Pages or parts of pages that don't change often (ESI) </li></ul><li>Can't : </li><ul><li>POST requests
  207. 207. Requests with Set-Cookie
  208. 208. Very large files (it's not a file server !)
  209. 209. User-specific content </li></ul></ul>
  210. 210. Apache - tuning tips <ul><li>Disable unused modules -> fixes 10% of performance issues
  211. 211. Set AllowOverride to None
  212. 212. Disable SymLinksIfOwnerMatch </li><ul><li>Site in /var/www/domain.com/subdomain/html
  213. 213. Check on /var, /var/www, /var/www/domain.com, etc. </li></ul><li>MinSpareServers, MaxSpareServers, StartServers, MaxClients, MPM selection -> a whole session of its own ;-)
  214. 214. Don't mod_proxy -> use Nginx or Varnish !
  215. 215. High load on an SSL-site ? -> put SSL on a reverse proxy </li></ul>
  216. 216. PHP speed - some tips <ul><li>Upgrade PHP - every minor release has 5-15% speed gain !
  217. 217. Use an opcode cache </li></ul>
  218. 218. Caching storage - Opcode caching
  219. 219. PHP speed - some tips <ul><li>Upgrade PHP - every minor release has 5-15% speed gain !
  220. 220. Use an opcode cache
  221. 221. Profile your code </li><ul><li>XHProf
  222. 222. Xdebug </li></ul><li>But : turn off profilers on acceptance/production platforms !
  223. 223. Let's see what difference opcode caching and profilers make... </li></ul>
  224. 224. KCachegrind is your friend
  225. 225. DB speed - some tips <ul><li>Avoid NOW() -> use PHP date(&quot;Y-m-d&quot;) as a parameter </li><ul><li>Why ? Query cache ! </li></ul><li>Index, index, index ! (where needed only)
  226. 226. Use same types for joins </li><ul><li>i.e. don't join decimal with int </li></ul><li>RAND() is evil !
  227. 227. Select the right storage engine
  228. 228. Don't use persistent connect </li></ul>
  229. 229. Caching & Tuning @ frontend http://www.websiteoptimization.com/speed/tweak/average-web-page/
  230. 230. Caching in the browser <ul><li>HTTP 304 (Not modified)
  231. 231. Expires/Cache-Control header </li></ul>
  232. 232. HTTP 304 First request Next requests
  233. 233. HTTP 304 with ETag First request Next requests
  234. 234. Expires/Cache-control header <ul>Cache-Control <ul><li>HTTP/1.1
  235. 235. Seconds to expiry
  236. 236. Used by browsers </li></ul></ul>First request Next requests No requests until item expires <ul>Expires <ul><li>HTTP/1.0
  237. 237. Date to expire on
  238. 238. Used by old proxies
  239. 239. Requires clock to be accurate ! </li></ul></ul>
  240. 240. Pragma: no-cache = evil <ul><li>&quot;Pragma: no cache&quot; doesn't make it uncacheable
  241. 241. Don't want caching on a page ? </li><ul><li>HTTP/1.0 : &quot;Expires : Fri, 30 Oct 1998 00:00:00 GMT&quot; (in the past)
  242. 242. HTTP/1.1 : &quot;Cache-Control: no-store&quot; </li></ul></ul>
  243. 243. Frontend tuning <ul>1. You optimize backend 2. Frontend engineers messes up -> havoc on backend 3. Don't forget : frontend sends requests to backend ! SO... <li>Care about frontend
  244. 244. Test frontend
  245. 245. Check what requests frontend sends to backend </li></ul>
  246. 246. Tuning frontend <ul><li>Minimize requests </li><ul><li>Combine CSS/JavaScript files
  247. 247. Use inline images in CSS/XHTML (not supported on all browsers yet) </li></ul></ul>
  248. 248. Frontend tuning - inline CSS/XHTML images #navbar span { width: 31px; height: 31px; display: inline; float: left; margin-right: 4px; } .home { background-image: url(data:image/gif;base64,R0lGODlhHwAfAPcAAAAAAIxKAKVjCLW1tb29tcbGvc7OxtZ7ANbWztbW1tbe1t7e1uelMefn1ufn3ufn5+fv3u+MAO/v5+/v7/fGCPf35/f37//nY////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////........MEl0nGVUC6tObNnPceSFBaQVMJAxC4lo3gNOrUaFnTHoAxNm3XVxPfRq139e8BEGAjWD5bgIALw287T8AcAXLly2kjOACdc17higXSIKDO/Lpv7Qq4bw7APgBq8eOzX69InrZ6xe3dbxZffyTGkb8tdx8F+b0Xn2sFsCSBAgTM5lp63RHYnoHUudZgRgkGOGCB+43nGk4OGcQTabKx5dyJKJ7ImoUNCaRRAZYN1ppsrT3Y2gIwyjSQBAtUpABml/0IJGYd6VjQUDH9uBFkGxGm5I8dPQaRUAQUMBdhhBV25ZYUJZBcSAtSJBddWZZ5UAGPOTXlgkNVOSZdBxEwIkYu7VhYnAol5GaadRqF0Uaz0TgXnX2umVFyGakJUUAAADs=); margin-left: 4px; } <img border=0 src=&quot;data:image/gif;base64,R0lGODlhHwAfAPcAAAAAAIxKAKVjCLW1tb29tcbGvc7OxtZ7ANbWztbW1tbe1t7e1uelMefn1ufn3ufn5+fv3u+MAO/v5+/v7/fGCPf35/f37//nY/......Uaz0TgXnX2umVFyGakJUUAAADs=&quot;>
  249. 249. Tuning frontend <ul><li>Minimize requests </li><ul><li>Combine CSS/JavaScript files
  250. 250. Use inline images in CSS (not supported on all browsers yet)
  251. 251. Use CSS Sprites </li></ul></ul>
  252. 252. CSS Sprites
  253. 253. Tuning content - CSS sprites
  254. 254. Tuning content - CSS sprites 11 images 11 HTTP requests 24KByte 1 images 1 HTTP requests 14KByte
  255. 255. Tuning frontend <ul><li>Minimize requests </li><ul><li>Combine CSS/JavaScript files
  256. 256. Use inline images in CSS (not supported on all browsers yet)
  257. 257. Use CSS Sprites (horizontally if possible) </li></ul><li>Put CSS at top
  258. 258. Put JavaScript at bottom </li><ul><li>Max. no connections
  259. 259. Especially if JavaScript does Ajax (advertising-scripts, …) ! </li></ul><li>Avoid iFrames </li><ul><li>Again : max no. of connections </li></ul><li>Don't scale images in HTML
  260. 260. Have a favicon.ico (don't 404 it !) </li></ul>
  261. 261. Tuning frontend <ul><li>Use GET for Ajax retrieval requests (and cache them !)
  262. 262. Split requests across subdomains
  263. 263. Put statics on a separate subdomain (without cookies !) </li></ul>www.phpbenelux.eu www.phpbenelux.eu images.phpbenelux.eu
  264. 264. Tuning miscellaneous <ul><li>Avoid DNS lookups </li><ul><li>Frontend : don't use too many subdomains (2 = ideal)
  265. 265. Backend : </li><ul><li>Turn off DNS resolution in Apache : HostnameLookups Off
  266. 266. If your app uses external data </li><ul><li>Run a local DNS cache (timeout danger !)
  267. 267. Make sure you can trust DNS servers (preferable run your own) </li></ul></ul></ul><li>Compress non-binary content (GZIP) </li><ul><li>mod_deflate in Apache
  268. 268. HttpGzipModule in Nginx (HttpGzipStaticModule for pre-zipped statics !)
  269. 269. No native support in Varnish </li></ul></ul>
  270. 270. What else can kill your site ? <ul><li>Redirect loops </li><ul><li>Multiple requests </li><ul><li>More load on Webserver
  271. 271. More PHP to process </li></ul><li>Additional latency for visitor
  272. 272. Try to avoid redirects anyway
  273. 273. -> In ZF : use $this->_forward instead of $this->_redirect </li></ul><li>Watch your logs, but equally important...
  274. 274. Watch the logging process ->
  275. 275. Logging = disk I/O -> can kill your site !
  276. 276. Slashdot effect </li></ul>
  277. 277. Above all else... be prepared ! <ul><li>Have a monitoring system
  278. 278. Use a cache abstraction layer (disk -> Memcache)
  279. 279. Don't install for the worst -> prepare for the worst
  280. 280. Have a test-setup
  281. 281. Have fallbacks </li><ul><li>Turn off non-critical functionality </li></ul></ul>
  282. 282. <ul>Questions ? </ul>
  283. 283. Contact <ul><li>Web http://techblog.wimgodden.be
  284. 284. Slides http://www.slideshare.net/wimg
  285. 285. Twitter @wimgtr
  286. 286. E-mail [email_address] </li></ul>
  287. 287. Please... <ul>Rate my talk : http://joind.in/2950 </ul>
  288. 288. <ul>Thanks ! </ul>

×