<?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>Big toy for boy! &#187; Array</title>
	<atom:link href="http://bigtoy4boy.com/blog/tag/array/feed/" rel="self" type="application/rss+xml" />
	<link>http://bigtoy4boy.com/blog</link>
	<description>一个有关一些个人兴趣爱好的博客</description>
	<lastBuildDate>Thu, 10 Jun 2010 02:33:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Array, APC and Memcached</title>
		<link>http://bigtoy4boy.com/blog/2009/11/array-apc-and-memcached/</link>
		<comments>http://bigtoy4boy.com/blog/2009/11/array-apc-and-memcached/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 02:20:22 +0000</pubDate>
		<dc:creator>羽高</dc:creator>
				<category><![CDATA[互联网技术]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[Memcached]]></category>

		<guid isPermaLink="false">http://bigtoy4boy.com/blog/?p=324</guid>
		<description><![CDATA[昨天花了一下午的时间测试一个程序的执行效率，该程序是一个后台日志分析的程序，犯懒用php写的，毕竟php对文本处理效率很高（编写&#38;执行），一开始担心php的数组按照键值查询效率低，所以使用memcache作为内存缓存来用。
程序编写好后执行正常，当处理数据量上来以后，发现执行很慢。其它的项目中我也发现在压力测试时memcache会是瓶颈并导致很高的cpu占用，因此怀疑是否自己编译的php+memcached有问题，或者是其它问题。于是做了下面的测试。
Trace for /logprocess/process_sessiontime_memcached.php
Total Elapsed Time = 767.74
Total System Time  = 19.15
Total User Time    = 742.67
 
 Real         User        System             secs/    cumm
%Time [...]]]></description>
			<content:encoded><![CDATA[<p>昨天花了一下午的时间测试一个程序的执行效率，该程序是一个后台日志分析的程序，犯懒用php写的，毕竟php对文本处理效率很高（编写&amp;执行），一开始担心php的数组按照键值查询效率低，所以使用memcache作为内存缓存来用。</p>
<p>程序编写好后执行正常，当处理数据量上来以后，发现执行很慢。其它的项目中我也发现在压力测试时memcache会是瓶颈并导致很高的cpu占用，因此怀疑是否自己编译的php+memcached有问题，或者是其它问题。于是做了下面的测试。</p>
<p><code>Trace for /logprocess/process_sessiontime_memcached.php<br />
Total Elapsed Time = 767.74<br />
Total System Time  = 19.15<br />
Total User Time    = 742.67</code></p>
<p><code> </code></p>
<p><code> Real         User        System             secs/    cumm<br />
%Time (excl/cumm)  (excl/cumm)  (excl/cumm) Calls    call    s/call  Memory Usage Name<br />
--------------------------------------------------------------------------------------<br />
69.2 531.12 531.12  520.74 520.74  6.94 6.94  92646  0.0057   0.0057            0 Memcached-&gt;set<br />
21.4 164.18 164.18  157.25 157.25  4.85 4.85  92646  0.0018   0.0018            0 Memcached-&gt;get<br />
</code></p>
<p>从上面的数据能看出，这个程序php执行的瓶颈在memcache，而set操作更加有问题，接近70%的时间都在做set操作，难道真是使用的模块有问题嘛？我查过php的memcached模块，代码基本上就是一个连接，实质使用的还是libmemcached这个库的内容，所以如果要是有问题的话也肯定在libmemcached这个上面。但网上搜索后，无果，没有人说它有问题。</p>
<p>后来细想，按照上面的数据折算，读写平均的话122.22次/秒，读单独是564.30次/秒，写单独是174.47次/秒，数据表现也算不错了。写慢是memcache以及被测试的程序逻辑有矛盾，我了解了一下，memcache会使用item(key+value)的长度做前期的定位，试想如果程序使得value长度不断变化，是否set会不断移动item所在的slab位置呢（将旧的变成过期，再按照新写入数据的流程写入新的item）？没有深度考究，但觉得值得怀疑；如果写操作所占用的cpu释放出来的话，读的效率应该可以更高，回头可以测试一下，估计能超过1千次/秒。</p>
<p>总结上述，memcache使用要被仔细的规划，取长补短，如果随意使用的话未必能有好的效果。上面的程序其实就不应该用memcache，频繁的写不是memcache的强项，而分布式、多点频繁读取才是强项。</p>
<p>说道缓存，所以我顺便又测试了<a href="http://www.php.net/manual/en/book.apc.php" target="_blank">Alternative PHP Cache</a>(APC)的模式，还是刚才的程序，出来的结果是读写平均392.57次/秒，比memcache快3倍多，我没有出读写分离的数据，估计如果单读的话，应该还能再快一些，毕竟APC是本地缓存。因此，如果你的应用不需要分布式的话，APC是一个很好的选择，它能帮你在一台机器的情况下，保持并缓存每次php请求之间的数据。其次，它还是一个类似<a href="http://eaccelerator.net/" target="_blank">eAccelerator</a>的代码opcode缓存模块，可以提高php代码执行速度。</p>
<p>最后，回到我一开始没有考虑的解决方案，因为我不需要跟其它进程或者服务器共享我的数据，所以直接用php的数组，处理速度是多少呢？15,441次/秒！当然啦，内部就是一堆指针指来指去而已，我没有想到的是数组在很多无序的key中找value还是很快的，所以以后大家可以放心这么使用，只是注意配置文件中允许的php运行时占用的内存再调大点就好了。</p>
<p>总结，任何设计要根据具体的应用需求来选择解决方案，选择时要考虑所选技术本身的特性，取其优点避其缺点。Memcache不适合做数据频繁变化的内存共享，一次写入多次读取的模式会更适合一些。<a href="http://1978th.net/tokyotyrant/">Tokyo Tyrant</a> / <a href="http://1978th.net/tokyocabinet/" target="_blank">Tokyo Cabinet</a> / <a href="http://code.google.com/p/redis/" target="_blank">Redis</a>也许能用于频繁读写的情况，我还没有时间去评测；BTW，以前还使用Mysql内存表做这类事情多一点，希望能构建一个数据写入缓存机制，但是实际使用时还是有一些问题，所以有空再找找新的解决方案吧。</p>
<p>最后说一句，就一句：在Memcache盛行的当今，Memcache不可滥用。</p>
]]></content:encoded>
			<wfw:commentRss>http://bigtoy4boy.com/blog/2009/11/array-apc-and-memcached/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
