Search This Blog

Friday, April 23, 2010

Release It! - Chapter 9 Capacity Antipatterns

Hardware and bandwidth are expensive so use them efficiently.

Resource Pool Contention
  • eliminate contention under normal loads
  • if possible, size resource pools to the request thread pool - if there is a resource for every thread then there should not be any contention.
  • prevent vicious cycles - resource contention causes transactions to take longer.  Slower transaction causes more resource contention.
  • watch for Block Threads - the pool capacity problem can quickly become a stability problem if your threads start blocking waiting for a resource 
Excessive JSP Fragments
  • JSPs can cause permgen memory problems because each "page's" class get loaded into memory and never leaves
  • don't use code for content - if the content is static, then use HTML.  Only use JSP for dynamic content where you need code to make it work.
AJAX Overkill
AJAX clients can overwhelm non-Google sized servers because the requests come more frequently than what a human might do.  Done right, AJAX can reduce bandwidth, done wrong and it can crash your system.
  • Interaction Design - try and use AJAX for interactions that represent a single task in the user's mind, such as sending an e-mail.  Can eliminate serving up multiple pages to walk through work flow.
  • Request Timings - see if your AJAX libraries allow you to modify the length between auto-complete requests.
  • Session Thrashing - make sure to configure your web back end for session affinity so that you don't needlessly migrate sessions.
  • Response Formatting - don't send back HTML pages or fragments.  HTML is verbose and chews up bandwidth.  Instead, send back the data and dynamically update the page on the client.  Use JSON instead of XML, it is easier to parse and is less verbose.
  • avoid needless requests - don't use polling for auto completion.  Instead, send the request when the field actually changes.
  • respect session architecture - make sure your AJAX requests include a session id cookie or query parameter.  If you don't, the application server will create a new, wasted one for each AJAX request.
  • minimize the size of replies - return the least amount of data. Avoid returning HTML and hand back JSON or XML instead.
  • increase the size of your web tier - AJAX is chatty and make sure your web tier can handle the additional traffic.
Overstaying Sessions
Java's default session time out of 30 minutes is overkill.  Analyze your traffic and try and determine what the average real session time is.  Set your session timeout to one deviation away.  Best bet is to avoid session all together.  If it is serving as a cache and  you can easily recreate its contents, throw the session away at the end of the operation.
  • curtail session retention - keep sessions in memory for as short a time as reasonable.
  • remember the users don't understand sessions - users understand automatic logout for security reasons.  They don't understand their shopping cart getting emptied because they took longer than 30 minutes to complete their transaction.  Things should not disappear because the user went away for a cup of coffee.
  • keep keys, not whole objects - keys are smaller and consume less memory. Keep whole objects only if you use SoftReferences.
Wasted Space in HTML
The more HTML you transmit that more it affects the system.
  • Whitespace - whitespace costs money.  Try putting in an interceptor to filter out whitespace.
  • Expensive Spacer Images - that little 1-pixel transparent GIF chews up resources because of multiplier effects.  Size things using HTML instead.
  • Excess HTML Tables - using Tables for formatting instead of CSS has a tremendously negative effect on capacity.
  • omit needless characters
  • remove whitespace - computers don't need nice formatting so don't pay for it
  • replace spacer images with non-breaking spaces or CSS
  • replace HTML tables with CSS layout - CSS files are loaded once, tables are loaded every time.
The Reload Button
Impatient users will hammer the reload button.  Only defense is to have a web site that is fast enough.  Make the reload button irrelevant - make your site fast enough.

Handcrafted SQL
Developer crafted SQL is usually bad and is difficult to find and tune. Handcrafted SQL is unpredictable while ORM generated SQL is not.
  • minimize hand crafted SQL
  • see whether the DBA laughs at your queries - don't put it into production if she does
  • verify gains against real data - try your SQL against production-sized
    data set.  If it is fast in development doesn't mean it'll be fast in
    production.
Database Eutrophication
Eutrophication is a fancy term for "lethal sludge build up".
  • Indexing - in general, any column that is a target of an association should be indexed.  Keep the DBA in the loop as development proceeds to help with evolving the database schema.
  • Partitioning - a vendor specific way of organizing the tables on disk
  • Historical Data - reporting and ad hoc analysis should not be done on the production database.  Think about a multi-level storage scheme to keep the amount of data needed that doesn't build up crud in the production db.
  • create indexes: it's not just the DBA's responsibility - you know how your app works and the type of access it uses use that knowledge to improve the db's performance.
  • purge sludge - old data slows down queries and inserts so try and get it off of the production servers
  • keep reports out of production - don't jeopardize production with expensive queries.  A data warehouse schema is different from an OLTP schema anyway.
Integration Point Latency
Performance problems for individual users become capacity problems for
the entire system.  Expose yourself to latency as seldom as possible - avoid chatty protocols.

Cookie Monsters
HTTP cookies can be easily abused.  Storing a serialized object graph as a cookie is a bad idea. There are security and code issues as well as capacity issues.  Cookies are meant to be small (less than 100 bytes) probably because they are meant to be sent with each request -- just enough to hold a session identifier.  Constantly sending 400K worth of cookie with each request is a drain on resources, including bandwidth and CPU.  Cookies are useful but be mindful that the client can lie, send back stale or broken data and might not send back any cookies at all
  • serve small cookies - use cookies for identification, not objects. 
  • keep session data on the server, where it can't be tampered with by a
    hacker. 

No comments:

Post a Comment