<?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>Grep My Mind &#187; memcached</title>
	<atom:link href="http://www.grepmymind.com/tags/memcached/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.grepmymind.com</link>
	<description>Wonder what’s on my mind? Now you know.</description>
	<lastBuildDate>Wed, 14 Oct 2009 22:20:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>MySQL Conf 2008 &#8211; Memcached (Day 1)</title>
		<link>http://www.grepmymind.com/2008/04/14/mysql-conf-2008-memcached-day-1/</link>
		<comments>http://www.grepmymind.com/2008/04/14/mysql-conf-2008-memcached-day-1/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 00:24:01 +0000</pubDate>
		<dc:creator>Michael Tougeron</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysql08]]></category>
		<category><![CDATA[mysqlconf08]]></category>

		<guid isPermaLink="false">http://www.grepmymind.com/2008/04/14/mysql-conf-2008-memcached-day-1/</guid>
		<description><![CDATA[The session I&#8217;m attending this afternoon is Memcached and MySQL: Everything You Need To Know. I&#8217;m really looking forward to this talk. For whatever geeky reason I think Memcached is the coolest. Brian Aker has put the PDF of the slides at http://download.tangent.org/talks/Memcached%20Study.pdf. The slides will be updated as time goes on so this link [...]]]></description>
			<content:encoded><![CDATA[<p>The session I&#8217;m attending this afternoon is <a href="http://en.oreilly.com/mysql2008/public/schedule/detail/1627">Memcached and MySQL: Everything You Need To Know</a>.  I&#8217;m really looking forward to this talk.  For whatever geeky reason I think <a href="http://danga.com/memcached/">Memcached</a> is the coolest.  <img src='http://www.grepmymind.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Brian Aker has put the PDF of the slides at <a href="http://download.tangent.org/talks/Memcached%20Study.pdf">http://download.tangent.org/talks/Memcached%20Study.pdf</a>.  The slides will be updated as time goes on so this link should always have the most up-to-date stuff.  In case at some point he removes them, you can find them <a title="Memcached Slides" href="http://www.grepmymind.com/wp-content/uploads/2008/04/memcached-study.pdf">attached</a>.</p>
<p>2:15pm: Talking about <a href="http://grazr.com/">Grazr</a> and how they have a daemon to do write-through cache.  Now talking about processing data so that the data normally/frequently used is always in cache.</p>
<p>2:25pm: Memcached is supposed to be &#8220;simple&#8221; so that it can be faster.  Has its own memory slab allocator, it originally tried using malloc but that was way too slow.  The way it assigns blocks for memory assignment means that each data store goes into one of those &#8220;blocks.&#8221;  If the # of available room in the block is full, then it drops the oldest record in that block.  Written around libevent for scalable network connections.  That was only connections sending data are &#8220;active&#8221; on the server.</p>
<p>2:27pm: The clients handle the majority of the load.  It takes the cache key and hashes it so that it knows which server to send to the data to.  Server doesn&#8217;t do the serialization either.</p>
<p>2:30pm: Server is not redundant and does not handle failover.  But some clients like with <a href="http://pecl.php.net/memcache">PHP&#8217;s PECL</a>, the client can implement this type of functionality.</p>
<p>2:33pm: Available commands are pretty much only set/get/replace/add, append/prepend, increment/decrement, <a href="http://en.wikipedia.org/wiki/Compare_and_swap">cas</a> and stats.  While they say append/prepend are easy to be abused it is still an easy &amp; quick way to store the keys used for something.  Unless the size of the keys that you are storing reaches close to 1MB, it&#8217;s okay.  It&#8217;s a great way to know what keys you&#8217;ll need to clear when product information has been updated.</p>
<p>2:38pm: <a href="http://tangent.org/586/Memcached_Functions_for_MySQL.html">MySQL UDF</a> usage for Memcached is growing.  <a href="http://code.google.com/soc/2008/">Google Summer of Code</a> is working on making <a href="http://forge.mysql.com/wiki/SummerOfCode2008Ideas">MySQL Query cache use Memcached</a>.   lighthttpd has mod_memcache for caching files from disk.  Apache also has mod_memcached but is still alpha.</p>
<p>2:42pm:  Memcached has a few limits that you should pay attention to:<br />
The max cache key is 250 bytes<br />
Max data size is 1MB<br />
Maxbytes limits the item cache, not everything<br />
Be careful because with 32bit machines, you can set too high of a maxbytes that in combination with other memcache memory elements (e.g., key storage) and it will segfault.</p>
<p>2:46pm:  <a href="http://en.wikipedia.org/wiki/Cache_algorithms">LRU</a> &#8211; Least recently accessed items are up for eviction and can be seen.  One LRU exists per &#8220;slab class.&#8221;  LRU evictions don&#8217;t need to be common.  That&#8217;s pretty nice because you won&#8217;t lose larger data sets because a small data element doesn&#8217;t have room in its slab (and vice versa).</p>
<p>2:50pm:  Threads &#8211; Great for large instances (16G+) and/or large multiget requests.  It scales okay now, but they are working on improving it.  Also means that you may not need to run multiple instances on the same box.  Only 1 thread can talk to the allocator and the hash table at one time.  This is so that you don&#8217;t have race conditions.</p>
<p>2:55pm:  Don&#8217;t run Memcached with swap enabled or at least set it really small.  Can seriously slow down performance and technically is contrary to purpose of memcache.  The smaller swap means that OS can still use if it really has to, but won&#8217;t let the writing to swap happen for Memcached.  The memory for Memcached is permanently allocated from the OS.  Shouldn&#8217;t be an issue with most modern servers.  The slab class are created by chunk size.  Tends to create 36-39 slab classes.  It does not reassign slab classes once the daemon loads.  They are working on a way to allow you to change the assignments on the fly.  e.g., if you find that you are evicting a lot of data from one slab, you can give that slab more pages while taking it from another slab.</p>
<p>3:10pm: There is normal hashing (usually crc or some modulus operation) and consistent hashing.  Each client could implement its own version, but usually use common methods so that multiple clients can use the same pool of memcache servers.</p>
<p>3:20pm:  PECL client (and most others) has option to not &#8220;remove&#8221; the server if it is not available.  It can have a &#8220;back-off&#8221; method where it won&#8217;t try to hit the server for 1 second, 5 seconds, then 15 seconds, etc.  It can also failover to a different server until the original is back online.</p>
<p>3:25pm: You should always try to use multi-get.  Memcached is optimized for handling multiple requests at once.  You&#8217;ll find a big improvement if you do this.  The trick is to write your code in a way that can utilize this to the fullest.</p>
<p>4:04pm: Back from break.  We&#8217;re now going over various coding examples of how to use Memcached.  I&#8217;m hoping this part will be helpful.  Most coding examples of how to use Memcached are generally fairly simple.  But with 90 minutes left, there aught to be some gems.</p>
<p>4:15pm: Going over locks.  Much like my previous post regarding <a href="http://www.grepmymind.com/2008/01/11/memcached-php-semaphore-cache-expiration-handling/">memcached cache locks</a>.</p>
<p>4:25pm: Just re-hashing the same examples in different languages.  <img src='http://www.grepmymind.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>4:35pm: <a href="http://tangent.org/552/libmemcached.html">libmemcached</a> is a C/C++ client.  Has replicated ability.  You can store flags associated with the data in the byte category.  Most clients don&#8217;t allow you direct access to this.</p>
<p>4:48pm: When doing a multi-get it hashes each key to determine the servers where the data would be stored.  Once it knows that, the requests are made in parallel and as single-combined request to each server needed.</p>
<p>4:50pm: MySQL &amp; Memcached.  The MySQL uses the UDF API and libmemcached.  You have to install it by CREATE FUNCTION.  Most common method is to use memc_delete to remove the memcached data when data is written to the db.  An example is &#8220;select id, url, memc_set(concat(&#8216;feeds&#8217;, md5(url), url) from feeds;&#8221;  or &#8220;select memc_get(concat(&#8216;feeds&#8217;, md5(url));&#8221;  This could be helpful for when you store the entire row, and only the row, in memcache.  But for the most part, I don&#8217;t see the benefit of using this.  Of course, I&#8217;ve been known to be wrong before.</p>
<p>5:00pm:  There is memcached-tool which may assist with some basic stats/display commands.  It will eventually be what does the slab re-allocation.  libmmcached has memslap which may be useful for performance testing.  MRTG gives you decent graphs about what is happening on the server.</p>
<p>5:05pm:  1.2.5 release supports multi-interface support, UDP all the time, noreply, &amp; IPV6.  Noreply is kind of neat as it allows you to set keys and not have have a response sent back to the client.  It makes it a fire &amp; forget save to memcache.  My experience is that most people don&#8217;t verify that the data is really set to memcache anyway.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.grepmymind.com/2008/04/14/mysql-conf-2008-memcached-day-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>memcached PHP semaphore &amp; cache expiration handling</title>
		<link>http://www.grepmymind.com/2008/01/11/memcached-php-semaphore-cache-expiration-handling/</link>
		<comments>http://www.grepmymind.com/2008/01/11/memcached-php-semaphore-cache-expiration-handling/#comments</comments>
		<pubDate>Fri, 11 Jan 2008 21:01:41 +0000</pubDate>
		<dc:creator>Michael Tougeron</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[semaphore]]></category>

		<guid isPermaLink="false">http://www.grepmymind.com/2008/01/11/memcached-php-semaphore-cache-expiration-handling/</guid>
		<description><![CDATA[There are a lot of different ways that people use memcached and PHP. The most common of which is probably your basic set and get to cache data from your database. function get_my_data1&#40;&#41; &#123; &#160; &#160; $cache_id = &#34;mykey&#34;; &#160; &#160; $data = $memcache_obj-&#62;get&#40;$cache_id&#41;; &#160; &#160; if &#40; !$data &#41; &#123; &#160; &#160; &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>There are a lot of different ways that people use <a href="http://www.danga.com/memcached/">memcached</a> and <a href="http://php.net/manual/en/ref.memcache.php">PHP</a>.   The most common of which is probably your basic <a href="http://php.net/manual/en/function.Memcache-set.php">set </a> and <a href="http://php.net/manual/en/function.Memcache-get.php">get</a> to cache data from your database.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">function</span> get_my_data1<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$cache_id</span> = <span class="st0">&quot;mykey&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$data</span> = <span class="re0">$memcache_obj</span>-&gt;<span class="me1">get</span><span class="br0">&#40;</span><span class="re0">$cache_id</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> !<span class="re0">$data</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span> = get_data_from_db_function<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$memcache_obj</span>-&gt;<span class="me1">set</span><span class="br0">&#40;</span><span class="re0">$cache_id</span>, <span class="re0">$data</span>, <span class="re0">$sec_to_cache_for</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$data</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>But what if the query that&#8217;s going to hit the database is pretty intensive and you don&#8217;t want more than one user to hit the db at a time?  That&#8217;s easily handling via a <a href="http://en.wikipedia.org/wiki/Semaphore_(programming)">semaphore</a> lock.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">function</span> get_my_data2<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$cache_id</span> = <span class="st0">&quot;mykey&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$data</span> = <span class="re0">$memcache_obj</span>-&gt;<span class="me1">get</span><span class="br0">&#40;</span><span class="re0">$cache_id</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> !<span class="re0">$data</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// check to see if someone has already set the lock</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data_lock</span> = <span class="re0">$memcache_obj</span>-&gt;<span class="me1">get</span><span class="br0">&#40;</span><span class="re0">$cache_id</span> . <span class="st0">&#8216;_qry_lock&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re0">$data_lock</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$lock_counter</span> = <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// loop until you find that the lock has been released. &nbsp;that implies that the query has finished</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">do</span> <span class="kw1">while</span> <span class="br0">&#40;</span> <span class="re0">$data_lock</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// you may only want to wait for a specified period of time.</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// one second is usually sufficient since your goal is to always have sub-second response time</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// if you query takes more than 1 second, you should consider &quot;warming&quot; your cached data via a cron job</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re0">$lock_counter</span> &gt; <span class="re0">$max_time_to_wait</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$lock_failed</span> = <span class="kw2">true</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">break</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// you really want this to be a fraction of a second so the user waits as little as possible</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// for the simplicity of example, I&#8217;m using the sleep function.</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/sleep"><span class="kw3">sleep</span></a><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data_lock</span> = <span class="re0">$memcache_obj</span>-&gt;<span class="me1">get</span><span class="br0">&#40;</span><span class="re0">$cache_id</span> . <span class="st0">&#8216;_qry_lock&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// if the loop is completed, that either means the user waited for too long</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// or that the lock has been removed. &nbsp;try to get the cached data again; it should exist now</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span> = <span class="re0">$memcache_obj</span>-&gt;<span class="me1">get</span><span class="br0">&#40;</span><span class="re0">$cache_id</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re0">$data</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$data</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// set a lock for 2 seconds</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$memcache_obj</span>-&gt;<span class="me1">set</span><span class="br0">&#40;</span><span class="re0">$cache_id</span> . <span class="st0">&#8216;_qry_lock&#8217;</span>, <span class="kw2">true</span>, <span class="nu0">2</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span> = get_data_from_db_function<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$memcache_obj</span>-&gt;<span class="me1">set</span><span class="br0">&#40;</span><span class="re0">$cache_id</span>, <span class="re0">$data</span>, <span class="re0">$sec_to_cache_for</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// don&#8217;t forget to remove the lock</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$memcache_obj</span>-&gt;<span class="me1">delete</span><span class="br0">&#40;</span><span class="re0">$cache_id</span> . <span class="st0">&#8216;_qry_lock&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$data</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>More below the break &#8211;&gt;<span id="more-11"></span></p>
<p>Another good use of the semaphore locking is to set the expire time as part of the cached data and have an extended expire time set in memcache.  This allows you to have more control over what happens when the cached data becomes stale.  You can make it so that one user repopulates the cache while other users continue to get the existing cache until the first user has finished.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">function</span> get_my_data3<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$cache_id</span> = <span class="st0">&quot;mykey&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$data</span> = <span class="re0">$memcache_obj</span>-&gt;<span class="me1">get</span><span class="br0">&#40;</span><span class="re0">$cache_id</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// if there is cached data and the expire timestamp has already expired or is within the next 2 minutes</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// then we want the user to freshen up the cached data</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re0">$data</span> &amp;amp;&amp;amp; <span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#91;</span><span class="st0">&#8216;cache_expires_timestamp&#8217;</span><span class="br0">&#93;</span> &#8211; <a href="http://www.php.net/time"><span class="kw3">time</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> &lt; <span class="nu0">120</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// if the semaphore lock has already been set, just return the data like you normally would.</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re0">$memcache_obj</span>-&gt;<span class="me1">get</span><span class="br0">&#40;</span><span class="re0">$cache_id</span> . <span class="st0">&#8216;_expire_lock&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$data</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// now we want to set the lock and have the user freshen the data.</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$memcache_obj</span>-&gt;<span class="me1">set</span><span class="br0">&#40;</span><span class="re0">$cache_id</span> . <span class="st0">&#8216;_expire_lock&#8217;</span>, <span class="kw2">true</span>, <span class="nu0">2</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// by unsetting the data it will cause the data gather logic below to execute.</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/unset"><span class="kw3">unset</span></a><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> !<span class="re0">$data</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// be sure to include all of the semaphore logic from example 2</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// set the _qry_lock for 2 seconds</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$memcache_obj</span>-&gt;<span class="me1">set</span><span class="br0">&#40;</span><span class="re0">$cache_id</span> . <span class="st0">&#8216;_qry_lock&#8217;</span>, <span class="kw2">true</span>, <span class="nu0">2</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$raw_data</span> = get_data_from_db_function<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span><span class="br0">&#91;</span><span class="st0">&#8216;cache_expires_timestamp&#8217;</span><span class="br0">&#93;</span> = <a href="http://www.php.net/time"><span class="kw3">time</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span> + <span class="re0">$sec_to_cache_for</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span><span class="br0">&#91;</span><span class="st0">&#8216;cached_data&#8217;</span><span class="br0">&#93;</span> = <span class="re0">$raw_data</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$memcache_obj</span>-&gt;<span class="me1">set</span><span class="br0">&#40;</span><span class="re0">$cache_id</span>, <span class="re0">$data</span>, <span class="re0">$sec_to_cache_for</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// remove the _qry_lock</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$memcache_obj</span>-&gt;<span class="me1">delete</span><span class="br0">&#40;</span><span class="re0">$cache_id</span> . <span class="st0">&#8216;_qry_lock&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// remove the _expires_lock</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$memcache_obj</span>-&gt;<span class="me1">delete</span><span class="br0">&#40;</span><span class="re0">$cache_id</span> . <span class="st0">&#8216;_expires_lock&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$data</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>When you mash these functions together, you end up with a system where only one user every freshens the cache and/or hits the database with a specific query at a time.  There are a lot of other things that suddenly become available once you start thinking of memcached beyond just saving your db from hits.  You have things like session handling, smarty template caching, flags for per-server processing (e.g., clearing local file cache), and even as a temporary database.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.grepmymind.com/2008/01/11/memcached-php-semaphore-cache-expiration-handling/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

