<?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>BTMao &#187; cache</title>
	<atom:link href="http://btmao.org/tag/cache/feed/" rel="self" type="application/rss+xml" />
	<link>http://btmao.org</link>
	<description>B小T的幸福生活</description>
	<lastBuildDate>Thu, 11 Feb 2010 03:09:06 +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>缓存，缓存，缓存（二）—— 言归正传说twitter</title>
		<link>http://btmao.org/2009/09/22/cacheandcache_2/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=cacheandcache_2</link>
		<comments>http://btmao.org/2009/09/22/cacheandcache_2/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 15:43:24 +0000</pubDate>
		<dc:creator>BTMao</dc:creator>
				<category><![CDATA[写程序]]></category>
		<category><![CDATA[系统架构]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[comet]]></category>
		<category><![CDATA[kestrel]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[varnish]]></category>

		<guid isPermaLink="false">http://btmao.org/?p=175</guid>
		<description><![CDATA[上一篇我们花了大部分的口水去说MQ，现在我们要言归正传说说twitter的架构了。
我们说到我们要应付的事情出了大量的消息要转发要处理，还有突然爆发的流量等等。解决这样的问题，思路应该是要提高服务器每秒对请求的响应数。通常我们是将Memcached作为Fragment Cache放在我们前端服务器上。当收到用户请求的时候我们的Router会去判断这样的Fragment Cache是否存在，如果存在的话则直接返回。这样的做法是有效率的，而且就memcahced而言，命中率很高，我们很难去确定请求的来源位置，所以我们不如把预先计算好的数据放在网络前端的RAM上面。
当然在这个之后我们还会有很多的问题，并且在twitter向我们展示的宏大架构中我们找到了一些有用的东西。
首先我们看看twitter用到的这些中间件。

memcached，这个就不说了。
Varnish，是取代Squid的一个HTTP缓存，也就是一个Page Cache，据说性能至少是Squid的四倍。这个数据来源也是据说挪威的在线报纸vg.no，用三台Varnish替代了12台Squid，效果还比之前要好。
Kestrel，是twitter团队开发的一个开源的MQ，持久存储效果不错，听说代码写得也很漂亮1200来行，Kestrel是基于Memcached的文本协议，并对这些协议有所优化和完善。这个东西最初是用Ruby搞的后来又在Scala上实现了一遍。Ruby下的那个版本伸缩性不强，特别是Ruby的GC（垃圾处理）不是分代的，这意味这GC在处理完一个队列之后就会把自己给kill掉，然后MQ就崩溃了。后来移植到Scala上，它有成熟的JVM GC这个机制，而且代码还可以更简要。
Comet，一种服务器push的技术，之前facebook貌似也在用。简单的说，就是Client发送一条请求，然后Server接收到之后进入一个无限循环，将Client需要的数据push到一个response里面并且刷新它，这个response并不会被关闭，而是不断的被push数据然后刷新。知道Client断开连接之后才跳出这个循环。正是这样，我们可以说，Ajax解决了单用户的响应，而Comet则在保障性能的前提下，解决了协同多用户的响应。Comet的优点是它可以随时向客户端发送数据而不是仅仅响应用户的输入请求。而且这个数据是在现有的一个单连接上面进行，所以大大降低了发送数据的延迟时间（建立链接的开销和用户发送请求的开销）。

按照twitter自己的说法，最初他cache的策略简单到无敌，有点让人蛋疼，除了在API那里有一个Page Cache之外，然后啥都没有了。不过还好他80%的流量是来自API的。后来随着发展，twitter进行了强有力的架构的建设，其中cache策略的发展也是飞速。
一、Vector Cache，直接放在Data Pool的上面。存放了tweetID和tweetID之间的关系，tweetID是序列化的64位整数。而直写式的设计保证了极高的命中率，使得程序在Data Pool中工作的效率大大的提高，并且极大程度上加大了Data Pool和上层Cache的关联。
二、再往上是一个Row Cache，存放了数据库信息，主要是用户和tweet详细信息的相互对应。同样是直写式，并且使用了一个叫做Cache-money的程序，这是一个针对rail的ActiveRecord的直写式缓存实现。Rail的ActiveRecord具有很强的灵活性，完全不亚于hibernate，而且使用简单，效率也很高。
三、接着往上依次便是用memcached做的Fragment Cache和用Varnish做的Page Cache。其中Fragment Cache是直接消费Row甚至是Vector中的数据，打包成JSON或者XML。虽然这是一个直读式的Cache，但是由于特殊的层级关系和工作特性，他的命中率依然能达到95%以上。
这样的缓存策略下，数据库的大部分压力都被转到了后端程序中，而后端程序对资源的占用较为平滑，可预估性也比较强。
另外twitter还提到要为Page Cache提供一个独立的池，理由很简单，他们希望能够为Page Cache提供一个永远不会自毁的Cache的，而是一种按时间来划分的键值模式，以致于可以根据HTTP的协议头来对数据进行切片。我不喜欢这样的方式，虽然它应该会很有用，但是当所有的流过的页面都要在留下痕迹时，情况也许就会变得不太可控。
这样的Cache的架构也有他的问题，因为底层的两个直写式的Cache总是要去修补上面直读式Cache中的数据，这必然会造成MQ的压力。但毕竟有舍才有得，或许这才是架构的魅力吧。
]]></description>
			<content:encoded><![CDATA[<p><a href="http://btmao.org/2009/09/22/cacheandcache_1/">上一篇</a>我们花了大部分的口水去说MQ，现在我们要言归正传说说twitter的架构了。</p>
<p>我们说到我们要应付的事情出了大量的消息要转发要处理，还有突然爆发的流量等等。解决这样的问题，思路应该是要提高服务器每秒对请求的响应数。通常我们是将Memcached作为Fragment Cache放在我们前端服务器上。当收到用户请求的时候我们的Router会去判断这样的Fragment Cache是否存在，如果存在的话则直接返回。这样的做法是有效率的，而且就memcahced而言，命中率很高，我们很难去确定请求的来源位置，所以我们不如把预先计算好的数据放在网络前端的RAM上面。</p>
<p>当然在这个之后我们还会有很多的问题，并且在twitter向我们展示的宏大架构中我们找到了一些有用的东西。</p>
<p>首先我们看看twitter用到的这些中间件。</p>
<ol>
<li><strong>memcached</strong>，这个就不说了。</li>
<li><strong>Varnish</strong>，是取代Squid的一个HTTP缓存，也就是一个Page Cache，据说性能至少是Squid的四倍。这个数据来源也是据说挪威的在线报纸vg.no，用三台Varnish替代了12台Squid，效果还比之前要好。</li>
<li><strong>Kestrel</strong>，是twitter团队开发的一个开源的MQ，持久存储效果不错，听说代码写得也很漂亮1200来行，Kestrel是基于Memcached的文本协议，并对这些协议有所优化和完善。这个东西最初是用Ruby搞的后来又在Scala上实现了一遍。Ruby下的那个版本伸缩性不强，特别是Ruby的GC（垃圾处理）不是分代的，这意味这GC在处理完一个队列之后就会把自己给kill掉，然后MQ就崩溃了。后来移植到Scala上，它有成熟的JVM GC这个机制，而且代码还可以更简要。</li>
<li><strong>Comet</strong>，一种服务器push的技术，之前facebook貌似也在用。简单的说，就是Client发送一条请求，然后Server接收到之后进入一个无限循环，将Client需要的数据push到一个response里面并且刷新它，这个response并不会被关闭，而是不断的被push数据然后刷新。知道Client断开连接之后才跳出这个循环。正是这样，我们可以说，Ajax解决了单用户的响应，而Comet则在保障性能的前提下，解决了协同多用户的响应。Comet的优点是它可以随时向客户端发送数据而不是仅仅响应用户的输入请求。而且这个数据是在现有的一个单连接上面进行，所以大大降低了发送数据的延迟时间（建立链接的开销和用户发送请求的开销）。</li>
</ol>
<p>按照twitter自己的说法，最初他cache的策略简单到无敌，有点让人蛋疼，除了在API那里有一个Page Cache之外，然后啥都没有了。不过还好他80%的流量是来自API的。后来随着发展，twitter进行了强有力的架构的建设，其中cache策略的发展也是飞速。</p>
<p>一、<strong>Vector Cache</strong>，直接放在Data Pool的上面。存放了tweetID和tweetID之间的关系，tweetID是序列化的64位整数。而直写式的设计保证了极高的命中率，使得程序在Data Pool中工作的效率大大的提高，并且极大程度上加大了Data Pool和上层Cache的关联。</p>
<p>二、再往上是一个<strong>Row Cache</strong>，存放了数据库信息，主要是用户和tweet详细信息的相互对应。同样是直写式，并且使用了一个叫做Cache-money的程序，这是一个针对rail的ActiveRecord的直写式缓存实现。Rail的ActiveRecord具有很强的灵活性，完全不亚于hibernate，而且使用简单，效率也很高。</p>
<p>三、接着往上依次便是用memcached做的<strong>Fragment Cache</strong>和用Varnish做的<strong>Page Cache</strong>。其中Fragment Cache是直接消费Row甚至是Vector中的数据，打包成JSON或者XML。虽然这是一个直读式的Cache，但是由于特殊的层级关系和工作特性，他的命中率依然能达到95%以上。</p>
<p>这样的缓存策略下，数据库的大部分压力都被转到了后端程序中，而后端程序对资源的占用较为平滑，可预估性也比较强。</p>
<p>另外twitter还提到要为Page Cache提供一个独立的池，理由很简单，他们希望能够为Page Cache提供一个永远不会自毁的Cache的，而是一种按时间来划分的键值模式，以致于可以根据HTTP的协议头来对数据进行切片。我不喜欢这样的方式，虽然它应该会很有用，但是当所有的流过的页面都要在留下痕迹时，情况也许就会变得不太可控。</p>
<p>这样的Cache的架构也有他的问题，因为底层的两个直写式的Cache总是要去修补上面直读式Cache中的数据，这必然会造成MQ的压力。但毕竟有舍才有得，或许这才是架构的魅力吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://btmao.org/2009/09/22/cacheandcache_2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>缓存，缓存，缓存（一）—— MQ</title>
		<link>http://btmao.org/2009/09/22/cacheandcache_1/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=cacheandcache_1</link>
		<comments>http://btmao.org/2009/09/22/cacheandcache_1/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 14:28:03 +0000</pubDate>
		<dc:creator>BTMao</dc:creator>
				<category><![CDATA[写程序]]></category>
		<category><![CDATA[系统架构]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[MQ]]></category>

		<guid isPermaLink="false">http://btmao.org/?p=158</guid>
		<description><![CDATA[今天看了twitter关于cache的策略，领略了cache的威力，抒发了一下情感。
Everything runs from memory in Web 2.0.
优化Cache的策略是为了什么，不外乎三点：

减少IO，减少传输，减少CPU计算，减少同时工作的服务器的数量。
对结果进行共享，比如搜索，通常我们将关键词和结果串化进行Cache，然后在时间范围内使用Cache来对分享服务器工作结果。
更快。这永远都是终极的目标。


通常的架构，对于Cache而言，我们有两层，最前端是一个Page Cache，然后是Memcached，最下来就是Data Pool。

这样的架构下我们能够解决大部分的问题，特别是在处理更多常态化的需求时，访问量平稳，数据提交远小于数据读取。但是这么做有瓶颈特别是对于2.0的网站，我们要应付越来越多的用户数据，要不断的缩短Page Cache的有效时间，我们还得应付更多的异常的流量爆发，于是这样的简单的策略就不顶用了。除非我们不计成本的增加我们的服务器，加大我们的带宽，但也许你的老板会说找你还不如请IDC的人吃饭。我们是架构师嘛，为了不让老板这么说，那我们就得找出策略来。
对于无穷无尽的用户数据的提交，我们通常会想到MQ。说说MQ是个什么东西。他是一种消息队列的处理方式，消息列队是分布式应用间交换数据的一种技术，队列被存在磁盘或者RAM里，队列里面是消息，消息直到它被app读走才被删除。这种机制使得app可以独立的运行，它们不必知道各自的位置和状态，执行过程中也不需要等待其他app的响应。
MQ的最上层是一个消息管理器，下面是队列，队列里存放消息。中间是通道，这里是通道是消息传递的管道，是建立在物理网络中的概念，可以说通道MQ整个概念的精华。通道通常被分为三种，消息通道，MQI，Cluster通道。消息通道是一个单向的通道，有Post, Get, Request, Server等不同的类型，一般是建立在MQ服务器与其他事务服务器之间；MQI是建立在app与MQ之间的，是双向的通道；而Cluster通道则是建立在不同的MQ服务器或者同一MQ集群下的不同消息管理器之间。
MQ的工作原理差不多可以来说。

我们先看看单个系统的情况。app1发送一条消息到MQ，并告诉它消息属于队列1，于是MQ则将消息放到队列1里面，app2便可以读取这个消息然后MQ等待app2读取后把这条消息del掉。
下面这个便要复杂一些。app1发送一条消息到MQ，并告诉它消息属于队列2，然而MQ将消息放到队列2之后发现，这个队列其实是在sysB里面的，这时候MQ会把消息放到一个特殊的传输队列中，然后我们建立一个cluster通道，这个通道更像是一个代理app，这个代理app读到数据并传输到sysB，而在确认sysB真正获取到消息之后MQ才释放掉这条消息。在这里我们意识到MQ在确保消息的准确传输，并且一条消息只有一次这样的传输。
移步：缓存，缓存，缓存（二）—— 言归正传说twitter
]]></description>
			<content:encoded><![CDATA[<p>今天看了twitter关于cache的策略，领略了cache的威力，抒发了一下情感。</p>
<blockquote><p>Everything runs from memory in Web 2.0.</p></blockquote>
<p>优化Cache的策略是为了什么，不外乎三点：</p>
<blockquote><ol>
<li>减少IO，减少传输，减少CPU计算，减少同时工作的服务器的数量。</li>
<li>对结果进行共享，比如搜索，通常我们将关键词和结果串化进行Cache，然后在时间范围内使用Cache来对分享服务器工作结果。</li>
<li>更快。这永远都是终极的目标。</li>
</ol>
</blockquote>
<p>通常的架构，对于Cache而言，我们有两层，最前端是一个Page Cache，然后是Memcached，最下来就是Data Pool。<br />
<img src="http://btmao.org/wp-content/2009/09/未标题-1.jpg" alt="simple cache" title="simple cache" width="192" height="343" class="alignnone size-full wp-image-165" /><br />
这样的架构下我们能够解决大部分的问题，特别是在处理更多常态化的需求时，访问量平稳，数据提交远小于数据读取。但是这么做有瓶颈特别是对于2.0的网站，我们要应付越来越多的用户数据，要不断的缩短Page Cache的有效时间，我们还得应付更多的异常的流量爆发，于是这样的简单的策略就不顶用了。除非我们不计成本的增加我们的服务器，加大我们的带宽，但也许你的老板会说找你还不如请IDC的人吃饭。我们是架构师嘛，为了不让老板这么说，那我们就得找出策略来。</p>
<p>对于无穷无尽的用户数据的提交，我们通常会想到MQ。说说MQ是个什么东西。他是一种消息队列的处理方式，消息列队是分布式应用间交换数据的一种技术，队列被存在磁盘或者RAM里，队列里面是消息，消息直到它被app读走才被删除。这种机制使得app可以独立的运行，它们不必知道各自的位置和状态，执行过程中也不需要等待其他app的响应。</p>
<p>MQ的最上层是一个消息管理器，下面是队列，队列里存放消息。中间是通道，这里是通道是消息传递的管道，是建立在物理网络中的概念，可以说通道MQ整个概念的精华。通道通常被分为三种，消息通道，MQI，Cluster通道。消息通道是一个单向的通道，有Post, Get, Request, Server等不同的类型，一般是建立在MQ服务器与其他事务服务器之间；MQI是建立在app与MQ之间的，是双向的通道；而Cluster通道则是建立在不同的MQ服务器或者同一MQ集群下的不同消息管理器之间。</p>
<p>MQ的工作原理差不多可以来说。<br />
<img src="http://btmao.org/wp-content/2009/09/mq1.jpg" alt="mq" title="mq" width="528" height="379" class="alignnone size-full wp-image-169" /><br />
我们先看看单个系统的情况。app1发送一条消息到MQ，并告诉它消息属于队列1，于是MQ则将消息放到队列1里面，app2便可以读取这个消息然后MQ等待app2读取后把这条消息del掉。</p>
<p>下面这个便要复杂一些。app1发送一条消息到MQ，并告诉它消息属于队列2，然而MQ将消息放到队列2之后发现，这个队列其实是在sysB里面的，这时候MQ会把消息放到一个特殊的传输队列中，然后我们建立一个cluster通道，这个通道更像是一个代理app，这个代理app读到数据并传输到sysB，而在确认sysB真正获取到消息之后MQ才释放掉这条消息。在这里我们意识到MQ在确保消息的准确传输，并且一条消息只有一次这样的传输。</p>
<p>移步：<a href="http://btmao.org/2009/09/22/cacheandcache_2/">缓存，缓存，缓存（二）—— 言归正传说twitter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://btmao.org/2009/09/22/cacheandcache_1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
