<?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>℃冻番茄&#039;s Blog</title>
	<atom:link href="http://phpd.cn/feed" rel="self" type="application/rss+xml" />
	<link>http://phpd.cn</link>
	<description>记录平时工作、学习的过程！开始学习新东西，下一个目标Android开发......</description>
	<lastBuildDate>Thu, 09 Feb 2012 10:13:41 +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>试用phonegap，编写一个android应用</title>
		<link>http://phpd.cn/archives/520</link>
		<comments>http://phpd.cn/archives/520#comments</comments>
		<pubDate>Thu, 09 Feb 2012 10:13:41 +0000</pubDate>
		<dc:creator>℃冻番茄</dc:creator>
				<category><![CDATA[图片/文字]]></category>

		<guid isPermaLink="false">http://phpd.cn/?p=520</guid>
		<description><![CDATA[把去年写的一个黄金t+d弄成apk &#160; &#160; 下载地址： lhold]]></description>
			<content:encoded><![CDATA[<p>把去年写的一个黄金t+d弄成apk</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>下载地址：</p>
<p><a href="http://phpd.cn/archives/520/lhold" rel="attachment wp-att-521">lhold</a></p>
]]></content:encoded>
			<wfw:commentRss>http://phpd.cn/archives/520/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>beanstalkd 消息队列的第一手资料</title>
		<link>http://phpd.cn/archives/517</link>
		<comments>http://phpd.cn/archives/517#comments</comments>
		<pubDate>Mon, 06 Feb 2012 04:40:51 +0000</pubDate>
		<dc:creator>℃冻番茄</dc:creator>
				<category><![CDATA[图片/文字]]></category>

		<guid isPermaLink="false">http://phpd.cn/?p=517</guid>
		<description><![CDATA[beanstalk 消息队列 小结 协议说明和各状态转换情况 基本知识点: 1. 对于beanstalk 消息队列中每条数据都为 job 2. beanstalk service端 ，会维护 tubes[多个管道] 3. client端可以监听,使用多 tube 4. client端可以指定 use &#8230; <a href="http://phpd.cn/archives/517" class="more-link">了解更多</a>]]></description>
			<content:encoded><![CDATA[<p>beanstalk 消息队列 小结<br />
协议说明和各状态转换情况</p>
<p>基本知识点:<br />
  1. 对于beanstalk 消息队列中每条数据都为 job<br />
  2. beanstalk service端 ，会维护 tubes[多个管道]<br />
  3. client端可以监听,使用多 tube<br />
  4. client端可以指定 use 管道[ client生成一个新的job时会把此job提交到 指定管道]<br />
  5. client端可以指定 watch 管道 [ client接收处理job时会到 指定管道得到待处理的job]</p>
<p>官方示意图:<br />
put            reserve               delete<br />
&#8212;&#8211;> [READY] &#8212;&#8212;&#8212;> [RESERVED] &#8212;&#8212;&#8211;> *poof*</p>
<p>一般情况:<br />
1. 任务提交到service端,job 管理放入内存空间并为其标记状态 [READY]<br />
2. client通过轮训竞争得到次状态, job 改为  [RESERVED]<br />
   2.1 当在默认时间 120 秒内没处理完 , job.stats.timeouts 就会大于 0<br />
      同时其他 轮训竞争client会拿到这个job【 注意了 每次timeouts时,在轮训的客户端就会得到次job，状态都为 ready,timeouts>0 】<br />
3. 随便其中一台client处理完 job.delete   , 其他 client 中的此job 都会    *poof*  </p>
<p>deom &#8211; python beanstalkc 中 job.stats 参考:<br />
使用 easy_install beanstalkc<br />
API 参考 : http://github.com/earl/beanstalkc/blob/master/TUTORIAL<br />
刚生成的 beanstalk<br />
{&#8216;buries&#8217;: 0, &#8216;releases&#8217;: 0, &#8216;tube&#8217;: &#8216;default&#8217;, &#8216;timeouts&#8217;: 0, &#8216;ttr&#8217;: 120,<br />
&#8216;age&#8217;: 6, &#8216;pri&#8217;: 2147483648L, &#8216;delay&#8217;: 0, &#8216;state&#8217;: &#8216;reserved&#8217;, &#8216;time-left&#8217;: 114,<br />
&#8216;kicks&#8217;: 0, &#8216;id&#8217;: 2}</p>
<p>以timeout了的 beanstalk,并且在其他client轮训到 job<br />
{&#8216;buries&#8217;: 0, &#8216;releases&#8217;: 0, &#8216;tube&#8217;: &#8216;default&#8217;, &#8216;timeouts&#8217;: 1, &#8216;ttr&#8217;: 120,<br />
&#8216;age&#8217;: 417, &#8216;pri&#8217;: 2147483648L, &#8216;delay&#8217;: 0, &#8216;state&#8217;: &#8216;reserved&#8217;, &#8216;time-left&#8217;: 110,<br />
&#8216;kicks&#8217;: 0, &#8216;id&#8217;: 2}<br />
{&#8216;buries&#8217;: 0, &#8216;releases&#8217;: 0, &#8216;tube&#8217;: &#8216;default&#8217;, &#8216;timeouts&#8217;: 1, &#8216;ttr&#8217;: 120, &#8216;age&#8217;: 415,<br />
&#8216;pri&#8217;: 2147483648L, &#8216;delay&#8217;: 0, &#8216;state&#8217;: &#8216;reserved&#8217;, &#8216;time-left&#8217;: 4294967163L,<br />
&#8216;kicks&#8217;: 0, &#8216;id&#8217;: 2}</p>
<p>当没所有client 的 job 都到期 了 状态<br />
{&#8216;buries&#8217;: 0, &#8216;releases&#8217;: 0, &#8216;tube&#8217;: &#8216;default&#8217;, &#8216;timeouts&#8217;: 2, &#8216;ttr&#8217;: 120,<br />
&#8216;age&#8217;: 417, &#8216;pri&#8217;: 2147483648L, &#8216;delay&#8217;: 0, &#8216;state&#8217;: &#8216;ready&#8217;, &#8216;time-left&#8217;: 4294967161L,<br />
&#8216;kicks&#8217;: 0, &#8216;id&#8217;: 2}<br />
{&#8216;buries&#8217;: 0, &#8216;releases&#8217;: 0, &#8216;tube&#8217;: &#8216;default&#8217;, &#8216;timeouts&#8217;: 2, &#8216;ttr&#8217;: 120, &#8216;age&#8217;: 415,<br />
&#8216;pri&#8217;: 2147483648L, &#8216;delay&#8217;: 0, &#8216;state&#8217;: &#8216;ready&#8217;, &#8216;time-left&#8217;: 4294967163L,<br />
&#8216;kicks&#8217;: 0, &#8216;id&#8217;: 2}</p>
<p>其中 client1 job.delete<br />
client1 job.stats  *poof*<br />
client2 job.stats  *poof*</p>
<p>比较全的状态说明 &#8211; [官方文档]</p>
<p>http://github.com/kr/beanstalkd/blob/v1.1/doc/protocol.txt?raw=true</p>
<p>官方示意图:</p>
<p>先简单说明下（完全自己理解的，欢迎拍砖。本人E人太差~看官档费劲，谅解下）:<br />
job.stats状态 = [READY] 待处理,  [RESERVED] 正处理, [DELAYED]延迟状态 ,  [BURIED] 隐藏状态</p>
<p>1. 延迟提交<br />
py.client1.put>>> beanstalk.put(&#8216;yes!&#8217;, delay=10)<br />
py.client3.reserve>>> job = beanstalk.reserve()<br />
# 等待 10  秒</p>
<p>2. 管道测试<br />
put-job到service端 可以指定 put的tube管道<br />
如: </p>
<p>py.client1.put>>> beanstalk.use(&#8216;foo&#8217;)<br />
py.client1.put>>> beanstalk.put(&#8216;hey!&#8217;)</p>
<p>py.client2.reserve>>> job = beanstalk.reserve()<br />
# 一直拥塞，应为 他 watch 管道 &#8216;default&#8217;</p>
<p>py.client3.reserve>>> beanstalk.watch(&#8216;foo&#8217;)<br />
# beanstalk.ignore(&#8216;bar&#8217;) 放弃监听 bar<br />
py.client3.reserve>>> job = beanstalk.reserve()<br />
py.client3.reserve>>> job.body #输出 &#8216;hey!&#8217; </p>
<p>3. 隐藏状态 现在吧 client 1/2/3 的 use watch 的管道都调回 default<br />
py.client2.reserve>>> job = beanstalk.reserve()<br />
py.client3.reserve>>> job = beanstalk.reserve()<br />
py.client1.put>>> beanstalk.put(&#8216;隐藏状态!&#8217;)<br />
py.client2.reserve>>> job.bury() #2 轮训得到 并且 修改 job 为隐藏状态<br />
# 120 秒后 client3 没有轮训得到 此job<br />
py.client2.reserve>>> job.stats()<br />
{&#8216;buries&#8217;: 1, &#8216;releases&#8217;: 0, &#8216;tube&#8217;: &#8216;default&#8217;, &#8216;timeouts&#8217;: 0, &#8216;ttr&#8217;: 120,<br />
&#8216;age&#8217;: 188, &#8216;pri&#8217;: 2147483648L, &#8216;delay&#8217;: 0, &#8216;state&#8217;: &#8216;buried&#8217;,<br />
&#8216;time-left&#8217;: 4294967228L, &#8216;kicks&#8217;: 0, &#8216;id&#8217;: 11}<br />
py.client2.reserve>>> beanstalk.kick( job.stats()['id'] ) #修改状态为 reserved<br />
# 立刻 client3 得到 job<br />
py.client3.reserve>>> job.stats()<br />
{&#8216;buries&#8217;: 1, &#8216;releases&#8217;: 0, &#8216;tube&#8217;: &#8216;default&#8217;, &#8216;timeouts&#8217;: 0, &#8216;ttr&#8217;: 120, &#8216;age&#8217;: 313,<br />
&#8216;pri&#8217;: 2147483648L, &#8216;delay&#8217;: 0, &#8216;state&#8217;: &#8216;reserved&#8217;,<br />
&#8216;time-left&#8217;: 110, &#8216;kicks&#8217;: 1, &#8216;id&#8217;: 11}<br />
# 这时候 client2 / 3 同时 有 job 11 状态 &#8216;buries&#8217;: 1,&#8217;timeouts&#8217;: 0,&#8217;state&#8217;: &#8216;reserved&#8217;</p>
<p>4. peek 窥见<br />
  可以得到 一个 stats &#8211; read 的 job ，其他 client 可以 job = beanstalk.reserve()<br />
  后马上 job.stats 会变成  [RESERVED]<br />
  py.client2.reserve>>> job = beanstalk.peek_ready()<br />
  取得 job 并看 本 client 能 处理能<br />
>>> job = beanstalk.peek(3)<br />
>>> job.body<br />
    &#8216;yes!&#8217;<br />
>>> job.stats()['state']<br />
    &#8216;ready&#8217;<br />
这种形式西 job 不能 bury 等修改状态，但 可以 delete</p>
<p>peek 系类<br />
 peek_buried<br />
 peek_ready</p>
]]></content:encoded>
			<wfw:commentRss>http://phpd.cn/archives/517/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>linux tar分卷压缩方法</title>
		<link>http://phpd.cn/archives/514</link>
		<comments>http://phpd.cn/archives/514#comments</comments>
		<pubDate>Thu, 02 Feb 2012 09:25:00 +0000</pubDate>
		<dc:creator>℃冻番茄</dc:creator>
				<category><![CDATA[图片/文字]]></category>

		<guid isPermaLink="false">http://phpd.cn/?p=514</guid>
		<description><![CDATA[linux下备份网站数据，由于文件很多，打包成一个文件会比较大，所以想分卷压缩成每个900M的文件，方便下载与上传到网盘备份。 1.分卷压缩，使用tar+split组合 进入网站目录，执行： tar cvzf &#8211; web&#124; split -b 900m 2.合并 cat x* &#62; web.tar.gz 3.解压 tar xvzf web.tar.gz]]></description>
			<content:encoded><![CDATA[<p>linux下备份网站数据，由于文件很多，打包成一个文件会比较大，所以想分卷压缩成每个900M的文件，方便下载与上传到网盘备份。</p>
<p>1.分卷压缩，使用tar+split组合<br />
进入网站目录，执行：<br />
tar cvzf &#8211; web| split -b 900m</p>
<p>2.合并<br />
cat x* &gt; web.tar.gz</p>
<p>3.解压<br />
tar xvzf web.tar.gz</p>
]]></content:encoded>
			<wfw:commentRss>http://phpd.cn/archives/514/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一年一度的回家过大年的行动就要开始了</title>
		<link>http://phpd.cn/archives/510</link>
		<comments>http://phpd.cn/archives/510#comments</comments>
		<pubDate>Mon, 09 Jan 2012 06:56:34 +0000</pubDate>
		<dc:creator>℃冻番茄</dc:creator>
				<category><![CDATA[图片/文字]]></category>

		<guid isPermaLink="false">http://phpd.cn/?p=510</guid>
		<description><![CDATA[元旦加班，第二天也就是2号，起个大早，打开电脑准备秒杀回家火车票！ 12306不给力，登了十多分钟才登上去，十点杭州放票，快十点半了票都没刷出来，等不了了，直接电话95105105，一打就通。然后屁颠屁颠得跑到城站火车站取票。 随便在火车站附近找了个小店吃饭。小店的水煮鱼非常给力！ 13号的票，也就是这周五了。开始想念妈妈做的菜了····]]></description>
			<content:encoded><![CDATA[<p>元旦加班，第二天也就是2号，起个大早，打开电脑准备秒杀回家火车票！<br />
12306不给力，登了十多分钟才登上去，十点杭州放票，快十点半了票都没刷出来，等不了了，直接电话95105105，一打就通。然后屁颠屁颠得跑到城站火车站取票。</p>
<p>随便在火车站附近找了个小店吃饭。小店的水煮鱼非常给力！</p>
<p>13号的票，也就是这周五了。开始想念妈妈做的菜了····</p>
]]></content:encoded>
			<wfw:commentRss>http://phpd.cn/archives/510/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Memcache的问题集</title>
		<link>http://phpd.cn/archives/507</link>
		<comments>http://phpd.cn/archives/507#comments</comments>
		<pubDate>Tue, 27 Dec 2011 06:32:41 +0000</pubDate>
		<dc:creator>℃冻番茄</dc:creator>
				<category><![CDATA[Redis/Memcache/Mongodb]]></category>
		<category><![CDATA[memcache]]></category>

		<guid isPermaLink="false">http://phpd.cn/?p=507</guid>
		<description><![CDATA[o memcached是怎么工作的？ o memcached最大的优势是什么？ o memcached和MySQL的query cache相比，有什么优缺点？ o memcached和服务器的local cache（比如PHP的APC、mmap文件等）相比，有什么优缺点？ o memcached的cache机制是怎样的？ o memcached如何实现冗余机制？ o memcached如何处理容错的？ o 如何将memcached中item批量导入导出？ o 但是我确实需要把memcached中的item都dump出来，确实需要把数据load到memcached中，怎么办？ &#8230; <a href="http://phpd.cn/archives/507" class="more-link">了解更多</a>]]></description>
			<content:encoded><![CDATA[<p>o memcached是怎么工作的？<br />
o memcached最大的优势是什么？<br />
o memcached和MySQL的query cache相比，有什么优缺点？<br />
o memcached和服务器的local cache（比如PHP的APC、mmap文件等）相比，有什么优缺点？<br />
o memcached的cache机制是怎样的？<br />
o memcached如何实现冗余机制？<br />
o memcached如何处理容错的？<br />
o 如何将memcached中item批量导入导出？<br />
o 但是我确实需要把memcached中的item都dump出来，确实需要把数据load到memcached中，怎么办？<br />
o memcached是如何做身份验证的？<br />
o 如何使用memcached的多线程是什么？如何使用它们？<br />
o memcached能接受的key的最大长度是多少？（250bytes）<br />
o memcached对item的过期时间有什么限制？（为什么有30天的限制？）<br />
o memcached最大能存储多大的单个item？（1M byte）<br />
o 为什么单个item的大小被限制在1M byte之内？<br />
o 为了让memcached更有效地使用服务器的内存，可以在各个服务器上配置大小不等的缓存空间吗？<br />
o 什么是binary协议？它值得关注吗？<br />
o memcached是如何分配内存的？为什么不用malloc/free！？究竟为什么使用slab呢？<br />
o memcached能保证数据存储的原子性吗？</p>
<p><span id="more-507"></span></p>
<p><strong>memcached是怎么工作的？</strong></p>
<p>Memcached的神奇来自两阶段哈希（two-stage hash）。Memcached就像一个巨大的、存储了很多&lt;key,value&gt;对的哈希表。通过key，可以存储或查询任意的数据。</p>
<p>客 户端可以把数据存储在多台memcached上。当查询数据时，客户端首先参考节点列表计算出key的哈希值（阶段一哈 希），进而选中一个节点；客户端将请求发送给选中的节点，然后memcached节点通过一个内部的哈希算法（阶段二哈希），查找真正的数据 （item）。</p>
<p>举个列子，假设有3个客户端1, 2, 3，3台memcached A, B, C：<br />
Client 1想把数据”barbaz”以key “foo”存储。Client 1首先参考节点列表（A, B, C），计算key “foo”的哈希值，假设memcached B被选中。接着，Client 1直接connect到memcached B，通过key “foo”把数据”barbaz”存储进去。Client 2使用与Client 1相同的客户端库（意味着阶段一的哈希算法相同），也拥有同样的memcached列表（A, B, C）。<br />
于是，经过相同的哈希计算（阶段一），Client 2计算出key “foo”在memcached B上，然后它直接请求memcached B，得到数据”barbaz”。<br />
各种客户端在memcached中数据的存储形式是不同的（perl Storable, php serialize, java hibernate, JSON等）。一些客户端实现的哈希算法也不一样。但是，memcached服务器端的行为总是一致的。</p>
<p>最后，从实现的角度看，memcached是一个非阻塞的、基于事件的服务器程序。这种架构可以很好地解决C10K problem ，并具有极佳的可扩展性。</p>
<p>可以参考A Story of Caching ，这篇文章简单解释了客户端与memcached是如何交互的。</p>
<p><strong>memcached最大的优势是什么？</strong></p>
<p>请 仔细阅读上面的问题（即memcached是如何工作的）。Memcached最大的好处就是它带来了极佳的水平可扩展 性，特别是在一个巨大的系统中。由于客户端自己做了一次哈希，那么我们很容易增加大量memcached到集群中。memcached之间没有相互通信， 因此不会增加 memcached的负载；没有多播协议，不会网络通信量爆炸（implode）。memcached的集群很好用。内存不够了？增加几台 memcached吧；CPU不够用了？再增加几台吧；有多余的内存？在增加几台吧，不要浪费了。</p>
<p>基于memcached的基本原则，可以相当轻松地构建出不同类型的缓存架构。除了这篇FAQ，在其他地方很容易找到详细资料的。</p>
<p>看看下面的几个问题吧，它们在memcached、服务器的local cache和MySQL的query cache之间做了比较。这几个问题会让您有更全面的认识。</p>
<p>memcached和MySQL的query cache相比，有什么优缺点？</p>
<p>把 memcached引入应用中，还是需要不少工作量的。MySQL有个使用方便的query cache，可以自动地缓存SQL查询的结果，被缓存的SQL查询可以被反复地快速执行。Memcached与之相比，怎么样呢？MySQL的query cache是集中式的，连接到该query cache的MySQL服务器都会受益。<br />
* 当您修改表时，MySQL的query cache会立刻被刷新（flush）。存储一个memcached item只需要很少的时间，但是当写操作很频繁时，MySQL的query cache会经常让所有缓存数据都失效。</p>
<p>* 在多核CPU上，MySQL的query cache会遇到扩展问题（scalability issues）。在多核CPU上，query cache会增加一个全局锁（global lock）, 由于需要刷新更多的缓存数据，速度会变得更慢。</p>
<p>* 在MySQL的query cache中，我们是不能存储任意的数据的（只能是SQL查询结果）。而利用memcached，我们可以搭建出各种高效的缓存。比如，可以执行多个独立 的查询，构建出一个用户对象（user object），然后将用户对象缓存到memcached中。而query cache是SQL语句级别的，不可能做到这一点。在小的网站中，query cache会有所帮助，但随着网站规模的增加，query cache的弊将大于利。</p>
<p>* query cache能够利用的内存容量受到MySQL服务器空闲内存空间的限制。给数据库服务器增加更多的内存来缓存数据，固然是很好的。但是，有了 memcached，只要您有空闲的内存，都可以用来增加memcached集群的规模，然后您就可以缓存更多的数据。</p>
<p>memcached和服务器的local cache（比如PHP的APC、mmap文件等）相比，有什么优缺点？</p>
<p>首 先，local cache有许多与上面(query cache)相同的问题。local cache能够利用的内存容量受到（单台）服务器空闲内存空间的限制。不过，local cache有一点比memcached和query cache都要好，那就是它不但可以存储任意的数据，而且没有网络存取的延迟。</p>
<p>* local cache的数据查询更快。考虑把highly common的数据放在local cache中吧。如果每个页面都需要加载一些数量较少的数据，考虑把它们放在local cached吧。</p>
<p>* local cache缺少集体失效（group invalidation）的特性。在memcached集群中，删除或更新一个key会让所有的观察者觉察到。但是在local cache中, 我们只能通知所有的服务器刷新cache（很慢，不具扩展性），或者仅仅依赖缓存超时失效机制。</p>
<p>* local cache面临着严重的内存限制，这一点上面已经提到。</p>
<p><strong>memcached的cache机制是怎样的？</strong></p>
<p>Memcached 主要的cache机制是LRU（最近最少用）算法+超时失效。当您存数据到memcached中，可以 指定该数据在缓存中可以呆多久Which is forever, or some time in the future。如果memcached的内存不够用了，过期的slabs会优先被替换，接着就轮到最老的未被使用的slabs。</p>
<p>memcached如何实现冗余机制？<br />
不实现！我们对这个问题感到很惊讶。Memcached应该是应用的缓存层。它的设计本身就不带有任何冗余机制。如果一个memcached节点失去了所 有数据，您应该可以从数据源（比如数据库）再次获取到数据。您应该特别注意，您的应用应该可以容忍节点的失效。不要写一些糟糕的查询代码，寄希望于 memcached来保证一切！如果您担心节点失效会大大加重数据库的负担，那么您可以采取一些办法。比如您可以增加更多的节点（来减少丢失一个节点的影 响），热备节点（在其他节点down了的时候接管IP），等等。</p>
<p><strong>memcached如何处理容错的？</strong><br />
不处理！:) 在memcached节点失效的情况下，集群没有必要做任何容错处理。如果发生了节点失效，应对的措施完全取决于用户。节点失效时，下面列出几种方案供您选择：</p>
<p>* 忽略它！ 在失效节点被恢复或替换之前，还有很多其他节点可以应对节点失效带来的影响。</p>
<p>* 把失效的节点从节点列表中移除。做这个操作千万要小心！在默认情况下（余数式哈希算法），客户端添加或移除节点，会导致所有的缓存数据不可用！因为哈希参照的节点列表变化了，大部分key会因为哈希值的改变而被映射到（与原来）不同的节点上。</p>
<p>* 启动热备节点，接管失效节点所占用的IP。这样可以防止哈希紊乱（hashing chaos）。</p>
<p>* 如果希望添加和移除节点，而不影响原先的哈希结果，可以使用一致性哈希算法（consistent hashing）。您可以百度一下一致性哈希算法。支持一致性哈希的客户端已经很成熟，而且被广泛使用。去尝试一下吧！</p>
<p>* 两次哈希（reshing）。当客户端存取数据时，如果发现一个节点down了，就再做一次哈希（哈希算法与前一次不同），重新选择另一个节点（需要注意 的时，客户端并没有把down的节点从节点列表中移除，下次还是有可能先哈希到它）。如果某个节点时好时坏，两次哈希的方法就有风险了，好的节点和坏的节 点上都可能存在脏数据（stale data）。</p>
<p><strong>如何将memcached中item批量导入导出？<br />
</strong><br />
您不应该这样做！Memcached是一个非阻塞的服务器。任何可能导致memcached暂停或瞬时拒绝服务的操作都应该值得深思熟虑。向 memcached中批量导入数据往往不是您真正想要的！想象看，如果缓存数据在导出导入之间发生了变化，您就需要处理脏数据了；如果缓存数据在导出导入 之间过期了，您又怎么处理这些数据呢？</p>
<p>因此，批量导出导入数据并不像您想象中的那么有用。不过在一个场景倒是很有用。如果您有大量的从不变化 的数据，并且希望缓存很快热（warm）起来，批量导入缓存数据是很有帮助的。虽然这个场景并不典型，但却经常发生，因此我们会考虑在将来实现批量导出导入的功能。</p>
<p>Steven Grimm，一如既往地,，在邮件列表中给出了另一个很好的例子：http://lists.danga.com/pipermail/memcached/2007-July/004802.html 。</p>
<p>但是我确实需要把memcached中的item批量导出导入，怎么办？？</p>
<p>好吧好吧。如果您需要批量导出导入，最可能的原因一般是重新生成缓存数据需要消耗很长的时间，或者数据库坏了让您饱受痛苦。</p>
<p>如 果一个memcached节点down了让您很痛苦，那么您还会陷入其他很多麻烦。您的系统太脆弱了。您需要做一些优化 工作。比如处理”惊群”问题（比如 memcached节点都失效了，反复的查询让您的数据库不堪重负…这个问题在FAQ的其他提到过），或者优化不好的查询。记住，Memcached 并不是您逃避优化查询的借口。</p>
<p>如果您的麻烦仅仅是重新生成缓存数据需要消耗很长时间（15秒到超过5分钟），您可以考虑重新使用数据库。这里给出一些提示：</p>
<p>* 使用MogileFS（或者CouchDB等类似的软件）在存储item。把item计算出来并dump到磁盘上。 MogileFS可以很方便地覆写item，并提供快速地访问。.您甚至可以把MogileFS中的item缓存在memcached中，这样可以加快读 取速度。 MogileFS+Memcached的组合可以加快缓存不命中时的响应速度，提高网站的可用性。<br />
* 重新使用MySQL。 MySQL的 InnoDB主键查询的速度非常快。如果大部分缓存数据都可以放到VARCHAR字段中，那么主键查询的性能将更好。从memcached中按key查询 几乎等价于MySQL的主键查询：将key 哈希到64-bit的整数，然后将数据存储到MySQL中。您可以把原始（不做哈希）的key存储都普通的字段中，然后建立二级索引来加快查询…key被 动地失效，批量删除失效的key，等等。</p>
<p>上面的方法都可以引入memcached，在重启memcached 的时候仍然提供很好的性能。由于您不需要当 心”hot”的item被 memcached LRU算法突然淘汰，用户再也不用花几分钟来等待重新生成缓存数据（当缓存数据突然从内存中消失时），因此上面的方法可以全面提高性能。</p>
<p>关于这些方法的细节，详见博客：http://dormando.livejournal.com/495593.html 。<br />
<strong><br />
memcached是如何做身份验证的？</strong><br />
没有身份认证机制！memcached是运行在应用下层的软件（身份验证应该是应用上层的职责）。memcached的客户端和服务器端之所以是轻量级 的，部分原因就是完全没有实现身份验证机制。这样，memcached可以很快地创建新连接，服务器端也无需任何配置。</p>
<p>如果您希望限制访问，您可以使用防火墙，或者让memcached监听unix domain socket。</p>
<p>memcached的多线程是什么？如何使用它们？<br />
线 程就是定律（threads rule）！在Steven Grimm和Facebook的努力下，memcached 1.2及更高版本拥有了多线程模式。多线程模式允许memcached能够充分利用多个CPU，并在CPU之间共享所有的缓存数据。memcached使 用一种简单的锁机制来保证数据更新操作的互斥。相比在同一个物理机器上运行多个memcached实例，这种方式能够更有效地处理multi gets。</p>
<p>如果您的系统负载并不重，也许您不需要启用多线程工作模式。如果您在运行一个拥有大规模硬件的、庞大的网站，您将会看到多线程的好处。</p>
<p>更多信息请参见：http://code.sixapart.com/svn/memcached/trunk/server/doc/threads.txt 。</p>
<p>简 单地总结一下：命令解析（memcached在这里花了大部分时间）可以运行在多线程模式下。memcached内部对 数据的操作是基于很多全局锁的（因此这部分工作不是多线程的）。未来对多线程模式的改进，将移除大量的全局锁，提高memcached在负载极高的场景下 的性能。</p>
<p><strong>memcached能接受的key的最大长度是多少？</strong><br />
key 的最大长度是250个字符。需要注意的是，250是memcached服务器端内部的限制，如果您使用的客户端支持”key的前缀”或类似特性，那么 key（前缀+原始key）的最大长度是可以超过250个字符的。我们推荐使用使用较短的key，因为可以节省内存和带宽。</p>
<p><strong>memcached对item的过期时间有什么限制？</strong><br />
过期时间最大可以达到30天。memcached把传入的过期时间（时间段）解释成时间点后，一旦到了这个时间点，memcached就把item置为失效状态。这是一个简单但obscure的机制。</p>
<p><strong>memcached最大能存储多大的单个item？</strong><br />
1MB。如果你的数据大于1MB，可以考虑在客户端压缩或拆分到多个key中。</p>
<p>为什么单个item的大小被限制在1M byte之内？<br />
啊…这是一个大家经常问的问题！</p>
<p>简单的回答：因为内存分配器的算法就是这样的。</p>
<p>详 细的回答：Memcached的内存存储引擎（引擎将来可插拔…）,使用slabs来管理内存。内存被分成大小不等的slabs chunks（先分成大小相等的slabs，然后每个slab被分成大小相等chunks，不同slab的chunk大小是不相等的）。chunk的大小 依次从一个最小数开始，按某个因子增长，直到达到最大的可能值。</p>
<p>如果最小值为400B，最大值是1MB，因子是1.20，各个slab的chunk的大小依次是：slab1 &#8211; 400B slab2 &#8211; 480B slab3 &#8211; 576B …</p>
<p>slab中chunk越大，它和前面的slab之间的间隙就越大。因此，最大值越大，内存利用率越低。Memcached必须为每个slab预先分配内存，因此如果设置了较小的因子和较大的最大值，会需要更多的内存。</p>
<p>还有其他原因使得您不要这样向memcached中存取很大的数据…不要尝试把巨大的网页放到mencached中。把这样大的数据结构load和unpack到内存中需要花费很长的时间，从而导致您的网站性能反而不好。</p>
<p>如果您确实需要存储大于1MB的数据，你可以修改slabs.c:POWER_BLOCK的值，然后重新编译memcached；或者使用低效的malloc/free。其他的建议包括数据库、MogileFS等。</p>
<p><strong>我可以在不同的memcached节点上使用大小不等的缓存空间吗？这么做之后，memcached能够更有效地使用内存吗？</strong><br />
Memcache 客户端仅根据哈希算法来决定将某个key存储在哪个节点上，而不考虑节点的内存大小。因此，您可以在不同的节点上使用大小不等的缓存。但是一般都是这样做 的：拥有较多内存的节点上可以运行多个memcached实例，每个实例使用的内存跟其他节点上的实例相同。</p>
<p><strong>什么是二进制协议，我该关注吗？</strong><br />
关于二进制最好的信息当然是二进制协议规范：http://code.google.com/p/memcached/wiki/MemcacheBinaryProtocol 。</p>
<p>二进制协议尝试为端提供一个更有效的、可靠的协议，减少客户端/服务器端因处理协议而产生的CPU时间。<br />
根据Facebook的测试，解析ASCII协议是memcached中消耗CPU时间最多的环节。所以，我们为什么不改进ASCII协议呢？</p>
<p>在这个邮件列表的thread中可以找到一些旧的信息：http://lists.danga.com/pipermail/memcached/2007-July/004636.html 。</p>
<p><strong>memcached的内存分配器是如何工作的？为什么不适用malloc/free！？为何要使用slabs？</strong><br />
实际上，这是一个编译时选项。默认会使用内部的slab分配器。您确实确实应该使用内建的slab分配器。最早的时候，memcached只使用 malloc/free来管理内存。然而，这种方式不能与OS的内存管理以前很好地工作。反复地malloc/free造成了内存碎片，OS最终花费大量 的时间去查找连续的内存块来满足malloc的请求，而不是运行memcached进程。如果您不同意，当然可以使用malloc！只是不要在邮件列表中 抱怨啊:)</p>
<p>slab分配器就是为了解决这个问题而生的。内存被分配并划分成chunks，一直被重复使用。因 为内存被划分成大小不等 的 slabs，如果item的大小与被选择存放它的slab不是很合适的话，就会浪费一些内存。Steven Grimm正在这方面已经做出了有效的改进。</p>
<p>邮件列表中有一些关于slab的改进（power of n 还是 power of 2）和权衡方案：http://lists.danga.com/pipermail/memcached/2006-May/002163.html http://lists.danga.com/pipermail/memcached/2007-March/003753.html 。</p>
<p>如果您想使用malloc/free，看看它们工作地怎么样，您可以在构建过程中定义USE_SYSTEM_MALLOC。这个特性没有经过很好的测试，所以太不可能得到开发者的支持。</p>
<p>更多信息：http://code.sixapart.com/svn/memcached/trunk/server/doc/memory_management.txt 。</p>
<p><strong><br />
memcached是原子的吗？</strong><br />
当然！好吧，让我们来明确一下：<br />
所有的被发送到memcached的单个命令是完全原子的。如果您针对同一份数据同时发送了一个set命令和一个get命令，它们不会影响对方。它们将被串行化、先后执行。即使在多线程模式，所有的命令都是原子的，除非程序有bug:)<br />
命令序列不是原子的。如果您通过get命令获取了一个item，修改了它，然后想把它set回memcached，我们不保证这个item没有被其他进程 （process，未必是操作系统中的进程）操作过。在并发的情况下，您也可能覆写了一个被其他进程set的item。</p>
<p>memcached 1.2.5以及更高版本，提供了gets和cas命令，它们可以解决上面的问题。如果您使用gets命令查询某个key的item，memcached会 给您返回该item当前值的唯一标识。如果您覆写了这个item并想把它写回到memcached中，您可以通过cas命令把那个唯一标识一起发送给 memcached。如果该item存放在memcached中的唯一标识与您提供的一致，您的写操作将会成功。如果另一个进程在这期间也修改了这个 item，那么该item存放在memcached中的唯一标识将会改变，您的写操作就会失败。</p>
<p>通常，基于memcached中item的值来修改item，是一件棘手的事情。除非您很清楚自己在做什么，否则请不要做这样的事情。</p>
<p>出处：http://blog.csdn.net/jarfield/archive/2009/07/10/4336035.aspx#how%20does%20memcached%20work</p>
]]></content:encoded>
			<wfw:commentRss>http://phpd.cn/archives/507/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>去年写的文本批量查找器改进版</title>
		<link>http://phpd.cn/archives/497</link>
		<comments>http://phpd.cn/archives/497#comments</comments>
		<pubDate>Thu, 17 Nov 2011 02:04:01 +0000</pubDate>
		<dc:creator>℃冻番茄</dc:creator>
				<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[我的作品]]></category>

		<guid isPermaLink="false">http://phpd.cn/?p=497</guid>
		<description><![CDATA[下载地址：文本批量查找器Archive]]></description>
			<content:encoded><![CDATA[<p>下载地址：<a href="http://phpd.cn/archives/497/archive" rel="attachment wp-att-499">文本批量查找器</a><a href="http://phpd.cn/archives/497/archive" rel="attachment wp-att-499">Archive</a></p>
<p><a href="http://phpd.cn/archives/497/qq%e6%88%aa%e5%9b%be20111117095857" rel="attachment wp-att-498"><img class="alignnone size-full wp-image-498" title="txtsearch" src="http://phpd.cn/wp-content/uploads/2011/11/QQ截图20111117095857.jpg" alt="" width="530" height="450" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://phpd.cn/archives/497/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于人面解锁功能的一些胡扯</title>
		<link>http://phpd.cn/archives/495</link>
		<comments>http://phpd.cn/archives/495#comments</comments>
		<pubDate>Mon, 14 Nov 2011 03:49:02 +0000</pubDate>
		<dc:creator>℃冻番茄</dc:creator>
				<category><![CDATA[随心日志]]></category>

		<guid isPermaLink="false">http://phpd.cn/?p=495</guid>
		<description><![CDATA[刚看了一个视频，用照片欺骗android4.0的人面解锁功能，据我所说，很多电脑也带这个功能，但基本上都可以用照片的方式进行欺通过，毕竟照片和真实人面通过摄像头生成的都是相同的平形图形图像。 所以就想到一个方法 记录合法用户的几个不同的面部特征。比如 眨左眼 眨右眼 张大嘴 等不同的几个动作保存下来 在验证人面时，类似随机验证码的原理，随机通过动作的先后，例如：先眨右眼，再张嘴等来进行验证，这样一般来说，可以防止照片来欺骗]]></description>
			<content:encoded><![CDATA[<p>刚看了一个视频，用照片欺骗android4.0的人面解锁功能，据我所说，很多电脑也带这个功能，但基本上都可以用照片的方式进行欺通过，毕竟照片和真实人面通过摄像头生成的都是相同的平形图形图像。</p>
<p>所以就想到一个方法</p>
<p>记录合法用户的几个不同的面部特征。比如 眨左眼 眨右眼 张大嘴 等不同的几个动作保存下来</p>
<p>在验证人面时，类似随机验证码的原理，随机通过动作的先后，例如：先眨右眼，再张嘴等来进行验证，这样一般来说，可以防止照片来欺骗</p>
]]></content:encoded>
			<wfw:commentRss>http://phpd.cn/archives/495/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Redis 作者详谈 2.4 版本改进[转]</title>
		<link>http://phpd.cn/archives/485</link>
		<comments>http://phpd.cn/archives/485#comments</comments>
		<pubDate>Tue, 25 Oct 2011 01:44:54 +0000</pubDate>
		<dc:creator>℃冻番茄</dc:creator>
				<category><![CDATA[Redis/Memcache/Mongodb]]></category>

		<guid isPermaLink="false">http://phpd.cn/?p=485</guid>
		<description><![CDATA[由于Redis集群可能在较长一段时间内还处理开发阶段，为了避免稳定版本由于这一原因被无限延后，于是从2.2版本fork出了一个2.4分支，这一分支目前进行了一些新的优化改进及bug修复，如果没有严重bug将会在近几个星期内发布稳定版本。 随后作者列出了2.4版本中的一大堆优化改进及Bug修复，主要有下面一些： 对小数据量的sorted sets结构的内存使用做很大的优化 RDB文件的持久化速度也将会大大提高 对目前的一些写操作命令进行了改进，支持批量写入功能 启用新的内存分配模式 jemalloc. 通过对copy on write机制使用的优化，数据持久化保存的子进程的内存占用将大大减少 INFO内容更加丰富 新的OBJECT命令，提供对Redis存储value结构描述 新的CLIENT命令，提供对Redis客户端连接的信息描述 彻底将Slave对Master的连接改成非阻塞，之前connect(2)系统调用是会阻塞的 Redis-benchmark、Redis-cli 都进行了几个方面的改进 Make 改为彩色输出，更易读 VM机制彻底废弃 总的来说2.4版本会在各方面有性能上的提升 &#8230; <a href="http://phpd.cn/archives/485" class="more-link">了解更多</a>]]></description>
			<content:encoded><![CDATA[<p>由于Redis集群可能在较长一段时间内还处理开发阶段，为了避免稳定版本由于这一原因被无限延后，于是从2.2版本fork出了一个2.4分支，这一分支目前进行了一些新的优化改进及bug修复，如果没有严重bug将会在近几个星期内发布稳定版本。</p>
<p>随后作者列出了2.4版本中的一大堆优化改进及Bug修复，主要有下面一些：</p>
<ul>
<li>对小数据量的sorted sets结构的内存使用做很大的优化</li>
<li>RDB文件的持久化速度也将会大大提高</li>
<li>对目前的一些写操作命令进行了改进，支持批量写入功能</li>
<li>启用新的内存分配模式 <em>jemalloc</em>.</li>
<li>通过对copy on write机制使用的优化，数据持久化保存的子进程的内存占用将大大减少</li>
<li>INFO内容更加丰富</li>
<li>新的OBJECT命令，提供对Redis存储value结构描述</li>
<li>新的CLIENT命令，提供对Redis客户端连接的信息描述</li>
<li>彻底将Slave对Master的连接改成非阻塞，之前connect(2)系统调用是会阻塞的</li>
<li>Redis-benchmark、Redis-cli 都进行了几个方面的改进</li>
<li>Make 改为彩色输出，更易读</li>
<li>VM机制彻底废弃</li>
<li>总的来说2.4版本会在各方面有性能上的提升</li>
<li>Redis测试框架也有非常大的提升</li>
</ul>
<p><span id="more-485"></span></p>
<p>后面又详细对其中的一些方面做了深入讲解</p>
<h3>1.对Sorted Sets的内存优化</h3>
<p>实际上在2.2版本中，Redis就对小数据量Value的情况做了性能优化，主要优化方式是将小数据量的Value值不再按具体的数据结构存储， 而是存在一块二进制的整块数据。而这一改进一直没能应用于Sorted Sets数据结构上来，而在2.4版本中，作者终于想到合适的办法把Sorted Sets在小数据量下也进行了此种优化。</p>
<h3>2.RDB文件持久化提速</h3>
<p>这块很大程度上依赖于上面第1点，由于小量数据被存为一个大的二进制数据块，所以在持久化的时候，就不需要再遍历数据了，只需要一个key进行一次持久化写入。</p>
<h3>3.提供批量写入功能</h3>
<p>下面是所有提供批量写入功能的命令</p>
<ul>
<li><strong>SADD set val1 val2 val3 …</strong> — 返回添加的元素个数</li>
<li><strong>HDEL hash field2 field3 field3 …</strong> — 返回删除的元素个数</li>
<li><strong>SREM set val1 val2 val3 … </strong>– 返回删除的元素个数</li>
<li><strong>ZREM zset val1 val2 val3 … </strong>– 返回删除的元素个数</li>
<li><strong>ZADD zset score1 val1 score2 val2 … </strong>– 返回添加的元素个数</li>
<li><strong>LPUSH/RLPUSH list val1 val2 val3 … </strong>– 返回操作后的LIST的长度</li>
</ul>
<p>提供批量命令的效果是显而易见的，网络往返的时间被大大节约了，在最理想的网络情况下，作者的测试结果是<strong>一次性写入200w个元素，仅仅花费了1.28秒</strong>，每秒超过100w元素的写入！</p>
<p>为何不为所有写入命令都加上批量功能呢？作者解释说，由于很多命令在返回值上需要携带信息，如果改成批量的，无法批量返回信息内容。不过相信上面的改进已经可以让很多应用场景得到大大改进了。</p>
<h3>4.改用jemalloc的内存分配模式</h3>
<p>Redis长期以来的思想就是尽量不产生外部依赖，比如网络事件库没有用传统的libevent库，而是自己单独抽离出几个文件组成的更简单且性能 更高的网络事件启动库，这一库目前在很多开源项目中也被采用。而此次引入jemalloc实在是由于作者认为Linux下的glibc的内存分配器实在是 太烂了，无法有效地防止碎片的产生。</p>
<p>虽然jemalloc是外部引入，你也不需要在安装Redis时先安装一堆东西，因为它已经包含在Redis源码里了，你还是像往常一样直接Make编译即可，还是那么方便贴心。</p>
<h3>5.减少 copy-on-write 使用</h3>
<p>Redis的RDB文件持久化和AOF日 志写入，都是通过调用fork()方法产生子进程来做的。由于主进程还是继续处理请求，当有数据写操作导致数据内容发生变化时，原来的内存段会被复制一 份，这就是我们熟知的copy-on-write机制。而采用这一机制的问题就是，在最坏的情况下，进行一次RDB文件写入，可能导致使用内存加倍。所以 在2.4版本中，作者对这一机制的使用进行了优化，大大减少了对copy-on-write的使用。</p>
<p>作者还坦言，自己在2.2版本中在这方面的一些修改是有问题的，这导致了2.2版本中的许多Bug。</p>
<h3>6.INFO输出内容增强</h3>
<p>2.4版本的INFO内容会有较大改变，其中比较重要的有下面两个</p>
<pre>used_memory_peak:185680824
used_memory_peak_human:177.08M</pre>
<p>你的实际物理内存使用（RSS）和内存碎片情况通常都与最高峰内存使用相关，而这参数就是用来描述这些情况。一个是以byte为单位（185680824），一个是自动智能单位（177.08M）。</p>
<h3>7.测试框架的优化和提速</h3>
<p>这一点在NoSQLFan之前的文章《<a href="http://blog.nosqlfan.com/html/2383.html">Redis 测试引擎将升级提速</a>》中有比较详细的描述。有兴趣的朋友可以查看之前的文章。</p>
]]></content:encoded>
			<wfw:commentRss>http://phpd.cn/archives/485/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>首位国人PHP开发组成员以及他的Yaf</title>
		<link>http://phpd.cn/archives/481</link>
		<comments>http://phpd.cn/archives/481#comments</comments>
		<pubDate>Thu, 20 Oct 2011 04:36:58 +0000</pubDate>
		<dc:creator>℃冻番茄</dc:creator>
				<category><![CDATA[图片/文字]]></category>

		<guid isPermaLink="false">http://phpd.cn/?p=481</guid>
		<description><![CDATA[PHP开发组终于有了国人参与,  最近， Laruence(http://www.laruence.com)，真名惠新宸，加入了PHP语言官方开发组.  做PHP的同学一定很熟悉他了, 他的博客风雪之隅发表了很多PHP源代码分析和扩展开发相关的文章. &#160; 他使用PHP扩展开发的PHP框架Yaf, 也进入了PHP官方扩展库(http://pecl.php.net/package/yaf),  这个框架借鉴目前最流行的PHP开发框架Zend Framework的设计, 迁移成本很低. 不过目前Yaf的英文文档还很不完善:http://www.php.net/manual/en/book.yaf.php, 中文文档稍微完善一些:http://yaf.laruence.com/manual/ Yaf的优点: 1. 用C语言开发的PHP框架, 相比原生的PHP, 几乎不会带来额外的性能开销. 2. 所有的框架类, 不需要编译, 在PHP启动的时候加载, 并常驻内存. 3. 更短的内存周转周期, 提高内存利用率, 降低内存占用率. 4. 灵巧的自动加载. 支持全局和局部两种加载规则, 方便类库共享. 5. 高性能的视图引擎. 6. 高度灵活可扩展的框架, 支持自定义视图引擎, 支持插件, 支持自定义路由等等. 7. 内建多种路由, 可以兼容目前常见的各种路由协议. 8. 强大而又高度灵活的配置文件支持. 并支持缓存配置文件, 避免复杂的配置结构带来的性能损失. 9. 在框架本身,对危险的操作习惯做了禁止. 10.更快的执行速度, 更少的内存占用. Yaf现在在国外已经被很多人关注, 包括Zend Framework的作者, 也在twitter上推荐了Yaf: julienPauli: pecl/yaf finally made it : A framework, inspired by ZendFramework, entirely writen in a C extension]]></description>
			<content:encoded><![CDATA[<p><strong>PHP开发组终于有了国人参与,  最近， Laruence(http://www.laruence.com)，真名惠新宸，加入了PHP语言官方开发组</strong>.  做PHP的同学一定很熟悉他了, 他的博客风雪之隅发表了很多PHP源代码分析和扩展开发相关的文章.</p>
<p>&nbsp;</p>
<div>他使用PHP扩展开发的PHP框架Yaf, 也进入了PHP官方扩展库(<a href="http://pecl.php.net/package/yaf" target="_blank">http://pecl.php.net/package/yaf</a>),  这个框架借鉴目前最流行的PHP开发框架Zend Framework的设计, 迁移成本很低. 不过目前Yaf的英文文档还很不完善:<a href="http://www.php.net/manual/en/book.yaf.php" target="_blank">http://www.php.net/manual/en/book.yaf.php</a>, 中文文档稍微完善一些:<a href="http://yaf.laruence.com/manual/" target="_blank">http://yaf.laruence.com/manual/<br />
</a><br />
Yaf的优点:<br />
1. 用C语言开发的PHP框架, 相比原生的PHP, 几乎不会带来额外的性能开销.<br />
2. 所有的框架类, 不需要编译, 在PHP启动的时候加载, 并常驻内存.<br />
3. 更短的内存周转周期, 提高内存利用率, 降低内存占用率.<br />
4. 灵巧的自动加载. 支持全局和局部两种加载规则, 方便类库共享.<br />
5. 高性能的视图引擎.<br />
6. 高度灵活可扩展的框架, 支持自定义视图引擎, 支持插件, 支持自定义路由等等.<br />
7. 内建多种路由, 可以兼容目前常见的各种路由协议.<br />
8. 强大而又高度灵活的配置文件支持. 并支持缓存配置文件, 避免复杂的配置结构带来的性能损失.<br />
9. 在框架本身,对危险的操作习惯做了禁止.<br />
10.更快的执行速度, 更少的内存占用.</p>
<p>Yaf现在在国外已经被很多人关注, 包括Zend Framework的作者, 也在twitter上推荐了Yaf:<br />
julienPauli:<br />
pecl/yaf finally made it : A framework, inspired by ZendFramework, entirely writen in a C extension</p></div>
]]></content:encoded>
			<wfw:commentRss>http://phpd.cn/archives/481/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>修改了一下firefox插件switchhosts,让其支持新版firefox</title>
		<link>http://phpd.cn/archives/476</link>
		<comments>http://phpd.cn/archives/476#comments</comments>
		<pubDate>Fri, 30 Sep 2011 01:35:03 +0000</pubDate>
		<dc:creator>℃冻番茄</dc:creator>
				<category><![CDATA[我的作品]]></category>

		<guid isPermaLink="false">http://phpd.cn/?p=476</guid>
		<description><![CDATA[switchhosts是firefox下一个非常好用的hosts切换工具，但是插件的作者更新缓慢，或者说是firefox更新太快了，所以switchhosts最新版的1.1只支持firefox3 和 firefox4 可是现在firefox都6.0了，所以只好下载了一个switchhosts,修改了里面的配置，支持最高的版本数，直接从4改成了14 可以在一定时期内不需要担心switchhosts不兼容新版firefox的问题了 switchhosts下载 通过 firefox直接下载安装，或下载后，把文件拖到firefox中，会自动提示安装 下载地址 switchhosts-1.1.0-fx-windows.xpi]]></description>
			<content:encoded><![CDATA[<p>switchhosts是firefox下一个非常好用的hosts切换工具，但是插件的作者更新缓慢，或者说是firefox更新太快了，所以switchhosts最新版的1.1只支持firefox3 和 firefox4</p>
<p>可是现在firefox都6.0了，所以只好下载了一个switchhosts,修改了里面的配置，支持最高的版本数，直接从4改成了14</p>
<p>可以在一定时期内不需要担心switchhosts不兼容新版firefox的问题了</p>
<p>switchhosts下载 通过 firefox直接下载安装，或下载后，把文件拖到firefox中，会自动提示安装</p>
<p>下载地址</p>
<p><a href="http://phpd.cn/switchhosts-1.1.0-fx-windows.xpi" target="_blank">switchhosts-1.1.0-fx-windows.xpi</a></p>
]]></content:encoded>
			<wfw:commentRss>http://phpd.cn/archives/476/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

