<?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>某人的栖息地 &#187; memcache</title>
	<atom:link href="http://www.ooso.net/tag/memcache/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ooso.net</link>
	<description>Linux + Apache + Mysql + Php + Flash</description>
	<lastBuildDate>Thu, 19 Jan 2012 01:21:44 +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>关于“facebook的memcached实战”小记</title>
		<link>http://www.ooso.net/archives/558</link>
		<comments>http://www.ooso.net/archives/558#comments</comments>
		<pubDate>Thu, 29 Apr 2010 16:38:07 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/?p=558</guid>
		<description><![CDATA[上周挤到QCon的会场里，听了两场 —— Facebook的Memcached实战，以及Twitter 的可伸缩性数据架构。当时对facebook超大规模使用memcached印象很深刻，只可惜到现在也没见到这个的ppt。平时用php比较多，因此听闻同样使着php的facebook讲memcached，有些小小的感触，记录下来。
更高效的序列化函数
php有两个memcache扩展，默认都是使用php自带的序列化函数serialize来存储数组或对象。但是serialize最为人诟病的就是速度慢，序列化之后占用空间大。由于facebook已经在memcached里保存了200T字节的数据，因此序列化函数即便作出的百分之一的优化对它来说都是个不小的收益。他们发粪涂墙在thrift的binary协议基础上搞出了一个fb_serialize，据称这个序列化方法能快上3倍，快倒算了，还能节省30%空间， 200T字节的数据能节省出30%，简直就是传说中的银弹啊，这让php官方的开发人员们情何以堪？

				<span class="readmore"><a href="http://www.ooso.net/archives/558" title="关于“facebook的memcached实战”小记">阅读全文（1275字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>上周挤到QCon的会场里，听了两场 —— Facebook的<a href="/tag/memcache">Memcached</a>实战，以及Twitter 的可伸缩性数据架构。当时对facebook超大规模使用memcached印象很深刻，只可惜到现在也没见到这个的ppt。平时用php比较多，因此听闻同样使着php的facebook讲memcached，有些小小的感触，记录下来。</p>
<h2>更高效的序列化函数</h2>
<p>php有两个memcache扩展，默认都是使用php自带的序列化函数serialize来存储数组或对象。但是serialize最为人诟病的就是速度慢，序列化之后占用空间大。由于facebook已经在memcached里保存了200T字节的数据，因此序列化函数即便作出的百分之一的优化对它来说都是个不小的收益。他们发粪涂墙在thrift的binary协议基础上搞出了一个fb_serialize，据称这个序列化方法能快上3倍，快倒算了，还能节省30%空间， 200T字节的数据能节省出30%，简直就是传说中的银弹啊，这让php官方的开发人员们情何以堪？</p>
<p>facebook目前已经开源了thrift，其中自带了一个thrift协议的php扩展，但是这些代码里没有找到传说中的fb_serialize，我倒是从最近他们放出来<a href="http://github.com/facebook/hiphop-php">hiphop-php</a>里找到了这部分代码，哪位大侠去扒拉扒拉弄出来做成php扩展造福广大群众？</p>
<p>作为备选方案，我推荐<a href="/archives/538">igbinary</a>，这也是一个binary的序列化方法。在上次的测试结果中，它甚至能节约50%的存储空间，速度也是稳超php原生的序列化方法，搞不好facebook换了这个序列化方法能省下更多的内存来？</p>
<p>节约每个item的存储空间有什么好处？我个人认为一个是省钱，另外一个就是能够带来速度上的提升。我们平常碰到稍大一点的item都得用gzip压的妥妥贴贴的才送到memcached里，网络传输的开销小了，这是实实在在的性能提升。何乐而不为？</p>
<h2>mcproxy</h2>
<p>mcproxy = memcached + proxy。facebook的机房遍布各洲，利用mcproxy来进行跨机房的同步或分发，全球制霸，指着太阳就能等到那天了。一般的互联网企业还真用不上这玩意，规模还没上去的时候，这些乱七八糟的只会拖后腿。facebook还没开源mcproxy，但是我找到两个替代品：</p>
<ol>
<ul>
<li><a href="http://code.google.com/p/memagent/">memagent</a> is a simple but useful proxy program for memcached servers. </li>
<li><a href="http://code.google.com/p/moxi/">moxi</a> = memcached + integrated proxy</li>
</ul>
</ol>
<p>从项目描述来看，moxi最接近facebook介绍的mcproxy，成熟度也比较高。</p>
<h2>数据的一致性</h2>
<p>Marc Kwiatkowski在会场上用大篇幅的ppt和大量的动画来阐述这个问题，他们用了很多额外的手段来解决在跨机房情况下因为延时问题造成的脏数据。这一段看着挺晕，但是我们联想到facebook用到的多级cache技术: 本地全局变量 + apc + memcache，不难理解这样做颇有些道理，这相当于用memcache实现了一个版本控制系统。</p>
<p>我还是很晕这段ppt。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/558/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>igbinary vs serialize vs json_encode</title>
		<link>http://www.ooso.net/archives/538</link>
		<comments>http://www.ooso.net/archives/538#comments</comments>
		<pubDate>Sun, 18 Apr 2010 15:01:58 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/archives/538</guid>
		<description><![CDATA[最近看到memcached扩展支持额外的序列化方式 &#8212; igbinary，这是一个未收录到pecl的php扩展，它提供的两个主要方法：


igbinary_serialize

				<span class="readmore"><a href="http://www.ooso.net/archives/538" title="igbinary vs serialize vs json_encode">阅读全文（1557字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>最近看到<a href="http://pecl.php.net/memcached">memcached</a>扩展支持额外的序列化方式 &#8212; <a href="http://github.com/phadej/igbinary">igbinary</a>，这是一个未收录到pecl的php扩展，它提供的两个主要方法：
<ol>
<ul>
<li>igbinary_serialize</li>
<li>igbinary_unserialize</li>
</ul>
</ol>
<p>据称可以用它来代替php自带的序列化函数serialize，性能更好，而且占用的字节数也更少。下面我就 igbinary ，serialize ，json_encode三者的性能做了一个简单的测试。</p>
<h2>测试</h2>
<p>以一个包含1000000个元素的数组做为原始数据，分别以json, serialize, igbinary进行序列化和反向操作。</p>
<pre><code>&lt;?php
ini_set('memory_limit', '512m');
$array = array_fill(0, 1000000, rand(1, 9999));

$start = microtime(true);
$export = json_encode($array);
$end = microtime(true);
$duration = $end - $start;
print('JSON Encode: ' . $duration . PHP_EOL);

$start = microtime(true);
$import = json_decode($export);
$end = microtime(true);
$duration = $end - $start;
print('JSON Decode: ' . $duration . PHP_EOL);

$start = microtime(true);
$export = serialize($array);
$end = microtime(true);
$duration = $end - $start;
print('Serialize: ' . $duration . PHP_EOL);

$start = microtime(true);
$import = unserialize($export);
$end = microtime(true);
$duration = $end - $start;
print('Serialize: ' . $duration . PHP_EOL);

$start = microtime(true);
$export = igbinary_serialize($array);
$end = microtime(true);
$duration = $end - $start;
print('Igbinary Serialize: ' . $duration . PHP_EOL);

$start = microtime(true);
$import = igbinary_unserialize($export);
$end = microtime(true);
$duration = $end - $start;
print('Igbinary Serialize: ' . $duration . PHP_EOL);
?&gt;</code></pre>
<h2>测试结果</h2>
<blockquote><p>JSON Encode: 0.084825992584229<br />
JSON Decode: 0.34976410865784<br />
Serialize: 0.38241410255432<br />
Serialize: 7.7904229164124<br />
Igbinary Serialize: 0.046916007995605<br />
Igbinary Serialize: 0.23396801948547</p></blockquote>
<p>从测试结果来看，速度方面优先级排列为 igbinary > json > serialize。同时我们也可以看到，<a href="/tag/php">php</a>原生的serialize在对大对象进行反向操作时，速度真是掉队一大截了。</p>
<p>占用字节数对比</p>
<ol>
<ul>
<li>json: 5000001</li>
<li>serialize: 15888902</li>
<li>igbinary: 7868681</li>
</ul>
</ol>
<p>在没有中文字符的情况下，json胜出，igbinary次之，serialize又被甩了几条街。</p>
<h2>一图顶千言</h2>
<p>柱状图越矮小的性能越好<br />
<img src="http://chart.apis.google.com/chart?cht=bvg&#038;chdl=json|serialize|igbinary&#038;chco=ff0000%2C00ff00%2C0000ff&#038;chs=600x300&#038;chxl=0%3A|Export|Import|1%3A|0|1|2|3|4|5|6|7|8|9|10&#038;chxt=x%2Cy&#038;chbh=25%2C1%2C25&#038;chds=0%2C10%2C0%2C10%2C0%2C10&#038;chd=t%3A0.084%2C0.349|0.382%2C7.79|0.047%2C0.234" alt="igbinary vs serialize vs json_encode 速度比较" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/538/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>试着开源LiteCloud项目</title>
		<link>http://www.ooso.net/archives/554</link>
		<comments>http://www.ooso.net/archives/554#comments</comments>
		<pubDate>Mon, 15 Mar 2010 15:47:32 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[litecloud]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[tokyocabinet]]></category>

		<guid isPermaLink="false">http://www.ooso.net/?p=554</guid>
		<description><![CDATA[所谓LiteCloud，无非就是前些天提到的LightCloud的php版本实现。这个和原来的python版本有一些区别，会造成不兼容，如下：


把Consistent Hashing算法换成了ketama，在pecl的memcached扩展里有简单方法可以实现，效率比单纯的php好很多，能快个10倍吧。没有重复造轮子，因此我很是得意。

				<span class="readmore"><a href="http://www.ooso.net/archives/554" title="试着开源LiteCloud项目">阅读全文（1844字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>所谓LiteCloud，无非就是<a href="http://www.ooso.net/archives/549">前些天提到的LightCloud</a>的php版本实现。这个和原来的python版本有一些区别，会造成不兼容，如下：</p>
<ul>
<ol>
<li>把Consistent Hashing算法换成了ketama，在pecl的memcached扩展里有简单方法可以实现，效率比单纯的php好很多，能快个10倍吧。没有重复造轮子，因此我很是得意。</li>
<li>静态方法调用时，不再支持原来的system参数，原版是用这个来支持多个LiteCloud集群。</li>
<li>第一个版本，利用memcached扩展来读取tokyo tyrant，所以目前仅支持简单的操作比如get, set, delete, increment。其实再努力一下，也可以支持更多的功能，比如redis。</li>
<li>去掉了原版的local_cache功能，我觉得这个功能完全可以放在外面，更灵活。</li>
</ol>
</ul>
<h2>项目主页</h2>
<p>目前托管在github上 —— <a href="http://github.com/volca/litecloud">LiteCloud</a> ，使用<a href="/tag/git">git</a>以及github的时间不太长，但是很喜欢，欢迎fork。</p>
<h2>使用示例</h2>
<p>用静态方法调用:</p>
<pre><code>require 'LiteCloud.php';

$config = array(
    'lookup1_A' =&gt; '127.0.0.1:41201',
    'lookup1_B' =&gt; '127.0.0.1:51201',

    'storage1_A' =&gt; '127.0.0.1:44201',
    'storage1_B' =&gt; '127.0.0.1:54201',
);

list($lookupNodes, $storageNodes) = LiteCloud::generateNodes($config);
LiteCloud::init($lookupNodes, $storageNodes);

LiteCloud::set('hello', 'world');
print LiteCloud::get("hello"); # =&gt; world
LiteCloud::delete("hello");

print LiteCloud::get("hello"); # =&gt; nil</code></pre>
<p>或者采用实例化的方式调用，这种方式能够支持多个LightCloud集群</p>
<pre><code>require 'LiteCloud.php';

$config = array(
    'lookup1_A' =&gt; '127.0.0.1:41201',
    'lookup1_B' =&gt; '127.0.0.1:51201',

    'storage1_A' =&gt; '127.0.0.1:44201',
    'storage1_B' =&gt; '127.0.0.1:54201',
);

$cloud = new LiteCloud($config);

$cloud-&gt;set('hello', 'world');
print $cloud-&gt;get("hello"); # =&gt; world
$cloud-&gt;delete("hello");

print $cloud-&gt;get("hello"); # =&gt; nil</code></pre>
<p>看上去和python版本差不多，对吧？</p>
<h2>性能测试</h2>
<p>这个部分是个重点，之前找到的lightcloud的php版本，性能比原版要慢一个数量级，我可不想在这个地方丢了份。</p>
<p>暂时做了个最简单的性能测试，测试脚本在test目录下。测试条件如下:</p>
<ul>
<ol>
<li>底层采用tokyo tyrant作为存储。</li>
<li>单个进程重复操作一万次，比如写一万次hello => world，这个测试条件和python版本完全一致</li>
<li>关闭了local_cache</li>
</ol>
</ul>
<h3>python版本的测试结果</h3>
<pre><code>Finished "Tyrant set" 10000 times in 2.50 sec [4002.0 operations pr.sec]
Finished "Tyrant get" 10000 times in 1.04 sec [9583.7 operations pr.sec]
Finished "Tyrant delete" 10000 times in 7.39 sec [1352.4 operations pr.sec]</code></pre>
<h3>LiteCloud的测试结果</h3>
<pre><code>Using 1.8229308128357 time to set 10000 values. QPS:5485.67
Using 0.71097207069397 time to get 10000 values. QPS:14065.25
Using 2.1550960540771 time to delete 10000 values. QPS:4640.16</code></pre>
<p>看上去还比较乐观，尤其是delete的性能翻了好几番，几乎要怀疑我在代码实现部分出了差错，在其它方面的表现也是全面超出，因为python版在hash_ring的实现上拖了后腿。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/554/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>LightCloud的设计原理</title>
		<link>http://www.ooso.net/archives/549</link>
		<comments>http://www.ooso.net/archives/549#comments</comments>
		<pubDate>Thu, 11 Mar 2010 17:37:16 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[common]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tokyocabinet]]></category>

		<guid isPermaLink="false">http://www.ooso.net/?p=549</guid>
		<description><![CDATA[LightCloud是最近看到的一个比较轻巧的分布式key-value数据库，尽管这类软件已经让人觉得审美疲劳，但我仍然觉得它的设计思路值得一提。
特色
除开其项目主页上列出来的特点不提，我觉得还能数得上的特色有：


				<span class="readmore"><a href="http://www.ooso.net/archives/549" title="LightCloud的设计原理">阅读全文（1470字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>LightCloud是最近看到的一个比较轻巧的分布式key-value数据库，尽管这类软件已经让人觉得审美疲劳，但我仍然觉得它的设计思路值得一提。</p>
<h2>特色</h2>
<p>除开其项目主页上列出来的特点不提，我觉得还能数得上的特色有：</p>
<ul>
<ol>
<li>理论上可以用任意key-value数据库做为底层存储，现在支持以<a href="http://1978th.net/tokyotyrant/">tokyo tyrant</a>或者<a href="http://code.google.com/p/redis/">redis</a>作为底层的存储，如果使用redis可以获得更好的性能（大概提升30%~50%）</li>
<li>没有定制服务器端，基本上靠客户端语言来实现键值查找。优点是部署起来比较简单，缺点也是显而易见的，效率会有损失。</li>
<li>可以很方便的移植到其它语言上，我已经在github上找到一个ruby版本，甚至还有个php版本的实现。</li>
<li>可以方便的增加节点。</li>
<li>结构简单，方便hack</li>
</ol>
</ul>
<h2>LightCloud的设计原理</h2>
<h3>Hash ring</h3>
<p>LightCloud不能免俗的使用了一致性hash算法（Consistent Hashing），这是为了避免新增数据节点时发生集体拆迁事件。Consistent Hashing算法的原理请参考<a href="http://www.yeeach.com/2009/10/02/consistent-hashing%E7%AE%97%E6"%B3%95/>这里</a>。</p>
<p>last.fm的工作人员写的ketama算法算是比较常见的一致性算法，在libmemcached里大量使用。而LightCloud的作者当时还没发现合适的ketama python版，所以干脆自己捋起袖子写了个python版本的hash_ring，不到50行。这个是量身定制的，所以效率也还过得去，但是兼容ketama就别想了。</p>
<p>献上hash圈圈一个以明志：<br />
<img alt="" src="http://static1.139js.com/system/picture/10528302/600x600/memcached000404-thumb.jpg" title="一致性hash算法原理示意图" class="alignnone" width="600" height="472" /></p>
<h3>LightCloud的hash环有什么与众不同？</h3>
<p>其它分布式key-value数据库采用的办法是复制数据到多个节点上，例如<a href="http://s3.amazonaws.com/AllThingsDistributed/sosp/amazon-dynamo-sosp2007.pdf">Amazon Dynamo</a>的复制策略图：<br />
<a href="http://www.ooso.net/wp-content/uploads/2010/03/dynamo_replication.png"><img src="http://www.ooso.net/wp-content/uploads/2010/03/dynamo_replication.png" alt="" title="dynamo_replication" class="alignnone" /></a></p>
<p>Dynamo用了许多办法解决consistent问题，系统相当复杂。而LightCloud直接使用tokyo tyrant的master-master复制功能，大幅简化了这部分的逻辑。所以在它的hash环上，单个节点其实是一对master-master的tokyo tyrant，焦不离孟不离焦。</p>
<p><a href="http://www.ooso.net/wp-content/uploads/2010/03/lc_replc.png"><img src="http://www.ooso.net/wp-content/uploads/2010/03/lc_replc.png" alt="" title="lc_replc" class="alignnone" /></a></p>
<p>在新增数据节点时，如果没有路由服务找到正确的服务器，可能会损失数据。那么LightCloud继续采用流氓手段解决这个问题，他又给上了个环，保证不会发生意外。这两个hash环里的节点仍然是之前提到的tokyo tyrant双人组，一个环叫<strong>lookup</strong>，记录了每一个key保存在哪个storage节点上；另外一个环叫<strong>storage</strong>，这是真正存放数据的地方。于是它的结构图变成了下面这个样子：</p>
<p><a href="http://www.ooso.net/wp-content/uploads/2010/03/storage_lookup.png"><img src="http://www.ooso.net/wp-content/uploads/2010/03/storage_lookup.png" alt="" title="storage_lookup" class="alignnone" /></a></p>
<p>这部分比较难以理解，试着就上图阐述一下：</p>
<ul>
<ol>
<li>一个名叫A的家伙，住在storage_SB地区(storage ring)。同时，我们还告诉记性好的lookup_B(lookup ring)，A君的地址为storage_SB。</li>
<li>很不幸或很幸运，咱们的数据膨胀到需要扩容了，于是新增了一个违章建筑storge_X，这个该死的建筑正好影响了我们找到A君。这时候，我们还可以问起记性好的lookup_B，A君住在哪个角落里啊？ —— lookup_B日道：他就住在sotrage_SB一带~</li>
<li>lookup这群家伙记性虽然好，但是也架不住人多，再也记不住这么多人的住址，所以又新来了几个记性好的lookup。这个会影响咱们找到storage住哪吗？答案是不会，因为没有新增别的违章storage建筑，咱们不需要问路也能找着人。</li>
</ol>
</ul>
<p>按照以上推论，一定要避免同时增加lookup和storage节点，这很可能会损失数据。</p>
<h2>参考网页</h2>
<ul>
<li><a href="http://opensource.plurk.com/LightCloud/">http://opensource.plurk.com/LightCloud/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/549/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>memcache连接慢又一例</title>
		<link>http://www.ooso.net/archives/524</link>
		<comments>http://www.ooso.net/archives/524#comments</comments>
		<pubDate>Tue, 22 Dec 2009 13:56:53 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/?p=524</guid>
		<description><![CDATA[继上次解决memcache连接慢问题以来，好长一段时间没在这个问题上翻过跟头。这一次我又在生产环境观察到php和memcache的连接时间经常会在50ms以上。
作为一个cache，占用了这么长的执行时间，天理何在？
实际的运行环境如下：


				<span class="readmore"><a href="http://www.ooso.net/archives/524" title="memcache连接慢又一例">阅读全文（699字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>继<a href="http://www.ooso.net/archives/479">上次解决memcache连接慢问题</a>以来，好长一段时间没在这个问题上翻过跟头。这一次我又在生产环境观察到php和memcache的连接时间经常会在50ms以上。</p>
<p>作为一个cache，占用了这么长的执行时间，天理何在？</p>
<p>实际的运行环境如下：</p>
<ol>
<ul>
<li>apache + mod_php</li>
<li><a href="http://pecl.php.net/memcache">php-memcache扩展</a>版本为2.2.5</li>
<li>memcache的并发连接数在400左右，相当少</li>
</ul>
</ol>
<p>这次memcache扩展用的是最新的稳定版，无可挑剔。所以刚开始我认为是网络环境的问题，于是直接采用telnet工具直连<a href="/?tag=memcache">memcache</a>进行测试，发现速度飞快！一点便秘感都没有！所以把目光仍然放回到memcache扩展上来，集中对比较慢的addServer方法各项参数进行排查。</p>
<h2>Memcache::addServer方法</h2>
<pre><code>bool Memcache::addServer  ( string $host  [, int $port = 11211  [, bool $persistent  [, int $weight  [, int $timeout  [, int $retry_interval  [, bool $status  [, callback $failure_callback  [, int $timeoutms  ]]]]]]]] )</code></pre>
<p>比对结果表明，$weight参数对memcache的连接时间有显著的影响，$weight的默认值为1，一旦设置为别的数值，连接时间便会由毫秒级变成50ms左右，立竿见影。</p>
<p>鉴于php-memcache扩展一贯恶劣的表现，俺不得不痛下决心迁移到新的<a href="http://pecl.php.net/memcached">memcached扩展</a>上。memcached扩展基于libmemcached开发，而且提供了丰富的接口方法，应该是更好的选择。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/524/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>启用memcached压缩注意事项</title>
		<link>http://www.ooso.net/archives/475</link>
		<comments>http://www.ooso.net/archives/475#comments</comments>
		<pubDate>Wed, 13 May 2009 23:56:05 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/?p=475</guid>
		<description><![CDATA[在php开发中，开启memcache的数据压缩存储是一件很简单的事情。在多数情况下，压缩数据不仅不会降低程序的执行效率，反倒会因为网络传输的开销降低，带来速度提升。看看最常用的Memcache::set方法:
bool Memcache::set  ( string $key  , mixed $var  [, int $flag  [, int $expire  ]] )
在这个方法中，将$flag设置为MEMCACHE_COMPRESSED即可启用memcache压缩存储。
这样做有什么弊端？

				<span class="readmore"><a href="http://www.ooso.net/archives/475" title="启用memcached压缩注意事项">阅读全文（1146字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>在php开发中，开启<a href="/?tag=memcache">memcache</a>的数据压缩存储是一件很简单的事情。在多数情况下，压缩数据不仅不会降低程序的执行效率，反倒会因为网络传输的开销降低，带来速度提升。看看最常用的Memcache::set方法:</p>
<pre><code>bool Memcache::set  ( string $key  , mixed $var  [, int $flag  [, int $expire  ]] )</code></pre>
<p>在这个方法中，将$flag设置为MEMCACHE_COMPRESSED即可启用memcache压缩存储。</p>
<h3>这样做有什么弊端？</h3>
<p>如果没有做额外判断，每一次写入memcache都会启用压缩，不管数据的大小。对应的，每次获得数据都需要做一次解压缩的操作，这是典型的一刀切手法。实际上在数据很小的情况下，不需要压缩，在这个基础上压缩省不了多少空间。</p>
<h3>更好的压缩策略？</h3>
<p>好了，我的想法是在数据超过一定大小（比如2k）的情况下，才开启压缩。这个好办，捋起袖子就干，在调用Memcache::set方法之前，首先判断一下数据的大小，一个strlen就搞定了，再简单不过了。</p>
<pre><code>$memcache = new Memcache;
$memcache-&gt;connect('localhost', 11211);
$flag = strlen($data) &gt; 2048 ? MEMCACHE_COMPRESSED : 0;
$memcache-&gt;set('mykey', $data, $flag);</code></pre>
<p>有人可能会问了，array和object怎么办，这玩意可不能用strlen判断长度。</p>
<p>这还真能难住我一阵子，要知道把array/object写入memcache的时候，php会自动做serialize，再把它当作字符串插入memcache。</p>
<pre><code>$flag = strlen(serialize($data)) &gt; 2048 ? MEMCACHE_COMPRESSED : 0;</code></pre>
<p>谁会采用这段代码？看起来非常山寨，而且serialize也不快，赔本买卖。</p>
<h3>更好的办法！</h3>
<p>上面的文字都是废话，直接看这段就好。<a href="http://cn2.php.net/manual/en/function.memcache-setcompressthreshold.php">Memcache::setCompressThreshold方法</a>可以包办之前所有的逻辑。</p>
<blockquote><p>Memcache::setCompressThreshold — Enable automatic compression of large values</p></blockquote>
<pre><code>bool Memcache::setCompressThreshold  ( int $threshold  [, float $min_savings  ] )</code></pre>
<p>举个例子，下面这段会自动启用压缩策略，当数据大于2k时，以0.2的压缩比进行zlib。</p>
<pre><code>$memcache-&gt;setCompressThreshold(2000, 0.2);</code></pre>
<p>根据我的测试结果，<strong>setCompressThreshold方法会忽略Memcache::set的flag参数</strong>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/475/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>starling试用手记</title>
		<link>http://www.ooso.net/archives/506</link>
		<comments>http://www.ooso.net/archives/506#comments</comments>
		<pubDate>Sat, 21 Mar 2009 10:48:53 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[queue]]></category>

		<guid isPermaLink="false">http://www.ooso.net/?p=506</guid>
		<description><![CDATA[twitter最近将ruby实现的消息队列服务器starling开源了，这是一个支持memcache协议的轻量级持久化服务器，因此使用php/perl/ruby/java等多种客户端都没问题，可以将较慢的处理逻辑通过消息队列放在后台处理，同时也支持多点分布式处理。周末找了个闲置的centos 5机器搭了一套starling试用，配合php的memcache扩展测试一番，有点意思。
starling安装步骤
centos默认不带ruby，得重新装，以下安装步骤都是以root身份跑的。
yum install ruby ruby-devel rubygems

				<span class="readmore"><a href="http://www.ooso.net/archives/506" title="starling试用手记">阅读全文（1299字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>twitter最近将ruby实现的<a href="http://github.com/starling/starling/tree/master">消息队列服务器starling</a>开源了，这是一个支持<a href="/?tag=memcache">memcache</a>协议的轻量级持久化服务器，因此使用php/perl/ruby/java等多种客户端都没问题，可以将较慢的处理逻辑通过消息队列放在后台处理，同时也支持多点分布式处理。周末找了个闲置的centos 5机器搭了一套starling试用，配合<a href="/?tag=php">php</a>的memcache扩展测试一番，有点意思。</p>
<h2>starling安装步骤</h2>
<p>centos默认不带ruby，得重新装，以下安装步骤都是以root身份跑的。</p>
<pre><code>yum install ruby ruby-devel rubygems
gem install memcache-client starling</code></pre>
<p>如果你使用yum找不到ruby的相关包，请记得<a href="http://www.ooso.net/archives/495">添加epel repository</a>。安装之后新增的程序：</p>
<ul>
<li>/usr/bin/starling   	#一个ruby脚本，starling的服务程序</li>
<li>/usr/bin/starling_top 	#starling的状态检查程序，可以查看starling的运行状态，类似memcache的状态显示，不同的是能够显示每个key的状态</li>
</ul>
<p>starling启动后默认会在22122端口蹲点守候。</p>
<p>为了使用方便，我修改了一个starling在centos下的启动脚本，放在/etc/init.d/starling，下载地址：<a href="http://customcode.googlecode.com/files/starling">http://customcode.googlecode.com/files/starling</a>。使用方法：</p>
<pre><code>/etc/init.d/starling start|stop|restart</code></pre>
<h2>测试程序</h2>
<p>以下是在测试中用的php脚本，说实话php在循环比较大的时候没啥优势，但是关键是简单，几行就搞定了。</p>
<p><strong>写入的测试程序</strong></p>
<pre><code>#!/usr/bin/php
&lt;?php
$m = new Memcache;
$m-&gt;addServer('127.0.0.1', '22122');

$start = microtime(true);

for($i = 0; $i &lt; 10000; ++$i) {
    //echo $i, "\n";
    $m-&gt;set('testtesttesttest', '中文测试中文测试中文测试中文测试中文测试中文测试中中文测试中中文中a');
}
echo "time:" . (microtime(true) - $start), "\n";</code></pre>
<p><strong>读出来的测试程序</strong></p>
<pre><code>#!/usr/bin/php
&lt;?php
$m = new Memcache;
$m-&gt;addServer('127.0.0.1', '22122');

while(1) {
    echo $m-&gt;get('test'), "\n";
    usleep(100); // 休息一下，否则容易cpu 100%
}</code></pre>
<h2>性能测试</h2>
<p>测试条件:</p>
<ul>
<li>key的长度16B</li>
<li>value的长度100B,</li>
<li>8个并发写入进程</li>
<li>每个进程插入10,000条记录</li>
</ul>
<p>平均每个进程花了7秒完成写入操作，那么照这样计算：</p>
<p><strong>10000 * 8 / 7 = 每秒写入11428次</strong></p>
<p>以上测试进行的比较随意，而且我懒得插入大量数据来测试了，这个比较花时间，所以测试结果仅供参考。由于starling是目前twitter在生产环境中运行的，经过实践检验过，稳定性应该不成问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/506/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>解决memcache连接奇慢问题一例</title>
		<link>http://www.ooso.net/archives/479</link>
		<comments>http://www.ooso.net/archives/479#comments</comments>
		<pubDate>Sat, 07 Mar 2009 03:19:44 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/?p=479</guid>
		<description><![CDATA[最近用xdebug观察线上程序的运行时间统计，发现往日里跑起来像飞的memcache居然是系统中拖后腿的耗时大户，连接时间特长。
运行环境

webserver是apache + php

				<span class="readmore"><a href="http://www.ooso.net/archives/479" title="解决memcache连接奇慢问题一例">阅读全文（788字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>最近用xdebug观察线上程序的运行时间统计，发现往日里跑起来像飞的<a href="/?tag=memcache">memcache</a>居然是系统中拖后腿的耗时大户，连接时间特长。</p>
<h2>运行环境</h2>
<ul>
<li>webserver是apache + php</li>
<li>php memcache extension版本是3.0.2，当时是最新的beta版&#8230;</li>
<li>有4个memcache server可供使用</li>
<li>代码中会利用php的Memcache::addServer依次连接四个memcache，长连接方式</li>
</ul>
<h2>现象</h2>
<p>完成四次addServer一共需要300ms以上，但是一旦连接上，获取单个item飞快，时间在3ms以下。<br />
更可恶的问题在于，虽然执行了四次Memcache::addServer，但是实际使用的始终是最后一个memcache，这实在让人崩溃。</p>
<h2>问题解决</h2>
<p>使用了一点搜索技巧，在pecl.php.net上找到了类似的bug: <a href="http://pecl.php.net/bugs/bug.php?id=13483">First get slow when using multiple memcached servers</a></p>
<p>这个bug的描述如下：</p>
<blockquote><p>
We are monitoring memcached performance and noticed that when we added a second memcached via Memcache::addServer the first get request is always slower than the subsequent ones although we are using persitent memcached connections. Switching from crc32 to fnv hashing didn&#8217;t help either. Is that delay explainable
</p></blockquote>
<p>看起来是最新的memcache extension有一些问题，尝试将这个扩展降级成最新的稳定版2.2.6，然后重启apache看看，memcache连接过慢的问题果然已经解决。</p>
<h2>结论</h2>
<p>吃螃蟹果然是要付出代价的。。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/479/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>memcached Binary协议的ppt</title>
		<link>http://www.ooso.net/archives/471</link>
		<comments>http://www.ooso.net/archives/471#comments</comments>
		<pubDate>Tue, 23 Sep 2008 12:35:09 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[common]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/index.php/archives/471</guid>
		<description><![CDATA[memcached 1.3将开始支持Binary Protocol，下面是一篇介绍的ppt。

大概看了一遍，可以认为memcache的binary协议相对原来基于文本的协议，略快一些。key的长度可以到65536(2 bytes)。而memcache 1.3将仍然保持向后兼容，同时支持文本协议和binary协议。
]]></description>
			<content:encoded><![CDATA[<p>memcached 1.3将开始支持Binary Protocol，下面是一篇介绍的ppt。</p>
<p><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=memcachednighttokyo-1221916987381523-9&#038;stripped_title=memcached-binary-protocol-in-a-nutshell-presentation" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=memcachednighttokyo-1221916987381523-9&#038;stripped_title=memcached-binary-protocol-in-a-nutshell-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></p>
<p>大概看了一遍，可以认为<a href="/?tag=memcache">memcache</a>的binary协议相对原来基于文本的协议，略快一些。key的长度可以到65536(2 bytes)。而memcache 1.3将仍然保持向后兼容，同时支持文本协议和binary协议。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/471/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>从memcache中dump所有key的patch</title>
		<link>http://www.ooso.net/archives/465</link>
		<comments>http://www.ooso.net/archives/465#comments</comments>
		<pubDate>Sat, 23 Aug 2008 04:27:41 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[common]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/?p=465</guid>
		<description><![CDATA[在邮件组里看到这个补丁，能够将memcache中所有的key dump出来。
I have just finished a patch to dump all keys from memcached.
And I am glad to share this patch to anyone who wants to use it.
In the attachment, there are two python scripts which are used for dump all keys from a memcached server,

				<span class="readmore"><a href="http://www.ooso.net/archives/465" title="从memcache中dump所有key的patch">阅读全文（343字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>在邮件组里看到这个补丁，能够将<a href="/?tag=memcache">memcache</a>中所有的key dump出来。</p>
<blockquote><p>I have just finished a patch to dump all keys from memcached.<br />
And I am glad to share this patch to anyone who wants to use it.</p>
<p>In the attachment, there are two python scripts which are used for dump all keys from a memcached server,<br />
you can find the usage in the example.py script.</p>
<p>Any  questions or advice can mail  to  we_2002 at 163.com </p></blockquote>
<p>用法见example.py</p>
<p>下载:  <a href="http://customcode.googlecode.com/files/memcached-hack.zip">memcached-hack.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/465/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>最简便的清空memcache的方法</title>
		<link>http://www.ooso.net/archives/462</link>
		<comments>http://www.ooso.net/archives/462#comments</comments>
		<pubDate>Sun, 20 Jul 2008 01:08:58 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/index.php/archives/462</guid>
		<description><![CDATA[如果要清空memcache的items，常用的办法是什么？杀掉重启？如果有n台memcache需要重启怎么办？挨个做一遍？
很简单，假设memcached运行在本地的11211端口，那么跑一下命令行：
$ echo ”flush_all” &#124; nc localhost 11211
注：flush并不会将items删除，只是将所有的items标记为expired。

				<span class="readmore"><a href="http://www.ooso.net/archives/462" title="最简便的清空memcache的方法">阅读全文（210字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>如果要清空memcache的items，常用的办法是什么？杀掉重启？如果有n台<a href="/?tag=memcache">memcache</a>需要重启怎么办？挨个做一遍？</p>
<p>很简单，假设memcached运行在本地的11211端口，那么跑一下命令行：</p>
<pre><code>$ echo ”flush_all” | nc localhost 11211</code></pre>
<p>注：flush并不会将items删除，只是将所有的items标记为expired。</p>
<p>原文：<a href="http://willj.net/blog/2008/06/10/flushing-memcached-servers-the-easy-way/">Flushing memcached servers the easy way</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/462/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>memcache遭遇out of memory错误</title>
		<link>http://www.ooso.net/archives/444</link>
		<comments>http://www.ooso.net/archives/444#comments</comments>
		<pubDate>Tue, 15 Jul 2008 09:34:24 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/index.php/archives/444</guid>
		<description><![CDATA[今天在服务器上碰到memcache的out of memory错误，这还是第一次遇到，稍稍有些慌。一共有15台服务器，每台服务器分配了1G内存给memcache，合计有15个G，遇到错误的时候，大概只使用了4个G不到的内存。
现象比较很灵异，设置一个很小的value的时候就会出现这个错误
[root@slave1 bin]# telnet localhost 11211
Trying 127.0.0.1...

				<span class="readmore"><a href="http://www.ooso.net/archives/444" title="memcache遭遇out of memory错误">阅读全文（1214字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>今天在服务器上碰到<a href="/?tag=memcache">memcache</a>的out of memory错误，这还是第一次遇到，稍稍有些慌。一共有15台服务器，每台服务器分配了1G内存给memcache，合计有15个G，遇到错误的时候，大概只使用了4个G不到的内存。</p>
<p>现象比较很灵异，设置一个很小的value的时候就会出现这个错误</p>
<pre><code>[root@slave1 bin]# telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.
set key1 0 0 2
SERVER_ERROR out of memory</code></pre>
<p>如果设置一个较大的value，反而Stored成功。</p>
<p>翻看了几篇关于memcache内存分配的介绍，大概有一些了解。</p>
<ul>
<li><a href="http://tech.idv2.com/2008/07/11/memcached-002/">memcached全面剖析–2.理解memcached的内存存储</a></li>
<li><a href="http://kevinminnick.blogspot.com/2006/01/understanding-memcached-memory.html">Understanding memcached memory management</a></li>
</ul>
<p>其中后一篇有实际操作的介绍，更为实用。根据个人理解先写个大概。</p>
<p>Memcache为了避免产生内存碎片，采用Slab Allocation机制来整理内存。比如某前端机分配了1G内存给memcache，那么它会将内存按照不同尺寸的小块(chunk)分成若干个组(classes)，组的数目不是很固定，每个组分配1M内存。见下图：<br />
<img src="http://tech.idv2.com/wp-content/uploads/2008/07/memcached-0002-01.png" /></p>
<p>当一条记录插入memcache中的时候，首先会寻找一个合适的能足够容纳这条记录的class。比如你insert一条100字节的数据，它会使用128字节的class来存储这条记录，只有28字节被浪费。</p>
<p>如果用memcached-tool来查看memcache的使用情况，会看到类似下面列出的情况。</p>
<pre>
[root@sql-slave1 bin]# ./memcached-tool localhost
# Item_Size 	Max_age		1MB_pages	Full?
6 64 B 		0 s 		0 		no
7 128 B 	742970 s 	4 		yes
8 256 B		1174852 s 	2 		yes
9 512 B		1279658 s 	1 		yes
10 1 kB		6494118 s 	1 		yes
11 2 kB 	434918 s 	71 		yes
12 4 kB 	917228 s 	140 	yes
13 8 kB 	794192 s 	30 		no
14 16 kB	1373208 s 	6 		yes
15 B 		0 s 		0 		yes
16 B 		0 s 		0 		yes
</pre>
<p>此时插入一条很小的记录，比如只有2个字节，那么memcache会尝试用最小的class（64字节）来保存这条记录，这时候由于64字节的class已满或未分配内存，写入数据的时候就会遭遇到前面所说的<b>out of memcache</b>错误了。</p>
<p>更糟糕的是，这时候增加cache大小似乎也不能解决问题。可行的办法是利用memcached-tool对内存进行移动操作：</p>
<pre><code>[root@sql-slave1 bin]# ./memcached-tool localhost move 14 6</code></pre>
<p>上面的操作会移动class 14的一个page到class 6。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/444/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>用mysql触发器自动更新memcache</title>
		<link>http://www.ooso.net/archives/436</link>
		<comments>http://www.ooso.net/archives/436#comments</comments>
		<pubDate>Wed, 09 Jul 2008 06:41:39 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/?p=436</guid>
		<description><![CDATA[mysql 5.1支持触发器以及自定义函数接口(UDF)的特性，如果配合libmemcache以及Memcached Functions for MySQL，就能够实现memcache的自动更新。简单记录一下安装测试步骤。
安装步骤

安装memcached,这个步骤很简单，随处可见

				<span class="readmore"><a href="http://www.ooso.net/archives/436" title="用mysql触发器自动更新memcache">阅读全文（1451字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>mysql 5.1支持触发器以及自定义函数接口(UDF)的特性，如果配合libmemcache以及Memcached Functions for MySQL，就能够实现<a href="/?tag=memcache">memcache</a>的自动更新。简单记录一下安装测试步骤。</p>
<h3>安装步骤</h3>
<ul>
<li>安装<a href="http://www.danga.com/memcached/">memcached</a>,这个步骤很简单，随处可见</li>
<li>安装<a href="http://www.mysql.com">mysql server 5.1RC</a>，安装办法也很大众，不废话了</li>
<li>编译<a href="http://hg.tangent.org/libmemcached/">libmemcached</a>，解压后安装即可
<pre><code>./configure; make; make install</code></pre>
</li>
<li>编译Memcached Functions for MySQL，在<a href="http://download.tangent.org/">http://download.tangent.org/</a>找一个最新的版本下载就是，
<pre><code>./configure --with-mysql=/usr/local/mysql/bin/mysql_config --libdir=/usr/local/mysql/lib/mysql/
make
make install</code></pre>
</li>
<li>接下来有两个办法让Memcached Functions for MySQL在mysql中生效
<ul>
<li>在mysql的shell中执行memcached_functions_mysql源码目录下的sql/install_functions.sql，这会把memcache function作为UDF加入mysql</li>
<li>运行memcached_functions_mysql源码目录下的utils/install.pl，这是一个perl脚本，作用同上一条</li>
</ul>
</li>
</ul>
<h3>测试memcache function</h3>
<p>以下测试脚本摘自memcached_functions_mysql的源码目录，有兴趣可以试试</p>
<pre><code>drop table if exists urls;
create table urls (
  id int(3) not null,
  url varchar(64) not null default '',
  primary key (id)
  );

select memc_servers_set('localhost:11211');
select memc_set('urls:sequence', 0);

DELIMITER |

DROP TRIGGER IF EXISTS url_mem_insert;
CREATE TRIGGER url_mem_insert
BEFORE INSERT ON urls
FOR EACH ROW BEGIN
    SET NEW.id= memc_increment('urls:sequence');
    SET @mm= memc_set(concat('urls:',NEW.id), NEW.url);
END |

DELIMITER ;

insert into urls (url) values ('http://google.com');
insert into urls (url) values ('http://www.ooso.net/index.php');
insert into urls (url) values ('http://www.ooso.net/');
insert into urls (url) values ('http://slashdot.org');
insert into urls (url) values ('http://mysql.com');
select * from urls;

select memc_get('urls:1');
select memc_get('urls:2');
select memc_get('urls:3');
select memc_get('urls:4');
select memc_get('urls:5');</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/436/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Memcache的备忘</title>
		<link>http://www.ooso.net/archives/428</link>
		<comments>http://www.ooso.net/archives/428#comments</comments>
		<pubDate>Fri, 20 Jun 2008 08:26:43 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/index.php/archives/428</guid>
		<description><![CDATA[把memcache使用时的一些细节记录下来.

用memcache保存session的例子，非常简单
&#60;?php

				<span class="readmore"><a href="http://www.ooso.net/archives/428" title="Memcache的备忘">阅读全文（899字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>把memcache使用时的一些细节记录下来.</p>
<ul>
<li>用memcache保存session的例子，非常简单
<pre><code>&lt;?php
$session_save_path = "tcp://$host:$port?persistent=1&#038;weight=2&#038;timeout=2&#038;retry_interval=10,  ,tcp://$host:$port  ";
ini_set('session.save_handler', 'memcache');
ini_set('session.save_path', $session_save_path);
?&gt;</code></pre>
</li>
<li>memcache每一个item上限是1M，注意不要超出上限</li>
<li>memcache本身并不支持namespace，但是可以通过一些手段模拟出namespace的效果来，见<a href="http://avenger.name/blog/memcache-namespace/">Memcache 中模拟 namespace</a></li>
<li>刚接触memcache的时候，可能会写出这样的代码来
<pre><code>$zhang = $memcache-&gt;get('key1');
$li = $memcache-&gt;get('key2');
$wang = $memcache-&gt;get('key3');</code></pre>
<p>这种写法实际运行效果是
<ul>
<li>get(key1) &#8211; 客户端发出请求 &#8211; 服务器端查询 &#8211; 客户端获取</li>
<li>get(key2) &#8211; 客户端 &#8211; 服务器端 &#8211; 客户端</li>
<li>get(key3) &#8211; 客户端 &#8211; 服务器端 &#8211; 客户端</li>
<li>&#8230;</li>
</ul>
<p>如此一来，会有三次客户端和服务器端交互的过程。但是如果用批量查询的方法，就只有一次交互的过程。比如:
<pre><code>$all = $memcache-&gt;get(array('key1', 'key2', 'key3'));</code></pre>
<p>这样性能会有一些提升。对于其它程序语言来说，也封装了类似get_multi这样的方法。
</li>
<li>从数据库从查询获得一个列表，放到memcache里面保存起来是一个不错的主意，但是不要忘记memcache有1m限制。如果列表太大，可以考虑把数据分割开来，然后用key序列来保存这个列表数据，比如event_0_500来保存前500行,用event_0_1000保存500-1000行，在获取的时候可以用前面说的批量get来一次性得到这个列表。</li>
<li>经常<a href="http://www.ooso.net/index.php/archives/414">观察memcache的大小，以及命中率</a>，方便调整缓存策略</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/428/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>用memcache.php监测memcache的状况</title>
		<link>http://www.ooso.net/archives/414</link>
		<comments>http://www.ooso.net/archives/414#comments</comments>
		<pubDate>Fri, 06 Jun 2008 05:10:00 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[优化]]></category>

		<guid isPermaLink="false">http://www.ooso.net/?p=414</guid>
		<description><![CDATA[最新的memcache pecl中，新增了一个memcache.php，这个php文件可以用来方便的查看memcache的状况，界面上与apc自带的apc.php风格一致。
如图:

应该算是最方便的监测memcache的办法了。

				<span class="readmore"><a href="http://www.ooso.net/archives/414" title="用memcache.php监测memcache的状况">阅读全文（128字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>最新的memcache pecl中，新增了一个memcache.php，这个php文件可以用来方便的查看memcache的状况，界面上与apc自带的apc.php风格一致。</p>
<p>如图:<br />
<a href="http://lh5.ggpht.com/viewccom/SEi0xswa7YI/AAAAAAAAAfs/N_PQT7tN6Dc/s800/memcache.jpg" target="_blank"><img src="http://lh5.ggpht.com/viewccom/SEi0xswa7YI/AAAAAAAAAfs/N_PQT7tN6Dc/s400/memcache.jpg" /></a></p>
<p>应该算是最方便的监测<a href="http://www.ooso.net/index.php/archives/414">memcache</a>的办法了。</p>
<p><a href="http://livebookmark.net/memcachephp/memcachephp.zip">memcache.php源文件下载</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/414/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>memcache的几个旁支</title>
		<link>http://www.ooso.net/archives/395</link>
		<comments>http://www.ooso.net/archives/395#comments</comments>
		<pubDate>Thu, 08 May 2008 06:23:30 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/index.php/archives/395</guid>
		<description><![CDATA[最近留意了一下，memcache出现了几个旁支项目，很有一点意思，也许在日后的项目中可以用的上。
memcached-tag
给memcache增加了tag功能，新增的命令如下：


				<span class="readmore"><a href="http://www.ooso.net/archives/395" title="memcache的几个旁支">阅读全文（1679字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>最近留意了一下，<a href="/?tag=memcache">memcache</a>出现了几个旁支项目，很有一点意思，也许在日后的项目中可以用的上。</p>
<h3><a href="http://memcached-tag.googlecode.com/">memcached-tag</a></h3>
<p>给memcache增加了tag功能，新增的命令如下：</p>
<ul>
<li>tag_add &lt;tag&gt; &lt;key&gt;</li>
<li>tag_delete &lt;tag&gt;</li>
</ul>
<blockquote><p>Memcached is a high-performance, distributed memory object caching system.</p>
<p>We add &#8220;Tag Function&#8221; for memcached. Propose is remove several keys with the same tag in one operation. This function will help the API programmers (such as php) do the delete operation easily, and reduce the network load. We use hash and splay tree, make the &#8220;tag_add&#8221; and &#8220;tag_delete&#8221; commands very quickly, and save memory as much as possible. </p></blockquote>
<h3><a href="http://jehiah.cz/projects/memcached-win32/">memcached for Win32</a></h3>
<p>顾名思义，这个是一个在win32下跑的memcached，某些人用的上吧，也许&#8230;</p>
<blockquote><p>This is a port of memcached to the win32 architecture by Kronuz<br />
The win32 version of memcached can be run both as a NT Service or from the command line.</p></blockquote>
<h3><a href="http://memcachedb.org/">memcachedb</a></h3>
<p>新浪互动社区技术团队提供的一个memcache版本。我们知道memcache是将数据保存在内存里的，要是停机或重启，biu的一下，就什么都没了，虽然这能满足cache的需要，但是如果有一个key-value的持久化存储db，也是不错的。</p>
<p>memcachedb就是这样一个基于memcache + berkeley db的持久存储，仍然可以使用之前的memcache client api，比如这些方法：</p>
<ul>
<li>get(also mutiple get)</li>
<li>set, add, replace</li>
<li>incr, decr</li>
<li>delete</li>
<li>stats</li>
</ul>
<p>我测试了一下，还不支持flush奥，但是没有关系，问题不大。测试的时候，读写速度相当快。据memcachedb的主页上说，这个不是拿来作为一个cache的解决方案的，而是一个快速的key-value持久存储db。</p>
<blockquote><p>Memcachedb is a distributed key-value storage system designed for persistent. It is NOT a cache solution, but a persistent storage engine for fast and reliable key-value based object storage and retrieval. It conforms to memcache protocol(not completed, see below), so any memcached client can have connectivity with it. Memcachedb uses Berkeley DB as a storing backend, so lots of features including transaction and replication are supported.</p></blockquote>
<h3><a href="http://tangent.org/506/memcache_engine.html">memcache_engine</a></h3>
<blockquote><p>memcache_engine是一个MySQL数据库的存储引擎，目前只支持MySQL5.1数据库，他能够把memcachedb作为MySQL数据库的一个存储引擎和MySQL集成起来，让用户通过标准的SQL查询语句访问memcachedb中存放的数据.</p></blockquote>
<blockquote><p>The memcache_engine allows memcache to work as a storage engine to MySQL. This means that you can SELECT/UPDATE/INSERTE/DELETE from it as though it is a table in MySQL.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/395/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用memcache的几个优点</title>
		<link>http://www.ooso.net/archives/306</link>
		<comments>http://www.ooso.net/archives/306#comments</comments>
		<pubDate>Thu, 31 May 2007 23:43:33 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/index.php/archives/306</guid>
		<description><![CDATA[最近在3个项目中都有用到memcache，这东东确实有出人意料的上佳表现，优点不少。

稳定，几个月以来，一同装上去的apache已重启过多次，这期间memcache一直踏踏实实干活，一点都不需要中途加油。
配置简单，那是相当的简单，几乎不用配置，一个命令行的守护进程跑下来，就可以不管了

				<span class="readmore"><a href="http://www.ooso.net/archives/306" title="使用memcache的几个优点">阅读全文（337字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>最近在3个项目中都有用到<a href="/index.php?tag=memcache">memcache</a>，这东东确实有出人意料的上佳表现，优点不少。</p>
<ul>
<li><strong>稳定</strong>，几个月以来，一同装上去的apache已重启过多次，这期间<a href="http://www.danga.com/memcached/">memcache</a>一直踏踏实实干活，一点都不需要中途加油。</li>
<li><strong>配置简单</strong>，那是相当的简单，几乎不用配置，一个命令行的守护进程跑下来，就可以不管了</li>
<li><strong><a href="http://www.ooso.net/index.php/archives/263">多机分布式存储</a></strong>，每个前端机都能匀出一些内存来跑memcache，这些内存加在一起，总大小也是相当的客观，能够应付足够多的缓存数据，如果开启了memcache的压缩选项MEMCACHE_COMPRESSED，存储量还能有进一步提升。</li>
<li><strong>速度快</strong>，这个论点需要数据支持，俺手头之前有一些不同数据量级下set/get的速度对比，但是这里不方便列出来</li>
</ul>
<p>以上，俺认为memcache是前端缓存一个漂亮的解决方案</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/306/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Memcache的分布式应用</title>
		<link>http://www.ooso.net/archives/263</link>
		<comments>http://www.ooso.net/archives/263#comments</comments>
		<pubDate>Thu, 26 Oct 2006 23:52:49 +0000</pubDate>
		<dc:creator>Volcano</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://www.ooso.net/index.php/archives/263</guid>
		<description><![CDATA[早就听说memcached是一个不错的分布式内存缓存系统,做了些功课想把这memcache用到实际当中来.因为一个好的缓存系统,能给web应用带来不小的性能提升.做了一些功课之后,做了下面几点总结:

memcache适合与web server安装在同一server上
memcache可以在n个端口开n个进程,如果和web server在同一机器的话,还能减少网络开销.

				<span class="readmore"><a href="http://www.ooso.net/archives/263" title="Memcache的分布式应用">阅读全文（919字）</a></span>]]></description>
			<content:encoded><![CDATA[<p>早就听说<a href="http://www.ooso.net/index.php/archives/263">memcached</a>是一个不错的分布式内存缓存系统,做了些功课想把这memcache用到实际当中来.因为一个好的缓存系统,能给web应用带来不小的性能提升.做了一些功课之后,做了下面几点总结:</p>
<ul>
<li>memcache适合与web server安装在同一server上</li>
<li>memcache可以在n个端口开n个进程,如果和web server在同一机器的话,还能减少网络开销.</li>
<li>配置简单,启动一个进程就行了,免去了配置文件</li>
</ul>
<p>我更关心的是,memcache的分布式应用应该如何部署.带着这个问题,我在各搜索引擎上做了进一步的功课.最初找到的办法是,首先启动n个memcache进程,这些进程可以在不同的server的不同端口上.</p>
<p>然后使用perl的api可以方便的一次链接多个memcache,存储读取机制不明.不久找到<a href="http://www.ooso.net/index.php/archives/category/php/">php</a>的一个MemcachedClient类,基本上就是perl里api的再实现.它使用的fscokopen或者socket系列function来直接读取memcache&#8212;-这说明只要清楚memcache的网络协议,你甚至不用装什么php的memcache extenstion.看了这个类的实现,基本上弄清楚,它的分布式应用差不多就是将不同的key保存在不同的memcache daemon,不会保留多个副本,也就不存在多memcache同步的问题了.</p>
<p>过了不久俺又有发现,在最新的php手册上找到了memcache::addServer()这方法,它就是为分布式应用而产生的,有了这个支持的话,php的代码就更简单:</p>
<pre><code>&lt;?php
   $memcache_obj = new Memcache;
   $memcache_obj-&gt;addServer('memcache_host', 11211);
   $memcache_obj-&gt;addServer('failed_host', 11211);

   $stats = $memcache_obj-&gt;getExtendedStats();
   print_r($stats);
?&gt;</code></pre>
<p>看来php手册也要与时俱进啊,最好是能够直接使用英文版,否则也不会走这么多弯路了:)</p>
<h3>官方站点</h3>
<p> <a href="http://www.danga.com/memcached/">http://www.danga.com/memcached/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooso.net/archives/263/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

