<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Motion Standing Still &#187; Memcache</title>
	<atom:link href="http://www.motionstandingstill.com/category/memcache/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.motionstandingstill.com</link>
	<description>high performance ruby on rails</description>
	<lastBuildDate>Sun, 11 Jul 2010 03:46:07 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Spandex Memcache Store is now in Rails 2.3</title>
		<link>http://www.motionstandingstill.com/spandex-memcache-store-is-now-in-rails-23/2009-02-04/</link>
		<comments>http://www.motionstandingstill.com/spandex-memcache-store-is-now-in-rails-23/2009-02-04/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 00:36:06 +0000</pubDate>
		<dc:creator>nahum</dc:creator>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[Memcache]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[spandex mem cache store]]></category>

		<guid isPermaLink="false">http://www.motionstandingstill.com/?p=228</guid>
		<description><![CDATA[Just a quick note to say that the local cache functionality of my Spandex Memcache Store Plugin has been included in Ruby on Rails 2.3 RC1.  After I released the plugin I was asked to submit a patch to Rails Edge adding it&#8217;s functionality &#8211; which I did over my Christmas break.  My changes have [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p>Just a quick note to say that the local cache functionality of my <a href="http://github.com/terrcin/spandex_mem_cache_store/tree/master" target="_blank">Spandex Memcache Store Plugin</a> has been included in <a href="http://weblog.rubyonrails.org/2009/2/1/rails-2-3-0-rc1-templates-engines-rack-metal-much-more" target="_blank">Ruby on Rails 2.3 RC1</a>.  After I released the plugin I was asked to submit a patch to Rails Edge adding it&#8217;s functionality &#8211; which I did over my Christmas break.  My changes have subsequently been re-factored a bit, decoupling the local cache functionality from the MemCacheStore class and moving it to being a wrapper around whatever caching store is used.  Hurray for open source!</p>
<p>The plugin is still useful as I didn&#8217;t submit it&#8217;s session caching changes to Rails &#8211; essentially using Rails.cache for session storage rather than establishing a second connection to MemCache.  This also benefits from the local cache changes.</p>
<p>Where next?  In the next week or so I plan on updating the plugin by removing the local cache functionality to prevent any conflicts with Rails 2.3 when it&#8217;s released.</p>
<p>After that, I&#8217;m planning on working through the list of changes detailed under <em>Future Plans</em> in the <a href="http://github.com/terrcin/spandex_mem_cache_store/blob/402a216f1a982d2eaacb2169802a9a41708366fb/README" target="_blank">plugins readme</a>, also listed below.</p>
<ul>
<li>TESTS! (I wrote a bunch for the patch, just need to do that for the remaining session changes)</li>
<li>Make this a Gem</li>
<li>Conditional caching</li>
<li>Multi-Get</li>
<li>Dynamic key helpers</li>
<li>Make the code more awesome</li>
</ul>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.motionstandingstill.com/spandex-memcache-store-is-now-in-rails-23/2009-02-04/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting simple with Rails caching</title>
		<link>http://www.motionstandingstill.com/starting-simple-with-rails-caching/2008-11-27/</link>
		<comments>http://www.motionstandingstill.com/starting-simple-with-rails-caching/2008-11-27/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 22:16:41 +0000</pubDate>
		<dc:creator>nahum</dc:creator>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[Memcache]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[expire]]></category>
		<category><![CDATA[keys]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[simple]]></category>
		<category><![CDATA[stale data]]></category>
		<category><![CDATA[sweeper]]></category>

		<guid isPermaLink="false">http://www.motionstandingstill.com/?p=195</guid>
		<description><![CDATA[So, you’ve launched your website and increasingly people are actually using it! Congratulations. Money is probably tight and your server(s) are starting to feel the strain but you can’t buy more - people get turned off by slow responding sites and traffic is $$. What do do?


No related posts.]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">So, you&#8217;ve launched your website and increasingly people are actually using it!  Congratulations. Money is probably tight and your server(s) are starting to feel the strain but you can&#8217;t buy more &#8211; people get turned off by slow responding sites and traffic is $$.  What do do?</p>
<p style="text-align: justify;">You&#8217;ve noticed that your app is doing a lot of repetitive work &#8211; calculating and showing the same data over and over again.  This doesn&#8217;t fit with your adherence to DRY principles at all.  If you cached repetitive responses your servers could give you way more bang for you buck &#8211; and it would only cost your time.</p>
<p style="text-align: justify;">You are about to embark on an exciting journey fraught with hidden dangers, so let me prepare you &#8211; cheesy I know but hey.</p>
<p style="text-align: justify;">First, you have actually done some code optimisation haven&#8217;t you?  Stopped using the default mysql config?  Checked your slow query log?  Used pl_analyise to parse your production logs?  Fixed the popular, but slow actions?  Done some eager loading so you get everything in a couple of hits from mysql rather than many many many little hits as your views render?  When you dream you see log tailing in the background?  Minified your javascript and css?  Static assets have expire headers?  Don&#8217;t have too many Mongrels running?  Sessions are stored in MemCache? Go do all that if you haven&#8217;t and only come back here if this are still too slow.  Oh and try to get your yslow score above 75.</p>
<p style="text-align: justify;">Note: I&#8217;m assuming that you have read a bit about caching in Rails already and have had a play, reading fragments from actions etc&#8230;  If not try googling as there are a number of great articles on it, the Agile book is probably a good start too.</p>
<p style="text-align: justify;"><strong>Start at the end</strong></p>
<p style="text-align: justify;">Instead of just saying &#8216;do this awesome thing&#8217; I&#8217;m gonna explain how I&#8217;ve gotten to saying that, as you shouldn&#8217;t be making blind decisions about these things.  Most of the time when I implement caching for clients I completely skip page caching and action caching and go straight to line item caching, ie caching of small fragments of html.  Sounds completely counter-intuitive doesn&#8217;t it, but it&#8217;s not.</p>
<p style="text-align: justify;">First off I need to define a typical client&#8217;s website so you see where I&#8217;m coming from.  It&#8217;s a user driven web 2.0 website &#8211; so most of the data is user generated and sometimes social networking elements are included, where a user&#8217;s data can be restricted to just their friends instead of being publicly available.  Basically the site lists stuff that people put on it.</p>
<p style="text-align: justify;">Why not page or action caching?  As a starting point it&#8217;s too hard to manage due to the continually changing nature of the data being presented.  This changing nature means your cache might not actually get used that much.  Additionally when you are logged in your name is typically on the page with other unique to you info &#8211; you have x messages etc&#8230;  The latter reason completely rules out caching a whole page for anyone that&#8217;s logged in.  Don&#8217;t restrict caching based speed increases to joe public as logged in people, ie people that give a damn about your site, shouldn&#8217;t be second class citizens.</p>
<p style="text-align: justify;"><strong>Don&#8217;t start with caching lists</strong></p>
<p style="text-align: justify;">Developers still want to jump straight in and cache lists of items (and pages too) rather than the individual line items &#8211; basically as much of the page as they can in a single hit &#8211; thinking they&#8217;ll get great bang for their buck.  When you deploy with that strategy you&#8217;re in for a world of hurt.  This is because they&#8217;ve not realised they need to take the following into account.</p>
<p style="text-align: justify;">Each time one of the line items changes you have to expire the cache for the whole listing.  If you have pagination then you&#8217;ll likely have to expire ALL cached pages unless you can 100% reliably work out which page the item is on.  So yes you have a separate cache entry for each page of the listing.  If someone adds or edits a line item you have to expire the whole lot &#8211; and thats what people should be doing all the time on your site right?.  Additionally, if you allow sorting or a filtering mechanism you have to uniquely cache by page and the additional dimension(s), thus further reducing the frequency the cache will be used.</p>
<p style="text-align: justify;"><strong>What&#8217;s the goal?</strong></p>
<p style="text-align: justify;">What we are trying to achieve with caching is to DRY up the execution of requests, but in a way that doesn&#8217;t add complexity.  The idea is to let your servers focus on the unique stuff like processing credit cards and telling Jill&#8217;s friends that based on her network and comment history she really doesn&#8217;t like doing things with Sarah unless Joe is there too.</p>
<p style="text-align: justify;">Keep this in mind.  With seeking something to cache, you are basically looking for something that has a high ratio of renders/requests of the exact same html in between changes of that html.  So the more content in the cached fragment, the more frequently you&#8217;ll need to expire it.  Putting that another way, the fewer data sources, instances of models and display dimensions like pagination, sorting and filtering used to make up the cached html the better.  The simplest you can go is one data source, ie a line item.  Remember, keep it simple.</p>
<p style="text-align: justify;">Put in business speak, it&#8217;s a cost / benefit decision.</p>
<p style="text-align: justify;"><strong>It&#8217;s all about the keys</strong></p>
<p style="text-align: justify;">When you store fragments in your cache you name them with a unique string based key so you can access them later -  exactly like a hash.  So yes, they are important.  Typically they looks like a url, sort of based on the actual url or controller/action and the dimensions involved to make it unique to the html being cached.  So for the above listing situation the key should look something like this:</p>
<p style="text-align: justify;">&#8216;/products/list/sort=price/status=in-stock/page=1&#8242;</p>
<p style="text-align: justify;">This actually presents a completely separate reason as to why you shouldn&#8217;t do list caching when you start out on this path.  The problem with this key is that to expire it you have to count the number of products to determine how many pages there are and then manually go and expire all possible keys that could have been generated, one at a time &#8211; this is because expiring via regex is not supported.  If additional dimensions are involved the problem will compound even further.</p>
<p style="text-align: justify;">Yes, that&#8217;s real ugly and will become completely unmanageable.  There are some clever tricks to help out there such as self expiring keys, but that&#8217;s a different topic which I&#8217;ll get to at a later date.</p>
<p style="text-align: justify;"><strong>When to expire</strong></p>
<p style="text-align: justify;">Wait there&#8217;s more!  You have to monitor data changes so you can expire those keys when they become stale as it doesn&#8217;t happen magically.  Normally you&#8217;d setup a sweeper (observer) and just expire things when &#8216;after_save&#8217; is triggered.  Not a problem.  If you have data from multiple models involved in your cached html fragments then you need to monitor all the models involved.  You can go as far as only expiring particular keys based on the attributes that are changing etc&#8230; now much easier in Rails 2.1 with Dirty Objects.</p>
<p style="text-align: justify;">This is all adding yet another layer of complexity.  Ugh.  It should all be documented so that other developers know about it especially new developers &#8211; otherwise further work could mess it up and you might start showing stale data to users.  In my book that&#8217;s pretty much on par with errors occurring as you could be showing the wrong price or even deleted data to users.  Unless you are careful about it, it can all become some really hard to manage mess which really isn&#8217;t going to give much benefit to your users.</p>
<p style="text-align: justify;"><strong>Line item caching</strong></p>
<p style="text-align: justify;">As you are not having to worry about other dimensions such as pagination, sort order and filtering, other line items or even if the user is logged in or not, the line item&#8217;s cache key should be something like this:</p>
<p style="text-align: justify;">&#8216;/products/#{product.id}/line_item&#8217;</p>
<p style="text-align: justify;">To make sure it expires correctly all you have to do is setup a sweeper watching the line item and simply delete it&#8217;s key when it changes &#8211; use Rails.cache.delete for this.  If the line item is rendered using data from through relationships, you then have to monitor them too.  I&#8217;ve seen people putting a &#8216;last_active_at&#8217; field on a line item and when anything related to it changes they update that time field.  That works nicely and things are kept simple.</p>
<p style="text-align: justify;"><strong>Finally</strong></p>
<p style="text-align: justify;">That should set you off in the right direction, remembering though this is a starting point for your first caching strategy.  Later on you&#8217;ll actually start doing multiple layers of caching and covering more complex html, such as lists, if your site continues to grow.</p>
<p style="text-align: justify;">Now hopefully I&#8217;ve convinced you to start out with caching the html for a single line item &#8211; or something just as simple.  If not post a comment and tell me why not.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.motionstandingstill.com/starting-simple-with-rails-caching/2008-11-27/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to reduce your memcache reads</title>
		<link>http://www.motionstandingstill.com/how-to-reduce-your-memcache-reads/2008-11-14/</link>
		<comments>http://www.motionstandingstill.com/how-to-reduce-your-memcache-reads/2008-11-14/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 00:21:23 +0000</pubDate>
		<dc:creator>nahum</dc:creator>
				<category><![CDATA[Memcache]]></category>
		<category><![CDATA[spandex mem cache store]]></category>

		<guid isPermaLink="false">http://www.motionstandingstill.com/?p=184</guid>
		<description><![CDATA[Several months back I presented at WellRailed on using Memcache with Rails.  I focused on fragment caching and the libraries I&#8217;d created to make life easier.  I&#8217;ve now moved some of what I discussed into a plugin available at github which I&#8217;ve described as follows:
A enhanced version of and replacement for the MemCacheStore shipping with [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Several months back I presented at <a href="http://groups.google.com/group/WellRailed" target="_blank">WellRailed</a> on using Memcache with Rails.  I focused on fragment caching and the libraries I&#8217;d created to make life easier.  I&#8217;ve now moved some of what I discussed into a <a href="http://github.com/terrcin/spandex_mem_cache_store/tree/master" target="_blank">plugin available at github</a> which I&#8217;ve described as follows:</p>
<blockquote style="text-align: justify;"><p>A enhanced version of and replacement for the MemCacheStore shipping with rails.  It uses a per-request local cache to buffer duplicate memcache reads which can result in halving read requests, and it uses a single connection to memcache for both the cache and session stores.</p></blockquote>
<p style="text-align: justify;">It doesn&#8217;t yet have the awesome key creation and maintenance library that I showed as that has evolved quite a bit and needs a big bunch of love first &#8211; which I&#8217;m working on.</p>
<p style="text-align: justify;">There is now a <a href="http://www.motionstandingstill.com/spandex-mem-cache-store/" target="_blank">dedicated page</a> on this site for the plugin, currently it&#8217;s holds a copy of the plugin&#8217;s README.  My intention is to update the page with examples etc.. as I extend the plugin.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.motionstandingstill.com/how-to-reduce-your-memcache-reads/2008-11-14/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.493 seconds -->
