<?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>MySQL Performance Blog &#187; memcached</title>
	<atom:link href="http://www.mysqlperformanceblog.com/category/memcached/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mysqlperformanceblog.com</link>
	<description>Everything about MySQL Performance</description>
	<lastBuildDate>Sat, 21 Nov 2009 03:11:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 2</title>
		<link>http://www.mysqlperformanceblog.com/2009/10/16/mysql_memcached_tyrant_part2/</link>
		<comments>http://www.mysqlperformanceblog.com/2009/10/16/mysql_memcached_tyrant_part2/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 16:00:41 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[NOSQL]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=1433</guid>
		<description><![CDATA[Part 1 of our series set-up our &#8220;test&#8221;  application and looked at boosting performance of the application by buffer MySQL with memcached.  Our test application is simple and requires only 3 basic operations per transaction 2 reads and 1 write.  Using memcached combined with MySQL we ended up nearly getting a 10X performance boost from [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/">Part 1</a> of our series set-up our &#8220;test&#8221;  application and looked at boosting performance of the application by buffer MySQL with memcached.  Our test application is simple and requires only 3 basic operations per transaction 2 reads and 1 write.  Using memcached combined with MySQL we ended up nearly getting a 10X performance boost from the application.  Now we are going to look at what we could achieve if we did not have to write to the database at all.  So let&#8217;s look at what happens if we push everything including writes into memcached.</p>
<p><img class="size-full wp-image-1427" title="Benchmarks if everything is in memcached" src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/10/db_right_option_html_m62d9ce6b.gif" alt="Benchmarks if everything is in memcached" width="641" height="335" /></p>
<p>Wow that&#8217;s shockingly fast isn&#8217;t it! I guess being completely in memory helps for this app.  What is very interesting is accessing 100% of the data in memcached gives very similar numbers to accessing 100% of the data in memory in the DB ( part 1 benchmarked a 4GB bp as being able to handle 7K TPS)&#8230; something is not 100% right here.  It stands to reason that memcached should be faster for this application then the DB.  Its just doing two gets via key and 1 set.  So why the similar numbers?</p>
<p>Well glad you asked.  It&#8217;s the API.  The api in this case was Cache::Memcached, by switching to using Cache::Memcached::Fast look what happens:</p>
<p><img class="size-full wp-image-1428" title="Memcached API - Fast" src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/10/db_right_option_html_m74e8a5a8.gif" alt="Memcached API - Fast" width="704" height="317" /></p>
<p>That is a nice jump in performance!</p>
<p>Using Memcached::Fast was kind of a mixed bag when looking at the benchmarks for mixing MySQL and Memcached in my tests:</p>
<p><img class="size-full wp-image-1421" title="Memcached Api's" src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/10/db_right_option_html_2ff88cd9.gif" alt="Sometimes Api changes can make a huge difference" width="667" height="340" /></p>
<p>In this case I think the Fast api was slower when working with MySQL with a 256m BP because the slower returns from memcached acted as a bottleneck to thin the demands on MySQL to write data, smoothing out the work load.  When we eliminate this bottleneck with the Fast api, MySQL gets hammered.  This type of thing happens a lot.  For example an application is CPU bound, so you add more processing power, but then you hit disks harder and  now your disk bound.</p>
<p>A couple of good things to remember here:  #1 resolving 1 bottleneck can open another bottleneck that is much worse.  #2  is to understand that not all API&#8217;s are created equal.  Additionally the configuration and setup that works well on one system may not work well on another.  Because of this people often leave lots of performance on the table.  Don&#8217;t just trust that your current API or config is optimal, test and make sure it fits your application.</p>
<p>So adding Memcached on top of MySQL for our test application can significantly boost performance. But you notice that if we were running 100% in memcached and could cut out MySQL we could get 2.5x more performance over a mixed solution and 100X over just stock MySQL.  As the number of writes against the database increase this gap will increase.  So let&#8217;s ditch the database!  But wait!  you need the DB for  persistence, right?</p>
<p>It depends.  A database may not be the best fit for every application.  There are several “NOSQL”  solutions out in the open source space that can give you some of the ease of a Memcached but with persistence most people use their database for.   Each application is different and understanding the application&#8217;s requirements is key to picking an appropriate solution.   I am going to look at several database alternatives over the next few months.  I need to start somewhere, so I decided to start with Tokyo Tyrant and Cabinet.    So stop in next time for part 3 of this series where we will focus on running the same tests against Tokyo Tyrant.</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;"><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">Wow that&#8217;s shockingly fast isn&#8217;t it! I guess being completely in memory helps for this app.  What is very interesting is accessing 100% of the data in memcached gives very similar numbers to accessing 100% of the data in memory in the DB&#8230; something is not 100% right here.  It stands to reason that memcached should be faster for this application then the DB, two gets via key and 1 set.  So why the similar numbers?</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Well glad you asked.  It&#8217;s the API.  The api in this case was Cache::Memcached, by switching to using Cache::Memcached::Fast look what happens:</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">That is a nice jump in performance!</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Using Memcached::Fast was kind of a mixed bag when looking at the benchmarks for mixing MySQL and Memcached in my tests:</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">In this case I think Fast was slower when working with MySQL with a 256m BP because the slower returns from memcached acted as a bottleneck to thin the demands on MySQL to write data, smoothing out the work load.  When we eliminate this bottleneck with the Fast api, MySQL gets hammered.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">A couple of good things to remember here:  #1 resolving 1 bottleneck can open another bottleneck that is much worse.  #2  is to understand that not all API&#8217;s are created equal.  Additionally the configuration and setup that works well on one system may not work well on another.  Because of this people often leave lots of performance on the table.  Don&#8217;t just trust that your current API or config is optimal, test and make sure it fits your application.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">So adding Memcached on top of MySQL for our test application can significantly boost performance. But you notice that if we were running 100% in memcached and could cut out MySQL we could get 2.5x more performance.  As the number of writes against the database increase this gap will increase.  So let&#8217;s ditch the database!  But wait!  you need the DB for  persistence, right?</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">It depends.  A database may not be the best fit for every application.  There are several “NOSQL”  solutions out in the open source space that can give you some of the ease of a Memcached but with persistence most people use their database for.   Each application is different and understanding the application&#8217;s requirements is key to picking an appropriate solution.   I am going to look at several database alternatives over the next few months.  I need to start somewhere, so I decided to start with Tokyo Tyrant and Cabinet.</p>
</div>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by matt |
      <a href="http://www.mysqlperformanceblog.com/2009/10/16/mysql_memcached_tyrant_part2/#comments">7 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/10/16/mysql_memcached_tyrant_part2/&amp;title=MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 2" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/10/16/mysql_memcached_tyrant_part2/&amp;title=MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 2" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/10/16/mysql_memcached_tyrant_part2/&amp;title=MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 2" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/10/16/mysql_memcached_tyrant_part2/&amp;T=MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 2" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/10/16/mysql_memcached_tyrant_part2/&amp;title=MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 2" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2009/10/16/mysql_memcached_tyrant_part2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 1</title>
		<link>http://www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/</link>
		<comments>http://www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 18:24:30 +0000</pubDate>
		<dc:creator>matt</dc:creator>
				<category><![CDATA[NOSQL]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=1419</guid>
		<description><![CDATA[All to often people force themselves into using a database like MySQL with no thought into whether if its the best solution to there problem. Why?  Because their other applications use it, so why not the new application?  Over the past couple of months I have been doing a ton of work for clients who [...]]]></description>
			<content:encoded><![CDATA[<p>All to often people force themselves into using a database like MySQL with no thought into whether if its the best solution to there problem. Why?  Because their other applications use it, so why not the new application?  Over the past couple of months I have been doing a ton of work for clients who use their database like most people use memcached .  Lookup a row based on a key, update the data in the row, stuff the row back in the database.  Rinse and repeat.  Sure these setups vary sometimes, throwing in a “lookup” via username, or even the rare count.  But for the most part they are designed to be simple.</p>
<p>A classic example is a simple online game.  An online game may only require that an application retrieve a single record from the database.  The record may contain all the vital stats for the game, be updated and stuffed back into the database.  You would be surprised how many people use this type of system as I run into this type of application frequently.  Keeping it simple, ensures that application is generally mean and lean and performs well.  The issue is even this simple design can start to have issues as the data size increases and you blow through your available memory.  Is there a better architecture?  Is there a way to get more scalability out of your database?  Is the database even the best place for this data?</p>
<p>I decided to walk through setting up a very simple application that does what I have seen many clients do.  Using this application I can then compare using MySQL to using MySQL + Memcached, and then to other solutions like Tokyo Tyrant or Cassandra.   My Application does the following:</p>
<p>A.)  read a row from a database based on an integer based primary key<br />
B.)  Update data from that row and replace the stored contents on disk<br />
C.)  Use the data from that row to lookup up a row in another table based on a text field ( called email address ).</p>
<p>Seems simple enough right?  My two tables each contain 5M rows of data.  let&#8217;s see what happens:</p>
<p><img class="size-full wp-image-1420" title="DB Fits into Memory" src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/10/db_right_option_html_1f7313bd.gif" alt="DB Fits into Memory" width="619" height="353" /></p>
<p><img class="size-full wp-image-1429" title="Chart of numbers" src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/10/db_right_option_html_m767bebf7.gif" alt="Chart of TPS for benchmark application" width="257" height="69" /></p>
<p>You can see a dramatic drop off in performance as my data falls out of memory, that&#8217;s not cool is it?  After all database sizes tend to always grow and very rarely shrink.  Which leads to a challenge faced by almost everyone how do you maintain your performance in the face of increasing data size?</p>
<p>Here is where people start to scratch their heads.  They naturally assume they need to scale more, we need more memory!   If performance sucks, we must need more.  So here comes the bigger boxes, the read-only slaves,  the complex sharding systems, the discussions on cluster, more memcached.  We need to cover up the databases inefficiencies to ensure that our application scales.</p>
<p>The problem is for some applications, we are fixing symptoms, not the problem itself.  No matter how much you want it to fit,  some things may not work (like the Godfather 3).    The issue is people assume that data storage has to be in the database.  “It&#8217;s data, it needs to go into the database.” is often the battle cry.   But hold on to your hat,  I  am going to shock you.  For some applications, putting your data in the database is silly.  Yes the guy who blogs on bigdbahead.com and is writing this on the mysqlperformanceblog is saying you may not want to use a database.  Heresy I know!  But for many of us we already accept storing data ( at least temporarily ) outside the DB.  Think memcached.</p>
<p>Almost everyone loves memcached, it&#8217;s simple, fast, and just works.  When your dataset exceeds your memory limitations or the database can simply not keep up any more this solution can really boost performance.  I know you&#8217;re thinking my simple key lookup should really benefit from memcached. So let&#8217;s try it!  I took the simple app I created that reads two rows, and update one of them to read from memcached if available, remove on update, and read from the db only when required.  I tested with a memcached size of 1GB, 2GB, and 4GB.  For these tests I left Innodb with a 256M buffer pool, or roughly with 9% of the total data in memory.</p>
<p>let&#8217;s look at the 1GB Setting:</p>
<div class="mceTemp mceIEcenter">
<dl id="attachment_1425" class="wp-caption aligncenter" style="width: 636px;">
<dt class="wp-caption-dt"><img class="size-full wp-image-1425" title="Ensure you have enough memory " src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/10/db_right_option_html_m5daa4d5f.gif" alt="Ensure you have enough memory for memcached" width="626" height="320" /> </dt>
</dl>
</div>
<p>What, a performance regression?  But we threw more memory at it!!   How can that be!</p>
<p>Memcached is not a cure all.  I have talked to many client&#8217;s who say “we will just throw memcached at it”.   Sometimes an app will scream other times it won&#8217;t&#8230; and yet others require lots and lots of memory allocated to memcached to be successful.    This application selects a random # between 1 and 2 Million and looks up the result via that key.  It then uses data from that random row to look up a second piece of information via email address.  Because the entire dataset  is about 4GB and only 1G is in memcached, I keep pushing data out of memcached to make room for new records I am reading from the database. Remember memcached needs repeatability to be helpful.   I am still getting a really solid # of hits in memcached, but the # of writes in MySQL coupled with the still large # of reads takes its toll.  Another place where I have seen this kill clients is in apps that do some sequential scanning and do not have enough memory for memcached.  For instance, if you have 1,000,000 rows of data, but enough memory to only store 500,000 rows&#8230; sequentially accessing this data will destroy the use of cache:</p>
<p>get record 1, miss, read from disk, cache record 1<br />
….<br />
get record 500,001, miss, read from disk, expunge record 1, cache record 500,001<br />
&#8230;.<br />
get record 1, miss, read from disk, expunge record 500,001, cache record 1</p>
<p>you keep overwriting the cache before you can use it.  So here the complexity of adding memcached hurts us, because the cache is not actually buying us anything.</p>
<p>Now bumping this up to 2GB actually makes the TPS jump around a lot, sometimes hitting 400 or 500 TPS and other times hitting as high as 1800 TPS.  My guess is the movement is caused by the random #&#8217;s being generated and simply the luck of the draw.</p>
<p>Finally let&#8217;s look when we have 4GB of memory allocated to memcached (full dataset fits ):</p>
<p><img class="size-full wp-image-1423" title="Transactions with and without Memcached" src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/10/db_right_option_html_m2dc4c2b4.gif" alt="Transactions with and without Memcached" width="625" height="331" /></p>
<p>Here you can see that our “transactions”  per second for this app increased almost 10Xby using memcached.  The TPS I get here vary from 1100 TPS to just under 2000TPS with the average around 1400TPS.   I think we would all be very happy if we could get a 10X performance boost from your application.</p>
<p>But wouldn&#8217;t it be great if we could get more?  I mean our reads are going pretty fast, but our writes leave a lot to be desired:</p>
<div class="mceTemp mceIEcenter"><img class="size-full wp-image-1424" title="Read -vs- write times " src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/10/db_right_option_html_m4d18b08e.gif" alt="Read -vs- write times with memcached + mysql mixed" width="648" height="286" /></div>
<p>Over 17 MS to do an update.  Wouldn&#8217;t be great to just eliminate all the updates as well?  What sort of throughput would we get?   I will show you in part 2.  Part 2 of this post will talk about performance in a 100% pure memcached environment. Part 3 will focus on these same benchmarks in Tokyo tyrant.</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;"><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">All to often people force themselves into using a database like MySQL with no thought into whether if its the best solution to there problem. Why?  Because their other applications use it, so why not the new application?  Over the past couple of months I have been doing a ton of work for clients who use their database like most people use memcached .  Lookup a row based on a key, update the data in the row, stuff the row back in the database.  Rinse and repeat.  Sure these setups vary sometimes, throwing in a “lookup” via username, or even the rare count.  But for the most part they are designed to be simple.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">A classic example is a simple online game.  An online game may only require that an application retrieve a single record from the database.  The record may contain all the vital stats for the game, be updated and stuffed back into the database.  You would be surprised how many people use this type of system as I run into this type of application frequently.  Keeping it simple, ensures that application is generally mean and lean and performs well.  The issue is even this simple design can start to have issues as the data size increases and you blow through your available memory.  Is there a better architecture?  Is there a way to get more scalability out of your database?  Is the database even the best place for this data?</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">I decided to walk through setting up a very simple application that does what I have seen many clients do.  Using this application I can then compare using MySQL to using MySQL + Memcached, and then to other solutions like Tokyo Tyrant or Cassandra.   My Application does the following:</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">A.)  read a row from a database based on an integer based primary key</p>
<p style="margin-bottom: 0in;">B.)  Update data from that row and replace the stored contents on disk</p>
<p style="margin-bottom: 0in;">C.)  Use the data from that row to lookup up a row in another table based on a text field ( called email address ).</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Seems simple enough right?  My two tables each contain 5M rows of data.  let&#8217;s see what happens:</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">You can see a dramatic drop off in performance as my data falls out of memory, that&#8217;s not cool is it?  After all database sizes tend to always grow and very rarely shrink.  Which leads to a challenge faced by almost everyone how do you maintain your performance in the face of increasing data size?</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Here is where people start to scratch their heads.  They naturally assume they need to scale more, we need more memory!   If performance sucks, we must need more.  So here comes the bigger boxes, the read-only slaves,  the complex sharding systems, the discussions on cluster, more memcached.  We need to cover up the databases inefficiencies to ensure that our application scales.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">The problem is for some applications, we are fixing symptoms, not the problem itself.  No matter how much you want it to fit,  somethings may not work (like the Godfather 3).    The issue is people assume that data storage has to be in the database.  “It&#8217;s data, it needs to go into the database.” is often the battle cry.   But hold on to your hat,  I  am going to shock you.  For some applications, putting your data in the database is silly.  Yes the guy who blogs on bigdbahead.com and is writing this on the mysqlperformanceblog is saying you may not want to use a database.  Heresy I know!  But for many of us we already accept storing data ( at least temporarily ) outside the DB.  Think memcached.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Almost everyone loves memcached, it&#8217;s simple, fast, and just works.  When your dataset exceeds your memory limitations or the database can simply not keep up any more this solution can really boost performance.  I know you&#8217;re thinking my simple key lookup should really benefit from memcached. So let&#8217;s try it!  I took the simple app I created that reads two rows, and update one of them to read from memcached if available, remove on update, and read from the db only when required.  I tested with a memcached size of 1GB, 2GB, and 4GB.  For these tests I left Innodb with a 256M buffer pool, or roughly with 9% of the total data in memory.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">let&#8217;s look at the 1GB Setting:</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">What, a performance regression?  But we threw more memory at it!!   How can that be!</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Memcached is not a cure all.  I have talked to many client&#8217;s who say “we will just throw memcached as it”.   Sometimes an app will scream other times it won&#8217;t&#8230; and yet others require lots and lots of memory allocated to memcached to be successful.    This application selects a random # between 1 and 2 Million and looks up the result via that key.  It then uses data from that random row to look up a second piece of information via email address.  Because the entire dataset  is about 4GB and only 1G is in memcached, I keep pushing data out of memcached to make room for new records I am reading from the database. Remember memcached needs repeatability to be helpful.   I am still getting a really solid # of hits in memcached, but the # of writes in MySQL coupled with the still large # of reads takes its toll.  Another place where I have seen this kill clients is in apps that do some sequential scanning and do not have enough memory for memcached.  For instance, if you have 1,000,000 rows of data, but enough memory to only store 500,000 rows&#8230; sequentially accessing this data will destroy the use of cache:</p>
<p style="margin-bottom: 0in;">
<ul>
<li>
<p style="margin-bottom: 0in;">get record 1, miss, read from 	disk, cache record 1</p>
</li>
<li>
<p style="margin-bottom: 0in;">….</p>
</li>
<li>
<p style="margin-bottom: 0in;">get record 500,001, miss, read 	from disk, expunge record 1, cache record 500,001</p>
</li>
<li>
<p style="margin-bottom: 0in;">&#8230;.</p>
</li>
<li>
<p style="margin-bottom: 0in;">get record 1, miss, read from 	disk, expunge record 500,001, cache record 1</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">you keep overwriting the cache before 	you can use it.  So here the complexity of adding memcached hurts 	us, because the cache is not actually buying us anything.</p>
</li>
</ul>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Now bumping this up to 2GB actually makes the TPS jump around a lot, sometimes hitting 400 or 500 TPS and other times hitting as high as 1800 TPS.  My guess is the movement is caused by the random #&#8217;s being generated and simply the luck of the draw.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Finally let&#8217;s look when we have 4GB of memory allocated to memcached (full dataset fits ):</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Here you can see that our “transactions”  per second for this app increased almost 10Xby using memcached.  The TPS I get here vary from 1100 TPS to just under 2000TPS with the average around 1400TPS.   I think we would all be very happy if we could get a 10X performance boost from your application.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">But wouldn&#8217;t it be great if we could get more?  I mean our reads are going pretty fast, but our writes leave a lot to be desired:</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Over 17 MS to do an update.  Wouldn&#8217;t be great to just eliminate all the updates as well?  What sort of throughput would we get?</p>
</div>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by matt |
      <a href="http://www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/#comments">13 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/&amp;title=MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 1" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/&amp;title=MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 1" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/&amp;title=MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 1" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/&amp;T=MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 1" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/&amp;title=MySQL-Memcached or NOSQL Tokyo Tyrant &#8211; part 1" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2009/10/15/mysql-memcached-or-nosql-tokyo-tyrant-part-1/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Maatkit Now Supports Memcached</title>
		<link>http://www.mysqlperformanceblog.com/2009/07/24/maatkit-now-supports-memcached/</link>
		<comments>http://www.mysqlperformanceblog.com/2009/07/24/maatkit-now-supports-memcached/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 17:33:15 +0000</pubDate>
		<dc:creator>Ryan Lowe</dc:creator>
				<category><![CDATA[announce]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[Maatkit]]></category>
		<category><![CDATA[Memcached Optimization]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=753</guid>
		<description><![CDATA[Have you ever wondered how optimized your Memcached installation is?  There is a common misconception that one doesn't have to think too deeply about Memcached performance, but that is not true.  If your setup is inefficient, you could:

Burn Memory
Waste Network Round-Trips
Store Keys That Never Get Retrieved
Have a Low Cache Hit Ratio (i.e. query [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wondered how optimized your Memcached installation is?  There is a common misconception that one doesn't have to think too deeply about Memcached performance, but that is not true.  If your setup is inefficient, you could:</p>
<ul>
<li>Burn Memory</li>
<li>Waste Network Round-Trips</li>
<li>Store Keys That Never Get Retrieved</li>
<li>Have a Low Cache Hit Ratio (i.e. query MySQL too much)</li>
<li>Suffer a fate too horrible to contemplate.</li>
</ul>
<p>Percona does a lot of <a href="http://www.percona.com/services/memcached.html">consulting around Memcached</a>, so we try to take a quantitative, scientific approach to measuring memcached performance, just like everything else we do.</p>
<p><a href="http://www.danga.com/memcached/">memcached</a> is basically a key-value in-memory database, so it works well to analyze its traffic with Maatkit's mk-query-digest tool.  You can now use mk-query-digest to get "query event" information and report on memcached effectiveness.  As far as we know, this is the first and only tool of its kind.</p>
<p>The output is very similar to that which would be displayed for MySQL queries.  Commands are fingerprinted so that similar things can be aggregated together.  The output begins with an overall report:</p>
<div class="igBar"><span id="lcode-4"><a href="#" onclick="javascript:showPlainTxt('code-4'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-4">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Overall: <span style="color:#800000;color:#800000;">2</span>.69k total, <span style="color:#800000;color:#800000;">113</span> unique, <span style="color:#800000;color:#800000;">28</span>.<span style="color:#800000;color:#800000;">36</span> QPS, <span style="color:#800000;color:#800000;">0</span>.04x concurrency _________</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; total&nbsp; &nbsp; &nbsp;min&nbsp; &nbsp; &nbsp;max&nbsp; &nbsp; &nbsp;avg&nbsp; &nbsp; &nbsp;<span style="color:#800000;color:#800000;">95</span>%&nbsp; stddev&nbsp; median</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Exec time&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4s&nbsp; &nbsp; 11us&nbsp; &nbsp; &nbsp; 2s&nbsp; &nbsp; &nbsp;1ms&nbsp; &nbsp;403us&nbsp; &nbsp; 43ms&nbsp; &nbsp; 28us</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Hosts&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#800000;color:#800000;">2694</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Time range&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#800000;color:#800000;">2009</span>-<span style="color:#800000;color:#800000;">06</span>-<span style="color:#800000;color:#800000;">11</span> <span style="color:#800000;color:#800000;">21</span>:<span style="color:#800000;color:#800000;">54</span>:<span style="color:#800000;color:#800000;">47</span>.<span style="color:#800000;color:#800000;">089744</span> to <span style="color:#800000;color:#800000;">2009</span>-<span style="color:#800000;color:#800000;">06</span>-<span style="color:#800000;color:#800000;">11</span> <span style="color:#800000;color:#800000;">21</span>:<span style="color:#800000;color:#800000;">56</span>:<span style="color:#800000;color:#800000;">22</span>.<span style="color:#800000;color:#800000;">136503</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># bytes&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#800000;color:#800000;">7</span>.34M&nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#800000;color:#800000;">0</span> <span style="color:#800000;color:#800000;">265</span>.49k&nbsp; &nbsp;<span style="color:#800000;color:#800000;">2</span>.79k&nbsp; &nbsp;<span style="color:#800000;color:#800000;">4</span>.71k&nbsp; <span style="color:#800000;color:#800000;">16</span>.50k&nbsp; &nbsp;<span style="color:#800000;color:#800000;">51</span>.<span style="color:#800000;color:#800000;">63</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># key print&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#800000;color:#800000;">2694</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; &nbsp;<span style="color:#800000;color:#800000;">4</span>% <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">119</span><span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; Memc_delete</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; &nbsp;<span style="color:#800000;color:#800000;">6</span>% <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">163</span><span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; Memc_error</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; <span style="color:#800000;color:#800000;">77</span>% <span style="color:#006600; font-weight:bold;">&#40;</span>2k<span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; &nbsp;Memc_get</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; &nbsp;<span style="color:#800000;color:#800000;">0</span>% <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">4</span><span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; &nbsp; Memc_incr</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; <span style="color:#800000;color:#800000;">15</span>% <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">415</span><span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; Memc_miss</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; <span style="color:#800000;color:#800000;">17</span>% <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">483</span><span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; Memc_set </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>We can see that 77% of commands (cmds) were get, 17% set, 4% delete and 4 incr (increment) cmds.  At present, Memc_error only refers to gets (or, retrieval cmds in general) that were interrupted (some things are TODO).  Memc_miss is for any cmd that resulted in a NOT_FOUND result.  So in this case, 15% of all cmds tried to do something with a nonexistent key.</p>
<p>The next bit aggregates similar queries into classes and prints out the most expensive ones.  Here's the top one:</p>
<div class="igBar"><span id="lcode-5"><a href="#" onclick="javascript:showPlainTxt('code-5'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-5">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Query <span style="color:#800000;color:#800000;">1</span>: <span style="color:#800000;color:#800000;">7</span>.<span style="color:#800000;color:#800000;">06</span> QPS, <span style="color:#800000;color:#800000;">0</span>.04x concurrency, ID 0x7AFBE9433477C7BC at byte <span style="color:#800000;color:#800000;">5983429</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># This item is included in the report because it matches --limit.</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pct&nbsp; &nbsp;total&nbsp; &nbsp; &nbsp;min&nbsp; &nbsp; &nbsp;max&nbsp; &nbsp; &nbsp;avg&nbsp; &nbsp; &nbsp;<span style="color:#800000;color:#800000;">95</span>%&nbsp; stddev&nbsp; median</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Count&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#800000;color:#800000;">24</span>&nbsp; &nbsp; &nbsp;<span style="color:#800000;color:#800000;">657</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Exec time&nbsp; &nbsp; &nbsp;<span style="color:#800000;color:#800000;">87</span>&nbsp; &nbsp; &nbsp; 3s&nbsp; &nbsp; 19us&nbsp; &nbsp; &nbsp; 2s&nbsp; &nbsp; &nbsp;5ms&nbsp; &nbsp; &nbsp;1ms&nbsp; &nbsp; 87ms&nbsp; &nbsp; 31us</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Hosts&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#800000;color:#800000;">1</span> <span style="color:#800000;color:#800000;">127</span>.<span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">1</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Time range <span style="color:#800000;color:#800000;">2009</span>-<span style="color:#800000;color:#800000;">06</span>-<span style="color:#800000;color:#800000;">11</span> <span style="color:#800000;color:#800000;">21</span>:<span style="color:#800000;color:#800000;">54</span>:<span style="color:#800000;color:#800000;">48</span>.<span style="color:#800000;color:#800000;">050834</span> to <span style="color:#800000;color:#800000;">2009</span>-<span style="color:#800000;color:#800000;">06</span>-<span style="color:#800000;color:#800000;">11</span> <span style="color:#800000;color:#800000;">21</span>:<span style="color:#800000;color:#800000;">56</span>:<span style="color:#800000;color:#800000;">21</span>.<span style="color:#800000;color:#800000;">669302</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># bytes&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#800000;color:#800000;">38</span>&nbsp; &nbsp;<span style="color:#800000;color:#800000;">2</span>.79M&nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#800000;color:#800000;">0</span>&nbsp; &nbsp;<span style="color:#800000;color:#800000;">4</span>.75k&nbsp; &nbsp;<span style="color:#800000;color:#800000;">4</span>.35k&nbsp; &nbsp;<span style="color:#800000;color:#800000;">4</span>.71k&nbsp; &nbsp;<span style="color:#800000;color:#800000;">1</span>.31k&nbsp; &nbsp;<span style="color:#800000;color:#800000;">4</span>.71k</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># key print&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#800000;color:#800000;">1</span> TEST_KEY</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; <span style="color:#800000;color:#800000;">17</span>% <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">114</span><span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; Memc_error</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># <span style="color:#800000;color:#800000;">100</span>% <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;color:#800000;">657</span><span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; Memc_get</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Query_time distribution</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; &nbsp;1us</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; 10us&nbsp; ################################################################</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># 100us&nbsp; #############</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; &nbsp;1ms&nbsp; ####</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; 10ms</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># 100ms</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; &nbsp; 1s&nbsp; #</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#&nbsp; 10s+</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">get TEST_KEY\G </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Interestingly, apparently 17% of all "get TEST_KEY" were interrupted (Memc_error), probably by the TCP connection being closed client-side.</p>
<p>You'll notice 100% Memc_get.  This is a result of the default --report and --group-by, which is "fingerprint" just like for slow query logs.  So the fingerprint for this event is "get TEST_KEY" and since the cmd is "get", 100% Memc_get.  There's another way to aggregate -- by the fingerprinted key, omitting the verb (get/set/etc).  To do this, you'd specify key_print as the group-by value.  More details are below.</p>
<p>This feature is still in beta.  Some things are TODO; the report format could be cleaned up a little, etc.  But we're releasing early and often, and we're calling on the community to help us out with testing!  Here's how:</p>
<ol>
<li>Get the latest mk-query-digest</li>
<li>Capture memcached network traffic with tcpdump</li>
<li>Parse memcached network traffic with mk-query-digest</li>
<li>Ponder the results, or consider a different --report option</li>
</ol>
<p>In code:</p>
<div class="igBar"><span id="lcode-6"><a href="#" onclick="javascript:showPlainTxt('code-6'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-6">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">wget&nbsp; http:<span style="color:#FF9933; font-style:italic;">//maatkit.googlecode.com/svn/trunk/mk-query-digest/mk-query-digest</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">sudo tcpdump -s <span style="color:#800000;color:#800000;">65535</span> -x -n -q -tttt -i eth0 port <span style="color:#800000;color:#800000;">11211</span>&amp;gt; memc_tcpdump.<span style="">txt</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mk-query-digest --type memcached memc_tcpdump.<span style="">txt</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Depending on what you're interested in, you may want to try these other reports:</p>
<ul>
<li><strong>--report key_print:</strong> Group events by a fingerprinted version of keys.  So "get user_123" and "set user_456" are grouped together because the key_print for both is "user_?".  Doing this, per-class results will have various percentages for Memc_get, Memc_set, etc. instead of 100% Memc_cmd like above.</li>
<li><strong>--report key:</strong> Like key_print but the keys are not fingerprinted so the two examples above are different classes because "user_123" != "user_456".  This would allow you to see per-key stats.  Maybe, for example, how often a certain key is get'ed in comparison to other keys.  (I.e. "what's the most popular get'ed or set'ed key" etc.)</li>
<li><strong>--report cmd:</strong> Group events by cmd.  So "get user_123" and "get whatever" are grouped together because both are "get" cmds.  You may want to do this to see, for example, what percentage of get cmds miss, i.e. result in NOT_FOUND.</li>
</ul>
<p>These instructions could change in the future -- this blog post is not authoritative documentation.  The most current documentation is always embedded in the tool itself, and is readable with perldoc!  Let us know what you think.  Please use the <a href="http://groups.google.com/group/maatkit-discuss">Maatkit mailing list</a> and and post bug reports on <a href="http://code.google.com/p/maatkit" target="#">Google Code</a>.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Ryan Lowe |
      <a href="http://www.mysqlperformanceblog.com/2009/07/24/maatkit-now-supports-memcached/#comments">9 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/07/24/maatkit-now-supports-memcached/&amp;title=Maatkit Now Supports Memcached" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/07/24/maatkit-now-supports-memcached/&amp;title=Maatkit Now Supports Memcached" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/07/24/maatkit-now-supports-memcached/&amp;title=Maatkit Now Supports Memcached" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/07/24/maatkit-now-supports-memcached/&amp;T=Maatkit Now Supports Memcached" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/07/24/maatkit-now-supports-memcached/&amp;title=Maatkit Now Supports Memcached" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2009/07/24/maatkit-now-supports-memcached/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>A quick way to get memcached status</title>
		<link>http://www.mysqlperformanceblog.com/2008/11/26/a-quick-way-to-get-memcached-status/</link>
		<comments>http://www.mysqlperformanceblog.com/2008/11/26/a-quick-way-to-get-memcached-status/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 02:32:54 +0000</pubDate>
		<dc:creator>Baron Schwartz</dc:creator>
				<category><![CDATA[memcached]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=547</guid>
		<description><![CDATA[There are all sorts of different interfaces to memcached, but you don't need any of them to make requests from the command line, because its protocol is so simple.  Try this, assuming it's running on the usual port on the local machine:
PLAIN TEXT
CODE:




echo stats &#124; nc 127.0.0.1 11211


STAT pid 22020


STAT uptime 3689364


STAT time 1227753109


STAT [...]]]></description>
			<content:encoded><![CDATA[<p>There are all sorts of different interfaces to memcached, but you don't need any of them to make requests from the command line, because its protocol is so simple.  Try this, assuming it's running on the usual port on the local machine:</p>
<div class="igBar"><span id="lcode-10"><a href="#" onclick="javascript:showPlainTxt('code-10'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-10">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">echo stats | nc <span style="color:#800000;color:#800000;">127</span>.<span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">1</span> <span style="color:#800000;color:#800000;">11211</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT pid <span style="color:#800000;color:#800000;">22020</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT uptime <span style="color:#800000;color:#800000;">3689364</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT time <span style="color:#800000;color:#800000;">1227753109</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT version <span style="color:#800000;color:#800000;">1</span>.<span style="color:#800000;color:#800000;">2</span>.<span style="color:#800000;color:#800000;">5</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT pointer_size <span style="color:#800000;color:#800000;">64</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT rusage_user <span style="color:#800000;color:#800000;">4543</span>.<span style="color:#800000;color:#800000;">071348</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT rusage_system <span style="color:#800000;color:#800000;">8568</span>.<span style="color:#800000;color:#800000;">293421</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT curr_items <span style="color:#800000;color:#800000;">139897</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT total_items <span style="color:#800000;color:#800000;">51710845</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT bytes <span style="color:#800000;color:#800000;">360147055</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT curr_connections <span style="color:#800000;color:#800000;">40</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT total_connections <span style="color:#800000;color:#800000;">66762</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT connection_structures <span style="color:#800000;color:#800000;">327</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT cmd_get <span style="color:#800000;color:#800000;">319992973</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT cmd_set <span style="color:#800000;color:#800000;">51710845</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT get_hits <span style="color:#800000;color:#800000;">280700485</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT get_misses <span style="color:#800000;color:#800000;">39292488</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT evictions <span style="color:#800000;color:#800000;">849165</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT bytes_read <span style="color:#800000;color:#800000;">141320046298</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT bytes_written <span style="color:#800000;color:#800000;">544357801590</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT limit_maxbytes <span style="color:#800000;color:#800000;">402653184</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">STAT threads <span style="color:#800000;color:#800000;">4</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">END </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Here's an easy "top" emulator for memcached:</p>
<div class="igBar"><span id="lcode-11"><a href="#" onclick="javascript:showPlainTxt('code-11'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-11">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">watch <span style="color:#CC0000;">"echo stats | nc 127.0.0.1 11211"</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>If you don't have netcat (nc), you can also use <a href="http://tldp.org/LDP/abs/html/devref1.html">Bash's built-in /proc/tcp magic</a> if it's enabled.  Anything that can push a couple of characters to a TCP port and print the result to stdout will work.  Or you can use something like this, if you must do it via PHP:</p>
<div class="igBar"><span id="lcode-12"><a href="#" onclick="javascript:showPlainTxt('code-12'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-12">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">watch <span style="color:#CC0000;">'php -r '</span><span style="color:#CC0000;">"'"</span><span style="color:#CC0000;">'$m=new Memcache;$m-&gt;connect(&quot;127.0.0.1&quot;, 11211);print_r($m-&gt;getstats());'</span><span style="color:#CC0000;">"'"</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Baron Schwartz |
      <a href="http://www.mysqlperformanceblog.com/2008/11/26/a-quick-way-to-get-memcached-status/#comments">One comment</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2008/11/26/a-quick-way-to-get-memcached-status/&amp;title=A quick way to get memcached status" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2008/11/26/a-quick-way-to-get-memcached-status/&amp;title=A quick way to get memcached status" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2008/11/26/a-quick-way-to-get-memcached-status/&amp;title=A quick way to get memcached status" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2008/11/26/a-quick-way-to-get-memcached-status/&amp;T=A quick way to get memcached status" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2008/11/26/a-quick-way-to-get-memcached-status/&amp;title=A quick way to get memcached status" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2008/11/26/a-quick-way-to-get-memcached-status/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
