<?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>Tim[后端技术] &#187; twitter</title>
	<atom:link href="http://timyang.net/tag/twitter/feed/" rel="self" type="application/rss+xml" />
	<link>http://timyang.net</link>
	<description>Tim&#039;s blog, 关于后端架构、互联网技术、分布式、大型网络应用、NoSQL、Key Value等</description>
	<lastBuildDate>Mon, 26 Jul 2010 15:32:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Twitter停用Cassandra原因分析</title>
		<link>http://timyang.net/data/twitter-cassandra/</link>
		<comments>http://timyang.net/data/twitter-cassandra/#comments</comments>
		<pubDate>Sun, 11 Jul 2010 16:29:41 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[data]]></category>
		<category><![CDATA[cassandra]]></category>
		<category><![CDATA[key value store]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=623</guid>
		<description><![CDATA[Twitter在其7.9一篇官方技术博客Cassandra at Twitter Today提到暂停使用Cassandra来代替MySQL存储feed的计划，这是Twitter一个重要的架构策略调整，因为之前Twitter一直是业界Cassandra方向的领头羊。
For now, we&#8217;re not working on using Cassandra as a store for Tweets. This is a change in strategy. Instead we&#8217;re going to continue to maintain our existing Mysql-based storage. We believe that this isn&#8217;t the time to make large scale migration to a new technology. We will focus our Cassandra work [...]]]></description>
			<content:encoded><![CDATA[<p>Twitter在其7.9一篇官方技术博客<a href="http://engineering.twitter.com/2010/07/cassandra-at-twitter-today.html">Cassandra at Twitter Today</a>提到暂停使用Cassandra来代替MySQL存储feed的计划，这是Twitter一个重要的架构策略调整，因为之前Twitter一直是业界Cassandra方向的领头羊。</p>
<blockquote><p>For now, we&#8217;re not working on using Cassandra as a store for Tweets. This is a change in strategy. Instead we&#8217;re going to continue to maintain our existing Mysql-based storage. We believe that this isn&#8217;t the time to make large scale migration to a new technology. We will focus our Cassandra work on new projects that we wouldn&#8217;t be able to ship without a large-scale data store.</p></blockquote>
<h3>Twitter为什么要停用Cassandra</h3>
<p>我们来分析一下Twitter停止使用Cassandra的原因<br />
1. Cassandra仍然缺少大并发海量数据访问的案例及经验，Cassandra来源自Facebook，但是在Facebook内部Cassandra目前只用在inbox search产品上，容量大约有100-200T。且Inbox Search在Facebook的基础架构中也并非核心应用。并且还传出不少rumors说facebook已经放弃Cassandra。</p>
<p>2. 新产品需要一定稳定期，Cassandra代码或许还存在不少问题，但是Twitter如果投入大量的精力来改进Cassandra和比较优化MySQL的投入来看有点得不偿失。在QCon Beijing上@<a href="http://twitter.com/nk">nk</a>也提到Cassandra在Twitter的内部测试中曾经暴露出不少严重的问题。</p>
<h3>Twitter为什么之前选用Cassandra</h3>
<p>此问题曾经在QCon Beijing 2010做过介绍，在去年的第一期广州技术沙龙也有过交流，类似Twitter这样的网站使用Cassandra的主要原因有<br />
1. 数据增长规模需要不断增加新服务器，传统的切分方案在面临增删硬件时候需要手工维护，当数据规模速度增快，业务又不运行停机维护，手工维护的成本增加造成系统运维不堪重负。<br />
2. 不能简单增加服务器解决请求量增长的问题，需要数据架构师精细的规划。<br />
3. 每一个新的特性都需要重复评估数据拆分及访问优化的问题，架构师需要投入大量精力review几乎相同的业务场景。</p>
<p>Twitter的调整对于MySQL业界来说或许是一大利好，MySQL虽然受近期Oracle收购阴影的影响，但是对于目前大多数拥有海量数据访问的网站依然是他们第一选择。MySQL简单，可靠，安全，配套工具完善，运维成熟。业界碰到的大部分可扩展性方面的问题在MySQL中其实都有清晰明确的解决方法。虽然重复sharding的问题很烦，增删机器相关的运维工作也很繁琐，但是这些工作量还是在可以接受的范围内。</p>
<p>究竟Twitter这次策略改变是NoSQL运动的一次挫折还是前进中的一段小插曲？我们拭目以待。目前另外一大Web 2.0巨头Digg仍然在使用Cassandra。</p>
Similar Posts:<ul><li><a href="http://timyang.net/architecture/2010-tech-predictions/" rel="bookmark" title="December 31, 2009">2010年的技术架构建议</a></li>

<li><a href="http://timyang.net/sns/web20-forum/" rel="bookmark" title="June 6, 2010">Web 2.0技术沙龙设想</a></li>

<li><a href="http://timyang.net/sns/facebook-f8-0/" rel="bookmark" title="July 1, 2009">Facebook平台设计(二)</a></li>

<li><a href="http://timyang.net/architecture/twitter-cache-architecture/" rel="bookmark" title="October 28, 2009">Twitter架构图(cache篇)</a></li>

<li><a href="http://timyang.net/architecture/farmville/" rel="bookmark" title="March 8, 2010">FarmVille(美版开心农场)谈架构:所有模块都是一个可降级的服务</a></li>
</ul><!-- Similar Posts took 9.185 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/data/twitter-cassandra/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>构建可扩展的微博架构(qcon beijing 2010演讲)</title>
		<link>http://timyang.net/architecture/microblog-design-qcon-beijing/</link>
		<comments>http://timyang.net/architecture/microblog-design-qcon-beijing/#comments</comments>
		<pubDate>Tue, 11 May 2010 02:00:16 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[架构]]></category>
		<category><![CDATA[microblog]]></category>
		<category><![CDATA[qcon]]></category>
		<category><![CDATA[qconbeijing]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=600</guid>
		<description><![CDATA[在使用Twitter几年的时间里面，经常思考微博如何更好的实现，恰好最近几个月也参与了相关工作，大部分都是工程实践，总结实践会促生更具实际价值的理论。因此在QCon Beijing 2010这次演讲参考了不少网友的意见后选择了《构建可扩展微博架构》的题目。
由于在决定选题时知道来自Twitter总部有30万followers的@nk也会讲一个类似的题目，心中当时有点忐忑，最大的顾虑就是要讲的领域更他重叠，如果他讲得更深入，我就没必要班门弄斧了。后来考虑到以下几个原因还是决定继续

Twitter架构是单IDC设计，从它递增的tweet id就可以看出，后来当面向@nk提问也得到了证实。
中美网络环境差异，单IDC和多IDC有很多设计上的不同
大部分参会人员未必能对英文演讲有深入理解及感悟，中文的演讲可以讲一些细节解释更透彻。
Twitter对故障的容忍度大，国内公司对服务故障通常更敏感。因此国内架构师会考虑设计方案尽量简单可靠，服务需要更稳定。国外开发团队更倾向追求在工作中应用技术创新，因此会导致架构设计理念的不少差异。

演讲的slide如下，登录slideshare之后可以下载。
Build scalable microblog qcon beijing 2010
View more presentations from Tim Y.

这里再补充在qcon演讲未来得及考虑成熟的一个方面，用户规模影响设计，具体是指用户数每上一个数量级，许多设计需要重新考虑。
10万用户级别

 单服务器，前端、后端、cache、db在一起。

百万级

 db和cache单独部署服务器，db或按业务进行拆分(sharding)
 cache或使用一致性hash扩展。
 前端后端还是在一起，但是根据业务拆分，每个业务可分配不同数量的服务器

 千万级

 开始重视架构设计，有专门技术架构师
 需跨机房部署，前端在远程增加反向代理加速，数据库在异地机房使用slave数据库副本
 后端拆分出来，系统内部需要远程调用，内部需远程调用协议。

亿级

 架构更细分，或增加数据架构师，cache架构师，分布式架构师
 数据库sharding碰到烦恼，开始考虑分布式数据服务
 数据访问需要根据业务特点细分。
 开发、运维、测量、调优具备有自己的专有工具。
 所有服务需要地理多机房分布，具备IDC容灾设计。
 服务可降级

上面的数字仅供理解“用户规模影响设计”，数字本身并无具体指导价值。
另外在slide中也提到了，目前新浪微博团队急需人才，对上面相关技术领域感兴趣的架构师及各层次开发人员(熟悉PHP，Java, C或数据架构任意一种)可随时跟我联系，工作地点为北京，联系方式见博客首页。
Similar Posts:Twitter架构图(cache篇)

QCon Beijing qconbeijing全部演讲资料下载

Twitter停用Cassandra原因分析

Web 2.0技术沙龙设想

陈杰谈网游服务器的后端技术
]]></description>
			<content:encoded><![CDATA[<p>在使用Twitter几年的时间里面，经常思考微博如何更好的实现，恰好最近几个月也参与了相关工作，大部分都是工程实践，总结实践会促生更具实际价值的理论。因此在QCon Beijing 2010这次演讲参考了不少网友的意见后选择了《构建可扩展微博架构》的题目。<br />
由于在决定选题时知道来自Twitter总部有30万followers的@<a href="http://twitter.com/nk">nk</a>也会讲一个类似的题目，心中当时有点忐忑，最大的顾虑就是要讲的领域更他重叠，如果他讲得更深入，我就没必要班门弄斧了。后来考虑到以下几个原因还是决定继续</p>
<ul>
<li>Twitter架构是单IDC设计，从它递增的tweet id就可以看出，后来当面向@nk提问也得到了证实。</li>
<li>中美网络环境差异，单IDC和多IDC有很多设计上的不同</li>
<li>大部分参会人员未必能对英文演讲有深入理解及感悟，中文的演讲可以讲一些细节解释更透彻。</li>
<li>Twitter对故障的容忍度大，国内公司对服务故障通常更敏感。因此国内架构师会考虑设计方案尽量简单可靠，服务需要更稳定。国外开发团队更倾向追求在工作中应用技术创新，因此会导致架构设计理念的不少差异。</li>
</ul>
<p>演讲的slide如下，登录slideshare之后可以下载。</p>
<div id="__ss_3973160" style="width: 425px;"><strong style="display: block; margin: 12px 0 4px;"><a title="Build scalable microblog qcon beijing 2010" href="http://www.slideshare.net/iso1600/build-scalable-microblog-qcon-beijing-2010">Build scalable microblog qcon beijing 2010</a></strong><object id="__sse3973160" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=buildscalablemicroblogqconbeijing2010-100505020917-phpapp01&amp;stripped_title=build-scalable-microblog-qcon-beijing-2010" /><param name="name" value="__sse3973160" /><param name="allowfullscreen" value="true" /><embed id="__sse3973160" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=buildscalablemicroblogqconbeijing2010-100505020917-phpapp01&amp;stripped_title=build-scalable-microblog-qcon-beijing-2010" name="__sse3973160" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="padding: 5px 0 12px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/iso1600">Tim Y</a>.</div>
</div>
<p>这里再补充在qcon演讲未来得及考虑成熟的一个方面，用户规模影响设计，具体是指用户数每上一个数量级，许多设计需要重新考虑。</p>
<p><strong>10万用户级别</strong></p>
<ul>
<li> 单服务器，前端、后端、cache、db在一起。</li>
</ul>
<p><strong>百万级</strong></p>
<ul>
<li> db和cache单独部署服务器，db或按业务进行拆分(sharding)</li>
<li> cache或使用一致性hash扩展。</li>
<li> 前端后端还是在一起，但是根据业务拆分，每个业务可分配不同数量的服务器</li>
</ul>
<p><strong> 千万级</strong></p>
<ul>
<li> 开始重视架构设计，有专门技术架构师</li>
<li> 需跨机房部署，前端在远程增加反向代理加速，数据库在异地机房使用slave数据库副本</li>
<li> 后端拆分出来，系统内部需要远程调用，内部需远程调用协议。</li>
</ul>
<p><strong>亿级</strong></p>
<ul>
<li> 架构更细分，或增加数据架构师，cache架构师，分布式架构师</li>
<li> 数据库sharding碰到烦恼，开始考虑分布式数据服务</li>
<li> 数据访问需要根据业务特点细分。</li>
<li> 开发、运维、测量、调优具备有自己的专有工具。</li>
<li> 所有服务需要地理多机房分布，具备IDC容灾设计。</li>
<li> 服务可降级</li>
</ul>
<p>上面的数字仅供理解“用户规模影响设计”，数字本身并无具体指导价值。</p>
<p>另外在slide中也提到了，目前新浪微博团队急需人才，对上面相关技术领域感兴趣的架构师及各层次开发人员(熟悉PHP，Java, C或数据架构任意一种)可随时跟我联系，工作地点为北京，联系方式见博客首页。</p>
Similar Posts:<ul><li><a href="http://timyang.net/architecture/twitter-cache-architecture/" rel="bookmark" title="October 28, 2009">Twitter架构图(cache篇)</a></li>

<li><a href="http://timyang.net/architecture/qcon-beijing-ppt-pdf-slide/" rel="bookmark" title="May 7, 2009">QCon Beijing qconbeijing全部演讲资料下载</a></li>

<li><a href="http://timyang.net/data/twitter-cassandra/" rel="bookmark" title="July 12, 2010">Twitter停用Cassandra原因分析</a></li>

<li><a href="http://timyang.net/sns/web20-forum/" rel="bookmark" title="June 6, 2010">Web 2.0技术沙龙设想</a></li>

<li><a href="http://timyang.net/architecture/game-backend/" rel="bookmark" title="December 25, 2008">陈杰谈网游服务器的后端技术</a></li>
</ul><!-- Similar Posts took 10.365 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/architecture/microblog-design-qcon-beijing/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Twitter“鲸鱼”故障技术剖析</title>
		<link>http://timyang.net/tech/twitter-whale/</link>
		<comments>http://timyang.net/tech/twitter-whale/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 03:56:53 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=564</guid>
		<description><![CDATA[很多人都熟悉Twitter访问故障时候那条白色的鲸鱼。今年新推出的Twitter Engineering Blog讲述了Twitter白鲸技术故障的原因及解决思路。这是到目前为止Twitter公开的最底层的一篇技术资料。
http://engineering.twitter.com/2010/02/anatomy-of-whale.html
当Web Server发生503错误后，Twitter配置了一个前端鲸鱼的显示页面。Twitter对鲸鱼页面有监控体系，当每秒超过100个鲸鱼就会引起报警。

为什么在单位时间内会有大量的&#8221;fail whale&#8221;呢？Twitter成立了一个小组来专门分析此原因。
1. 分析背景资料
“分析性能问题不是一门科学，而是一门艺术”。
鲸鱼页面实际上是对HTTP 503错误的前端展示，503错误通常是调用后台请求超时产生，为了避免用户长时间等待，Twitter的前端(Tim: 也可能是HTTP反向代理)给请求加了超时，避免用户无限制的等待。超时通常是由于单位时间内访问的用户数过大，也有可能是后台某个服务突然变慢造成。
由于Twitter网站每个时刻都有海量的数据流过，因此要简单的定位并解决此问题并不容易。
2. Web page请求分解
Twitter的页面请求后端分成2个阶段，在Twitter内部称为IO phase及CPU phase。IO phase指通过网络服务获取用户的关注关系及相关的Tweets。第2阶段为CPU phase，指将数据聚合、排序及按用户请求的条件输出。IO及CPU各自在1天内消耗的时间如下。

从图上看到，latency增大时IO是主要瓶颈。IO对应于Network service，因此可以判断是某个网络服务性能降级造成。
3. 深度分析
理想情况是网络服务在应答相同参数的请求消耗时间应该基本相同。但实际情况并非如此，我们大胆假设某一网络服务性能下降厉害，于是我们就从统计分析中去寻找这个服务，我们看到Memcached的统计图表如下

4. Memcached 竟然是鲸鱼故障的直接原因
可提高的空间及解决思路

 从上图看，Memcached在 latency高峰的性能比低谷相差一倍，因此最简单的判断是增加硬件即可提高50%的性能。
另外一种思路就是优化Memcached程序，判断程序热点和瓶颈并进行优化。

分析

通过 Google perf-tools project 工具来分析, http://code.google.com/p/google-perftools/ http://github.com/tmm1/perftools.rb
通过自己些的一段分析代码来监控 http://github.com/eaceaser/ruby-call-graph
通过上面工具的call graph来分析热点和瓶颈

最后分析数据Memcached请求分布比例如下
get         0.003s
get_multi   0.008s
add         0.003s
delete      0.003s
set         0.003s
incr        0.003s
prepend     0.002s

get         71.44%
get_multi    8.98%
set          8.69%
delete       5.26%
incr         3.71%
add          1.62%
prepend      0.30%

结论：从上面数据来看，调用热点和瓶颈主要集中在Get操作
因此回头取看Twitter页面执行流程代码，找出优化方法见注释。
get(["User:auth:missionhipster",              # 将昵称转换成uid
get(["User:15460619",                         # 获取user object(用于检查密码)
get(["limit:count:login_attempts:...",        # 防止密码字典攻击
set(["limit:count:login_attempts:...",        # 大部分情况不需要, bug
set(["limit:timestamp:login_attempts:...",    # 大部分情况不需要, bug
get(["limit:timestamp:login_attempts:...",
get(["limit:count:login_attempts:...",        [...]]]></description>
			<content:encoded><![CDATA[<p>很多人都熟悉Twitter访问故障时候那条白色的鲸鱼。今年新推出的<a href="http://engineering.twitter.com/">Twitter Engineering Blog</a>讲述了Twitter白鲸技术故障的原因及解决思路。这是到目前为止Twitter公开的最底层的一篇技术资料。<br />
<a href="http://engineering.twitter.com/2010/02/anatomy-of-whale.html">http://engineering.twitter.com/2010/02/anatomy-of-whale.html</a></p>
<p>当Web Server发生503错误后，Twitter配置了一个前端鲸鱼的显示页面。Twitter对鲸鱼页面有监控体系，当每秒超过100个鲸鱼就会引起报警。<br />
<a href="http://timyang.net/blog/wp-content/uploads/2010/03/whale.png"><img class="alignnone size-full wp-image-565" title="whale" src="http://timyang.net/blog/wp-content/uploads/2010/03/whale.png" alt="" width="391" height="292" /></a></p>
<p>为什么在单位时间内会有大量的&#8221;fail whale&#8221;呢？Twitter成立了一个小组来专门分析此原因。</p>
<h3>1. 分析背景资料</h3>
<blockquote><p>“分析性能问题不是一门科学，而是一门艺术”。</p></blockquote>
<p>鲸鱼页面实际上是对HTTP 503错误的前端展示，503错误通常是调用后台请求超时产生，为了避免用户长时间等待，Twitter的前端(Tim: 也可能是HTTP反向代理)给请求加了超时，避免用户无限制的等待。超时通常是由于单位时间内访问的用户数过大，也有可能是后台某个服务突然变慢造成。<br />
由于Twitter网站每个时刻都有海量的数据流过，因此要简单的定位并解决此问题并不容易。</p>
<h3>2. Web page请求分解</h3>
<p>Twitter的页面请求后端分成2个阶段，在Twitter内部称为IO phase及CPU phase。IO phase指通过网络服务获取用户的关注关系及相关的Tweets。第2阶段为CPU phase，指将数据聚合、排序及按用户请求的条件输出。IO及CPU各自在1天内消耗的时间如下。<br />
<a href="http://timyang.net/blog/wp-content/uploads/2010/03/cpulatency.png"><img class="alignnone size-full wp-image-566" title="cpulatency" src="http://timyang.net/blog/wp-content/uploads/2010/03/cpulatency.png" alt="" width="400" height="285" /></a></p>
<p>从图上看到，latency增大时IO是主要瓶颈。IO对应于Network service，因此可以判断是某个网络服务性能降级造成。</p>
<h3>3. 深度分析</h3>
<p>理想情况是网络服务在应答相同参数的请求消耗时间应该基本相同。但实际情况并非如此，我们大胆假设某一网络服务性能下降厉害，于是我们就从统计分析中去寻找这个服务，我们看到Memcached的统计图表如下<br />
<a href="http://timyang.net/blog/wp-content/uploads/2010/03/networkservice.png"><img class="alignnone size-full wp-image-567" title="networkservice" src="http://timyang.net/blog/wp-content/uploads/2010/03/networkservice.png" alt="" width="400" height="253" /></a></p>
<h3>4. Memcached 竟然是鲸鱼故障的直接原因</h3>
<p>可提高的空间及解决思路</p>
<ol>
<li> 从上图看，Memcached在 latency高峰的性能比低谷相差一倍，因此最简单的判断是增加硬件即可提高50%的性能。</li>
<li>另外一种思路就是优化Memcached程序，判断程序热点和瓶颈并进行优化。</li>
</ol>
<p>分析</p>
<ol>
<li>通过 Google perf-tools project 工具来分析, <a href="http://code.google.com/p/google-perftools/">http://code.google.com/p/google-perftools/</a> <a href="http://github.com/tmm1/perftools.rb">http://github.com/tmm1/perftools.rb</a></li>
<li>通过自己些的一段分析代码来监控 <a href="http://github.com/eaceaser/ruby-call-graph">http://github.com/eaceaser/ruby-call-graph</a></li>
<li>通过上面工具的call graph来分析热点和瓶颈</li>
</ol>
<p>最后分析数据Memcached请求分布比例如下</p>
<pre>get         0.003s
get_multi   0.008s
add         0.003s
delete      0.003s
set         0.003s
incr        0.003s
prepend     0.002s

get         71.44%
get_multi    8.98%
set          8.69%
delete       5.26%
incr         3.71%
add          1.62%
prepend      0.30%
</pre>
<p>结论：从上面数据来看，调用热点和瓶颈主要集中在Get操作</p>
<p>因此回头取看Twitter页面执行流程代码，找出优化方法见注释。</p>
<pre>get(["User:auth:missionhipster",              # 将昵称转换成uid
get(["User:15460619",                         # 获取user object(用于检查密码)
get(["limit:count:login_attempts:...",        # 防止密码字典攻击
set(["limit:count:login_attempts:...",        # 大部分情况不需要, bug
set(["limit:timestamp:login_attempts:...",    # 大部分情况不需要, bug
get(["limit:timestamp:login_attempts:...",
get(["limit:count:login_attempts:...",        # 重复调用，可记住
get(["limit:count:login_attempts:...",        # 重复调用
get(["user:basicauth:...",                    # 防止解密的优化
get(["limit:count:api:...",                   # 请求数限制
set(["limit:count:api:...",                   # 设置请求数，大部分情况不需要，为什么？
set(["limit:timestamp:api:...",               # 大部分情况不需要, bug
get(["limit:timestamp:api:...",
get(["limit:count:api:...",                   # 重复调用
get(["home_timeline:15460619",                # home_timeline业务调用
get(["favorites_timeline:15460619",           # favorites_timeline业务调用
get_multi([["Status:fragment:json:74736693",  # multi_get所有tweets内容
</pre>
<p>上面这段代码将17个请求优化成10个，部分重复调用通过本地cache避免，另外一些没必要的调用直接删除。通过一个简单的优化性能就提高了42%。</p>
<h3>结论</h3>
<ol>
<li>在前文<a href="http://timyang.net/architecture/2010-tech-predictions/">2010年的技术架构建议</a>中提过Cache已经是Web 2.0系统核心元素。从Twitter的故障案例来看Memcached竟然成为了瓶颈并导致了Twitter服务的不稳定。由于在social应用中cache核心化的设计，“RAM is the new disk”，在cache广泛使用后也变得调用成本增加，需要考虑进行系统的规划减少不必要的调用。避免开发人员在代码中随意使用cache</li>
<li>如何定位瓶颈，可以借鉴Google perf-tools项目及上面其他分析工具的思路。</li>
<li>Twitter页面执行流程值得参考</li>
<li>整个故障流程分析图如下</li>
</ol>
<p><a href="http://timyang.net/blog/wp-content/uploads/2010/03/twitter_whale_error.png"><img class="alignnone size-full wp-image-569" title="twitter_whale_error" src="http://timyang.net/blog/wp-content/uploads/2010/03/twitter_whale_error.png" alt="" width="412" height="701" /></a></p>
Similar Posts:<ul><li><a href="http://timyang.net/architecture/twitter-cache-architecture/" rel="bookmark" title="October 28, 2009">Twitter架构图(cache篇)</a></li>

<li><a href="http://timyang.net/web/pagination/" rel="bookmark" title="January 19, 2010">用Twitter的cursor方式进行Web数据分页</a></li>

<li><a href="http://timyang.net/data/mcdb-tt-redis/" rel="bookmark" title="August 11, 2009">MemcacheDB, Tokyo Tyrant, Redis performance test</a></li>

<li><a href="http://timyang.net/sns/twitter-api-changes/" rel="bookmark" title="December 30, 2009">Twitter API最近的一些飞跃</a></li>

<li><a href="http://timyang.net/tech/twitter-operations/" rel="bookmark" title="November 2, 2009">Twitter系统运维经验</a></li>
</ul><!-- Similar Posts took 12.612 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/tech/twitter-whale/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>用Twitter的cursor方式进行Web数据分页</title>
		<link>http://timyang.net/web/pagination/</link>
		<comments>http://timyang.net/web/pagination/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 14:16:58 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=532</guid>
		<description><![CDATA[本文讨论Web应用中实现数据分页功能，不同的技术实现方式的性能方区别。

上图功能的技术实现方法拿MySQL来举例就是
select * from msgs where thread_id = ? limit page * count, count
不过在看Twitter API的时候，我们却发现不少接口使用cursor的方法，而不用page, count这样直观的形式，如 followers ids 接口
URL:
http://twitter.com/followers/ids.format
Returns an array of numeric IDs for every user following the specified user.
Parameters:
* cursor. Required. Breaks the results into pages. Provide a value of -1 to begin paging. Provide values as returned to in the response body&#8217;s next_cursor [...]]]></description>
			<content:encoded><![CDATA[<p>本文讨论Web应用中实现数据分页功能，不同的技术实现方式的性能方区别。<br />
<a href="http://timyang.net/blog/wp-content/uploads/2010/01/pagination.png"><img class="alignnone size-full wp-image-533" title="pagination" src="http://timyang.net/blog/wp-content/uploads/2010/01/pagination.png" alt="" width="376" height="148" /></a><br />
上图功能的技术实现方法拿MySQL来举例就是</p>
<pre>select * from msgs where thread_id = ? limit page * count, count</pre>
<p>不过在看Twitter API的时候，我们却发现不少接口使用cursor的方法，而不用page, count这样直观的形式，如 followers ids 接口</p>
<blockquote><p><strong>URL:</strong></p>
<p>http://twitter.com/followers/ids.format</p>
<p>Returns an array of numeric IDs for every user following the specified user.</p>
<p><strong>Parameters:</strong><br />
* cursor. Required. Breaks the results into pages. Provide a value of -1 to begin paging. Provide values as returned to in the response body&#8217;s next_cursor and previous_cursor attributes to page back and forth in the list.<br />
o Example: http://twitter.com/followers/ids/barackobama.xml?cursor=-1<br />
o Example: http://twitter.com/followers/ids/barackobama.xml?cursor=-1300794057949944903</p></blockquote>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 101px; width: 1px; height: 1px;"><span style="font-family: courier new,monospace;"><span style="font-family: arial,sans-serif;"><span style="font-family: courier new,monospace;"><span style="font-family: arial,sans-serif;"><span style="font-family: courier new,monospace;">http://twitter.com/followers/ids.<em>format</em></span></span></span></span></span></div>
<p>从上面描述可以看到，http://twitter.com/followers/ids.xml 这个调用需要传cursor参数来进行分页，而不是传统的 url?page=n&amp;count=n的形式。这样做有什么优点呢？是否让每个cursor保持一个当时数据集的镜像？防止由于结果集实时改变而产生查询结果有重复内容？<br />
在Google Groups这篇<a href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/712b4765028d527c/3f444faee8f8d7ef">Cursor Expiration</a>讨论中Twitter的架构师<a href="http://twitter.com/jkalucki">John Kalucki</a>提到</p>
<blockquote><p>A cursor is an opaque deletion-tolerant index into a Btree keyed by source<br />
userid and modification time. It brings you to a point in time in the<br />
reverse chron sorted list. So, since you can&#8217;t change the past, other than<br />
erasing it, it&#8217;s effectively stable. (Modifications bubble to the top.) But<br />
you have to deal with additions at the list head and also block shrinkage<br />
due to deletions, so your blocks begin to overlap quite a bit as the data<br />
ages. (If you cache cursors and read much later, you&#8217;ll see the first few<br />
rows of cursor[n+1]&#8217;s block as duplicates of the last rows of cursor[n]&#8217;s<br />
block. The intersection cardinality is equal to the number of deletions in<br />
cursor[n]&#8217;s block). Still, there may be value in caching these cursors and<br />
then heuristically rebalancing them when the overlap proportion crosses some<br />
threshold.</p></blockquote>
<p>在另外一篇<a href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/cfccfa4302ff9729/66d6b91f9a6bf96d">new cursor-based pagination not multithread-friendly</a>中John又提到</p>
<blockquote><p>The page based approach does not scale with large sets. We can no<br />
longer support this kind of API without throwing a painful number of<br />
503s.</p>
<p>Working with row-counts forces the data store to recount rows in an O<br />
(n^2) manner. Cursors avoid this issue by allowing practically<br />
constant time access to the next block. The cost becomes O(n/<br />
block_size) which, yes, is O(n), but a graceful one given n &lt; 10^7 and<br />
a block_size of 5000. The cursor approach provides a more complete and<br />
consistent result set.</p>
<p>Proportionally, very few users require multiple page fetches with a<br />
page size of 5,000.</p>
<p>Also, scraping the social graph repeatedly at high speed is could<br />
often be considered a low-value, borderline abusive use of the social<br />
graph API.</p></blockquote>
<p>通过这两段文字我们已经很清楚了，对于大结果集的数据，使用cursor方式的目的主要是为了极大地提高性能。还是拿MySQL为例说明，比如翻页到100,000条时，不用cursor，对应的SQL为</p>
<pre>select * from msgs limit 100000, 100</pre>
<p>在一个百万记录的表上，第一次执行这条SQL需要5秒以上。<br />
假定我们使用表的主键的值作为cursor_id, 使用cursor分页方式对应的SQL可以优化为</p>
<pre>select * from msgs where id &gt; cursor_id limit 100;</pre>
<p>同样的表中，通常只需要100ms以下, 效率会提高几十倍。MySQL limit性能差别也可参看我3年前写的一篇不成熟的文章 <a href="http://hi.baidu.com/jabber/blog/item/67485b43379290119313c6b5.html">MySQL LIMIT 的性能问题</a>。</p>
<h3>结论</h3>
<p>建议Web应用中<strong>大数据集翻页可以采用这种cursor方式</strong>，不过此方法缺点是翻页时必须连续，不能跳页。</p>
Similar Posts:<ul><li><a href="http://timyang.net/architecture/friendfeed-like-aggregator/" rel="bookmark" title="April 3, 2009">Ideas for creating a friendfeed like feed aggregator system</a></li>

<li><a href="http://timyang.net/tech/twitter-whale/" rel="bookmark" title="March 8, 2010">Twitter“鲸鱼”故障技术剖析</a></li>

<li><a href="http://timyang.net/python/python-rest/" rel="bookmark" title="February 12, 2009">用Python实现CRUD功能REST服务</a></li>

<li><a href="http://timyang.net/architecture/twitter-cache-architecture/" rel="bookmark" title="October 28, 2009">Twitter架构图(cache篇)</a></li>

<li><a href="http://timyang.net/sns/twitter-api-changes/" rel="bookmark" title="December 30, 2009">Twitter API最近的一些飞跃</a></li>
</ul><!-- Similar Posts took 9.776 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/web/pagination/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Twitter API最近的一些飞跃</title>
		<link>http://timyang.net/sns/twitter-api-changes/</link>
		<comments>http://timyang.net/sns/twitter-api-changes/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 04:41:26 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[SNS]]></category>
		<category><![CDATA[firehose]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=516</guid>
		<description><![CDATA[Twitter的平台总监Ryan Sarver在最近一封给开发者公开email Platform announcements from LeWeb提到，打算将API用户请求限制扩大10倍，由目前的150次/小时扩大到1,500次/小时(但同时将搜索范围缩短到7天)。
*Auth announcements*
With the recent launches of Retweet, Lists and Geotagging we have seen
applications struggle to provide the experience they want for their users
within the 150 req/hr limit. We are excited to open the skies up a bit and
provide some more room for developers to work within. Starting in a few
weeks [...]]]></description>
			<content:encoded><![CDATA[<p>Twitter的平台总监Ryan Sarver在最近一封给开发者公开email <a href="http://groups.google.com/group/twitter-development-talk/browse_thread/thread/a1076d83d70d0450">Platform announcements from LeWeb</a>提到，打算将API用户请求限制扩大10倍，由目前的150次/小时扩大到1,500次/小时(但同时将搜索范围缩短到7天)。</p>
<blockquote><p>*Auth announcements*<br />
With the recent launches of Retweet, Lists and Geotagging we have seen<br />
applications struggle to provide the experience they want for their users<br />
within the 150 req/hr limit. We are excited to open the skies up a bit and<br />
provide some more room for developers to work within. Starting in a few<br />
weeks all OAuth requests to api.twitter.com/1/ will be able to take<br />
advantage of a 10x rate limit increase. Basic Whitelisting still exists and<br />
is unchanged. We look forward to what this means in terms of the increased<br />
richness around the user experience in Twitter apps.</p></blockquote>
<p>注意文中的限制是OAuth客户端，为什么只限OAuth客户端？由于OAuth客户端可控性较强。如果发现app有滥用api嫌疑，可以直接suspend这个app；而另外一种鉴权方式Basic Authentication方式并不强制client传递app id, 服务器判断app abuse较困难。</p>
<p>在我的理解，microblog的最大的特性应该是realtime,(另外一特性应是social graph), 即使Twitter扩大rate limit, REST方式的HTTP协议终究没法实现realtime，如果所有的客户端都1分钟请求25次(1,500/60=25)，twitter服务器稳定性一向声誉不佳，增大后能否经住考验也是一个疑问。</p>
<p>如果要实现真正的realtime, 目前有http callback或者XMPP等方案。callback由于客户端通常在防火墙内并不可行。XMPP由于协议栈庞大，服务端及客户端编写都比较繁琐，而且XMPP是为IM协议设计，所以并不十分适合twitter api。</p>
<p>另外Twitter在邮件中还提到，打算将所有最新更新feed的数据流(Twitter称为Firehose)向所有人开放。</p>
<blockquote><p>*Firehose for everyone*<br />
Finally, the announcement that has garnered the most coverage and<br />
excitement. As I stated in the session at LeWeb we are committed to<br />
providing a framework for any company big or small, rich or poor to do a<br />
deal with us to get access to the Firehose in the same way we did deals with<br />
Google and Microsoft. We want everyone to have the opportunity &#8212; terms will<br />
vary based on a number of variables but we want a two-person startup in a<br />
garage to have the same opportunity to build great things with the full feed<br />
that someone with a billion dollar market cap does. There are still a lot of<br />
details to be fleshed out and communicated, but this a top priority for us<br />
and we look forward to what types of companies and products get built on top<br />
of this unique and rich stream.</p></blockquote>
<p>Firehose可以理解成所有Twitter最近更新的水龙头，目前只对 Microsoft, Google等少量公司开放。Twitter表示以后即使&#8221;a two-person startup in a garage&#8221;这样的公司也可以获取firehose访问权限, &#8220;We want everyone to have the opportunity&#8221;。相信不少公司将会为这一特性而激动甚至疯狂。firehose开放意味为第三方提供了无限的创意空间，另外它也会对Twitter已有的服务search, geotag等业务构成威胁，走出这一步需要很大的勇气。</p>
<p>以上文字基本已在<a href="http://t.sina.com.cn/" target="_blank">新浪微博</a>发表过，整理后就成了一篇blog, 欢迎在新浪微博关注我，点这里进入 <a href="http://t.sina.com.cn/timyang" target="_blank">http://t.sina.com.cn/timyang</a></p>
Similar Posts:<ul><li><a href="http://timyang.net/sns/web20-forum/" rel="bookmark" title="June 6, 2010">Web 2.0技术沙龙设想</a></li>

<li><a href="http://timyang.net/web/pubsubhubbub/" rel="bookmark" title="October 29, 2009">PubSubHubbub的价值</a></li>

<li><a href="http://timyang.net/architecture/friendfeed-like-aggregator/" rel="bookmark" title="April 3, 2009">Ideas for creating a friendfeed like feed aggregator system</a></li>

<li><a href="http://timyang.net/google/google-wave/" rel="bookmark" title="May 31, 2009">从技术角度看Google Wave</a></li>

<li><a href="http://timyang.net/architecture/twitter-cache-architecture/" rel="bookmark" title="October 28, 2009">Twitter架构图(cache篇)</a></li>
</ul><!-- Similar Posts took 10.944 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/sns/twitter-api-changes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Twitter系统运维经验</title>
		<link>http://timyang.net/tech/twitter-operations/</link>
		<comments>http://timyang.net/tech/twitter-operations/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 12:46:49 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[velocity]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=463</guid>
		<description><![CDATA[最近看到的另外一个介绍Twitter技术的视频[Slides] [Video (GFWed)]，这是Twitter的John Adams在Velocity 2009的一个演讲，主要介绍了Twitter在系统运维方面一些经验。 本文大部分整理的观点都在Twitter(@xmpp)上发过，这里全部整理出来并补充完整。
Twitter没有自己的硬件，都是由NTTA来提供，同时NTTA负责硬件相关的网络、带宽、负载均衡等业务，Twitter operations team只关注核心的业务，包括Performance，Availability，Capacity Planning容量规划，配置管理等，这个可能跟国内一般的互联网公司有所区别。
1. 运维经验
* Metrics
Twitter的监控后台几乎都是图表(critical metrics)，类似驾驶室的转速表，时速表，让操作者可以迅速的了解系统当前的运作状态。联想到我们做的类似监控后台，数据很多，但往往还需要浏览者做二次分析判断，像这样满屏都是图表的方法做得还不够，可以学习下这方面经验。 据John介绍可以从图表上看到系统的瓶颈-系统最弱的环节(web, mq, cache, db?)
根据图表可以科学的制定系统容量规划，而不是事后救火。
* 配置管理
每个系统都需要一个自动配置管理系统，越早越好，这条一整理发到Twitter上去之后引起很多回应。
* Darkmode
配置界面可以enable/disable 高计算消耗或高I/O的功能，也相当于优雅降级，系统压力过大时取消一些非核心但消耗资源大的功能。
* 进程管理
Twitter做了一个&#8221;Seppaku&#8221; patch, 就是将Daemon在完成了n个requests之后主动kill掉，以保持健康的low memory状态，这种做法据了解国内也有不少公司是这样做。
* 硬件
Twitter将CPU由AMD换成Xeon之后，获得30%性能提升，将CPU由双核/4核换成8核之后，减少了40%的CPU, 不过John也说，这种升级不适合自己购买硬件的公司。
2. 代码协同经验
* Review制度
Twitter有上百个模块，如果没有一个好的制度，容易引起代码修改冲突，并把问题带给最终用户。所以Twitter有一强制的source code review制度, 如果提交的代码的svn comment没有&#8221;reviewed by xxx&#8221;, 则pre-commit脚本会让提交失败, review过的代码提交后会通过自动配置管理系统应用到上百台服务器上。 有@xiaomics同学在Twitter上马上就问，时间成本能否接受？如果有紧急功能怎么办？个人认为紧急修改时有两人在场，一人修改一人review也不是什么难事。
* 部署管理
从部署图表可以看到每个发布版本的CPU及latency变化，如果某个新版本latency图表有明显的向上跳跃，则说明该发布版本存在问题。另外在监控首页列出各个模块最后deploy版本的时间，可以清楚的看到代码库的现状。
* 团队沟通
Campfire来协同工作，campfire有点像群，但是更适合协同工作。对于Campfire就不做更多介绍，可参考Campfire官方说明。
3. cache

Memcache key hash, 使用FNV hash 代替 MD5 hash，因为FNV更快。
开发了Cache Money plugin(Ruby), 给应用程序提供read-through, write-through cache, 就像一个db访问的钩子，当读写数据库的时候会自动更新cache, 避免了繁琐的cache更新代码。
“Evictions make the [...]]]></description>
			<content:encoded><![CDATA[<p>最近看到的另外一个介绍Twitter技术的视频[<a href="http://assets.en.oreilly.com/1/event/29/Fixing%20Twitter_%20Improving%20the%20Performance%20and%20Scalability%20of%20the%20World%27s%20Most%20Popular%20Micro-blogging%20Site%20Presentation.pdf">Slides</a>] [<a href="http://blip.tv/file/2300327">Video</a> (GFWed)]，这是Twitter的John Adams在<a href="http://en.oreilly.com/velocity2009">Velocity 2009</a>的一个演讲，主要介绍了Twitter在系统运维方面一些经验。 本文大部分整理的观点都在Twitter(@<a href="http://twitter.com/xmpp">xmpp</a>)上发过，这里全部整理出来并补充完整。</p>
<p>Twitter没有自己的硬件，都是由NTTA来提供，同时NTTA负责硬件相关的网络、带宽、负载均衡等业务，Twitter operations team<strong>只关注核心的业务，包括Performance，Availability，Capacity Planning容量规划，配置管理</strong>等，这个可能跟国内一般的互联网公司有所区别。</p>
<h3>1. 运维经验</h3>
<h4>* Metrics</h4>
<p>Twitter的监控后台几乎都是图表(critical metrics)，类似驾驶室的转速表，时速表，让操作者可以迅速的了解系统当前的运作状态。联想到我们做的类似监控后台，数据很多，但往往还需要浏览者做二次分析判断，像这样满屏都是图表的方法做得还不够，可以学习下这方面经验。 据John介绍可以从图表上看到系统的瓶颈-系统最弱的环节(web, mq, cache, db?)<br />
根据图表可以科学的制定系统容量规划，而不是事后救火。<img class="alignnone size-full wp-image-464" title="Twitter operation dashboard" src="http://timyang.net/blog/wp-content/uploads/2009/11/dashboard.jpg" alt="Twitter operation dashboard" width="543" height="488" /></p>
<h4>* 配置管理</h4>
<p>每个系统都需要一个自动配置管理系统，越早越好，这条一整理发到Twitter上去之后引起很多回应。</p>
<h4>* Darkmode</h4>
<p>配置界面可以enable/disable 高计算消耗或高I/O的功能，也相当于优雅降级，系统压力过大时取消一些非核心但消耗资源大的功能。</p>
<h4>* 进程管理</h4>
<p>Twitter做了一个&#8221;Seppaku&#8221; patch, 就是将Daemon在完成了n个requests之后主动kill掉，以保持健康的low memory状态，这种做法据了解国内也有不少公司是这样做。</p>
<h4>* 硬件</h4>
<p>Twitter将CPU由AMD换成Xeon之后，获得30%性能提升，将CPU由双核/4核换成8核之后，减少了40%的CPU, 不过John也说，这种升级不适合自己购买硬件的公司。</p>
<h3>2. 代码协同经验</h3>
<h4>* Review制度</h4>
<p>Twitter有上百个模块，如果没有一个好的制度，容易引起代码修改冲突，并把问题带给最终用户。所以Twitter有一强制的source code review制度, 如果提交的代码的svn comment没有&#8221;reviewed by xxx&#8221;, 则pre-commit脚本会让提交失败, review过的代码提交后会通过自动配置管理系统应用到上百台服务器上。 有@xiaomics同学在Twitter上马上就问，时间成本能否接受？如果有紧急功能怎么办？个人认为紧急修改时有两人在场，一人修改一人review也不是什么难事。</p>
<h4>* 部署管理</h4>
<p>从部署图表可以看到每个发布版本的CPU及latency变化，如果某个新版本latency图表有明显的向上跳跃，则说明该发布版本存在问题。另外在监控首页列出各个模块最后deploy版本的时间，可以清楚的看到代码库的现状。</p>
<h4>* 团队沟通</h4>
<p>Campfire来协同工作，campfire有点像群，但是更适合协同工作。对于Campfire就不做更多介绍，可参考<a href="http://campfirenow.com/">Campfire</a>官方说明。</p>
<h3>3. cache</h3>
<ul>
<li>Memcache key hash, 使用FNV hash 代替 MD5 hash，因为FNV更快。</li>
<li>开发了Cache Money plugin(Ruby), 给应用程序提供<strong>read-through, write-through cache</strong>, 就像一个db访问的钩子，当读写数据库的时候会自动更新cache, 避免了繁琐的cache更新代码。</li>
<li>“Evictions make the cache unreliable for important configuration data”，Twitter使用memcache的一条经验是，不同类型的数据需放在不同的mc,避免eviction，跟作者前文<a href="http://timyang.net/data/memcached-lru-evictions/">Memcached数据被踢(evictions&gt;0)现象分析</a>中的一些经验一致。</li>
<li>Memcached SEGVs, Memcached崩溃(cold cache problem)据称会给这种高度依赖Cache的Web 2.0系统带来灾难，不知道Twitter具体怎么解决。</li>
<li>在Web层Twitter使用了Varnish作为反向代理，并对其评价较高。</li>
</ul>
Similar Posts:<ul><li><a href="http://timyang.net/architecture/twitter-cache-architecture/" rel="bookmark" title="October 28, 2009">Twitter架构图(cache篇)</a></li>

<li><a href="http://timyang.net/tech/twitter-whale/" rel="bookmark" title="March 8, 2010">Twitter“鲸鱼”故障技术剖析</a></li>

<li><a href="http://timyang.net/programming/memcache-mutex/" rel="bookmark" title="July 26, 2010">Memcache mutex设计模式</a></li>

<li><a href="http://timyang.net/architecture/warehouse-scale-computer/" rel="bookmark" title="May 24, 2009">Google说，一个Datacenter就是一台计算机</a></li>

<li><a href="http://timyang.net/data/twitter-cassandra/" rel="bookmark" title="July 12, 2010">Twitter停用Cassandra原因分析</a></li>
</ul><!-- Similar Posts took 11.258 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/tech/twitter-operations/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Twitter架构图(cache篇)</title>
		<link>http://timyang.net/architecture/twitter-cache-architecture/</link>
		<comments>http://timyang.net/architecture/twitter-cache-architecture/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 12:55:53 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[架构]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=438</guid>
		<description><![CDATA[根据网上公开资料整理的Twitter架构，主要是cache方面，加了作者自己的补充，跟实际的架构未必完全一致。

一些数据：

Cache分Page cache, fragment cache, row cache, vector Cache, cache命中率见图。
Fragment cache存放了API各种请求格式的数据，包括XML, JSON, RSS, ATOM。
发表Tweets是先放入Kestrel, 再异步处理，Kestrel用的也是memcached协议。
API requests: 550 r/s。
POST tweets: 峰值：平时 80tweets/s, 奥巴马就任时达到 350tweets/s。
Aggregator模块需要访问memcached multi get  数百个/s。
Ruby on Rails前面还用了Varnish作前端反向代理。

参考资料：

QCon London 2009: Upgrading Twitter without service disruptions
Improving Running Components at Twitter (PDF slide)

Similar Posts:Twitter“鲸鱼”故障技术剖析

MemcacheDB, Tokyo Tyrant, Redis performance test

FarmVille(美版开心农场)谈架构:所有模块都是一个可降级的服务

Twitter系统运维经验

Twitter停用Cassandra原因分析
]]></description>
			<content:encoded><![CDATA[<p>根据网上公开资料整理的Twitter架构，主要是cache方面，加了作者自己的补充，跟实际的架构未必完全一致。<br />
<img class="alignnone size-full wp-image-439" title="twitter cache" src="http://timyang.net/blog/wp-content/uploads/2009/10/twittercache.png" alt="twitter cache" width="708" height="738" /><br />
一些数据：</p>
<ul>
<li>Cache分Page cache, fragment cache, row cache, vector Cache, cache命中率见图。</li>
<li>Fragment cache存放了API各种请求格式的数据，包括XML, JSON, RSS, ATOM。</li>
<li>发表Tweets是先放入Kestrel, 再异步处理，Kestrel用的也是memcached协议。</li>
<li>API requests: 550 r/s。</li>
<li>POST tweets: 峰值：平时 80tweets/s, 奥巴马就任时达到 350tweets/s。</li>
<li>Aggregator模块需要访问memcached multi get  数百个/s。</li>
<li>Ruby on Rails前面还用了Varnish作前端反向代理。</li>
</ul>
<p>参考资料：</p>
<ul>
<li><a href="http://gojko.net/2009/03/16/qcon-london-2009-upgrading-twitter-without-service-disruptions/">QCon London 2009: Upgrading Twitter without service disruptions</a></li>
<li><a href="http://qconlondon.com/london-2009/file?path=/qcon-london-2009/slides/EvanWeaver_ImprovingRunningComponentsAtTwitter.pdf">Improving Running Components at Twitter</a> (PDF slide)</li>
</ul>
Similar Posts:<ul><li><a href="http://timyang.net/tech/twitter-whale/" rel="bookmark" title="March 8, 2010">Twitter“鲸鱼”故障技术剖析</a></li>

<li><a href="http://timyang.net/data/mcdb-tt-redis/" rel="bookmark" title="August 11, 2009">MemcacheDB, Tokyo Tyrant, Redis performance test</a></li>

<li><a href="http://timyang.net/architecture/farmville/" rel="bookmark" title="March 8, 2010">FarmVille(美版开心农场)谈架构:所有模块都是一个可降级的服务</a></li>

<li><a href="http://timyang.net/tech/twitter-operations/" rel="bookmark" title="November 2, 2009">Twitter系统运维经验</a></li>

<li><a href="http://timyang.net/data/twitter-cassandra/" rel="bookmark" title="July 12, 2010">Twitter停用Cassandra原因分析</a></li>
</ul><!-- Similar Posts took 15.815 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/architecture/twitter-cache-architecture/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>关于阙宏宇lighttpd与mod_cache在twitter上的一些讨论</title>
		<link>http://timyang.net/programming/lighttpd-mod_cache-twitter/</link>
		<comments>http://timyang.net/programming/lighttpd-mod_cache-twitter/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 14:52:48 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[mod_cache]]></category>
		<category><![CDATA[thread]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=306</guid>
		<description><![CDATA[6月28日的beta技术沙龙上阙宏宇介绍了lighttpd与modcache，视频及slide在 http://club.blogbeta.com/76.html，modcache是阙宏宇开发的一个lighttpd module, 它在部分程度上可以替代squid。在活动的介绍上提到
lighttpd是基于事件驱动的高性能web服务器。mod_cache是在lighttpd上运行的缓存插件。lighttpd+mod_cache 搭建的缓存系统，具有配置简单，性能高，在很多大型系统得到了广泛应用。本次活动由mod_cache作者阙宏宇介绍lighttpd的基础知识，讲解 lighttpd高性能的原理，讨论lighttpd的扩展编写方法等高级话题。也将分享mod_cache插件的特点和使用经验。
在看视频的过程中我在twitter上也分享了阙宏宇的一些观点，同时也引起了一些网友的关注及讨论，部分内容摘录如下(下文每行开头的链接是发言人的twitter ID)
xmpp: 刚看到阙宏宇的lighttpd mod_cache视频，他的调优建议把keep-alive设成=0(相当于关掉)，个人不是很认同
xmpp: 阙宏宇称”使用lighttpd+mod_cache比squid快一个数量级，原因是lighttpd用event/file, squid用thread/db“ 视频第41分钟
xmpp: 阙宏宇最后说web server使用多线程是倒退，并拿memcached单线程跑得很好来证明。但是我觉得并不能单纯这么考虑，一是多核CPU被浪费，二是web server(io密集, 慢连接)和cache server特性有区别不能简单相提并论。
SnaiX: @xmpp 我觉得阙宏宇的言论很有问题，首先所谓的event based也是需要较大消耗的，且，squid有n中模式可以选择，包括了所谓的db based files based。
xmpp: @SnaiX 是阿，他的软件对于某些场景可能有意义，但是大部分情况还是没法代替squid的，视频最后Q&#38;A也看到，比如没法实现合并多个相同资源的并发请求等
xmpp: @eishn: &#8220;对于任务的处理, 不可避免会涉及到 multithreading 的问题&#8221; 是 @yingfeng 提到的，在我的理解，“任务”是指为了返回请求，需要消耗cpu及io等待,直至输出内容返回网络这个执行过程
yingfeng: @xmpp 读过POSA II便可知道event based只是解决了acceptor端的问题，对于任务的处理，不可避免会涉及到multithreading的问题
xmpp: @SnaiX: 批评多线程者无非就是批评锁，所以1最极端者就用单线程，2退一步者就线程不共享内存，线程间用消息通讯，3普通多线程通常加锁，因此会带来等待锁(其实Semaphore锁对等待线程没什么开销的)及线程切换开销，因此开发多线程程序只要了解底层原理就没什么恐惧的
xmpp: @eishn 你说的是实现方法是协程吗，我倒很想看到你说的实现方法详细描述。如果是协程，它虽然避免了锁，但还是存在切换开销，而且也不能随时切换，我觉得如要利用多核优势，多线程是大势所趋
alpha86: @xmpp 静态文件的请求可以开keep-alive, 动态请求的话其实keep-alive起不到多大效果。
Joshfeng: @xmpp 我个人觉得keep-alive的设置要看服务器上主要是什么类型的文件
xiaoxiaolu: RT @xmpp: &#8230; 他的调优建议把keep-alive设成=0(相当于关掉)，个人不是很认同//就web而言,我挺认同的
mikespook: RT: @xiaoxiaolu: RT @xmpp: 刚看到&#8230;.调优建议把keep-alive设成=0(相当于关掉)，个人不是很认同//就web而言,我挺认同的// [...]]]></description>
			<content:encoded><![CDATA[<p>6月28日的beta技术沙龙上阙宏宇介绍了<a href="http://www.lighttpd.net/">lighttpd</a>与<a href="http://www.linux.com.cn/modcache/">modcache</a>，视频及slide在 <a href="http://club.blogbeta.com/76.html">http://club.blogbeta.com/76.html</a>，modcache是阙宏宇开发的一个lighttpd module, 它在部分程度上可以替代squid。在活动的介绍上提到</p>
<blockquote><p>lighttpd是基于事件驱动的高性能web服务器。mod_cache是在lighttpd上运行的缓存插件。lighttpd+mod_cache 搭建的缓存系统，具有配置简单，性能高，在很多大型系统得到了广泛应用。本次活动由mod_cache作者阙宏宇介绍lighttpd的基础知识，讲解 lighttpd高性能的原理，讨论lighttpd的扩展编写方法等高级话题。也将分享mod_cache插件的特点和使用经验。</p></blockquote>
<p>在看视频的过程中我在twitter上也分享了阙宏宇的一些观点，同时也引起了一些网友的关注及讨论，部分内容摘录如下(下文每行开头的链接是发言人的twitter ID)</p>
<p><a href="http://twitter.com/xmpp">xmpp</a>: 刚看到阙宏宇的lighttpd mod_cache视频，他的调优建议把keep-alive设成=0(相当于关掉)，个人不是很认同</p>
<p><a href="http://twitter.com/xmpp">xmpp</a>: 阙宏宇称”使用lighttpd+mod_cache比squid快一个数量级，原因是lighttpd用event/file, squid用thread/db“ 视频第41分钟</p>
<p><a href="http://twitter.com/xmpp">xmpp</a>: 阙宏宇最后说web server使用多线程是倒退，并拿memcached单线程跑得很好来证明。但是我觉得并不能单纯这么考虑，一是多核CPU被浪费，二是web server(io密集, 慢连接)和cache server特性有区别不能简单相提并论。</p>
<p><a href="http://twitter.com/SnaiX">SnaiX</a>: @xmpp 我觉得阙宏宇的言论很有问题，首先所谓的event based也是需要较大消耗的，且，squid有n中模式可以选择，包括了所谓的db based files based。</p>
<p><a href="http://twitter.com/xmpp">xmpp</a>: @<a href="http://twitter.com/SnaiX">SnaiX</a> 是阿，他的软件对于某些场景可能有意义，但是大部分情况还是没法代替squid的，视频最后Q&amp;A也看到，比如没法实现合并多个相同资源的并发请求等</p>
<p><a href="http://twitter.com/xmpp">xmpp</a>: @<a href="http://twitter.com/eishn">eishn</a>: &#8220;对于任务的处理, 不可避免会涉及到 multithreading 的问题&#8221; 是 @yingfeng 提到的，在我的理解，“任务”是指为了返回请求，需要消耗cpu及io等待,直至输出内容返回网络这个执行过程</p>
<p><a href="http://twitter.com/yingfeng">yingfeng</a>: @xmpp 读过POSA II便可知道event based只是解决了acceptor端的问题，对于任务的处理，不可避免会涉及到multithreading的问题</p>
<p><a href="http://twitter.com/xmpp">xmpp</a>: @<a href="http://twitter.com/SnaiX">SnaiX</a>: 批评多线程者无非就是批评锁，所以1最极端者就用单线程，2退一步者就线程不共享内存，线程间用消息通讯，3普通多线程通常加锁，因此会带来等待锁(其实Semaphore锁对等待线程没什么开销的)及线程切换开销，因此开发多线程程序只要了解底层原理就没什么恐惧的</p>
<p><a href="http://twitter.com/xmpp">xmpp</a>: @<a href="http://twitter.com/eishn">eishn</a> 你说的是实现方法是协程吗，我倒很想看到你说的实现方法详细描述。如果是协程，它虽然避免了锁，但还是存在切换开销，而且也不能随时切换，我觉得如要利用多核优势，多线程是大势所趋</p>
<p><a href="http://twitter.com/alpha86">alpha86</a>: @xmpp 静态文件的请求可以开keep-alive, 动态请求的话其实keep-alive起不到多大效果。</p>
<p><a href="http://twitter.com/Joshfeng">Joshfeng</a>: @xmpp 我个人觉得keep-alive的设置要看服务器上主要是什么类型的文件</p>
<p><a href="http://twitter.com/xiaoxiaolu">xiaoxiaolu</a>: RT @xmpp: &#8230; 他的调优建议把keep-alive设成=0(相当于关掉)，个人不是很认同//就web而言,我挺认同的</p>
<p><a href="http://twitter.com/mikespook">mikespook</a>: RT: @<a href="http://twitter.com/xiaoxiaolu">xiaoxiaolu</a>: RT @xmpp: 刚看到&#8230;.调优建议把keep-alive设成=0(相当于关掉)，个人不是很认同//就web而言,我挺认同的// 具体情况具体处理，keep-alive 对小文件友好，对高并发不利～</p>
<p><a href="http://twitter.com/rockyzh">rockyzh</a>: @xmpp 同意，现在已经进入多核时代了，当年的squid以高效的单线程著称，现在可得改改了</p>
<p><a href="http://twitter.com/TerryTsui">TerryTsui</a>: RT: @xmpp: 阙宏宇最后说web server使用多线程是倒退，并拿memcached单线程跑得很好来证明。。。 //memcache 也可以是多线程跑啊</p>
<p><a href="http://twitter.com/xiaoxiaolu">xiaoxiaolu</a>: RT @mikespook: RT: @xiaoxiaolu: RT @xmpp:调优建议把keep-alive设成=0，个人不是很认同//我挺认同// 具体情况具体处理，keep-alive 对小文件友好，对高并发不利～//高并发看情况,若跳出率很高,就关掉,省事的话,一律关掉</p>
<p><a href="http://twitter.com/SnaiX">SnaiX</a>: @xmpp 在他视频20分钟左右的位置，提到squid和lighty的比较。提到“能不用线程就不用线程，尤其是几个线程在做同一个事情，用这种事件驱动的模型更好“，我不赞同，这种并发的目的就是用来做同一个事情的。其次就是线程模型和事件驱动一点也不冲突。</p>
<p><a href="http://twitter.com/SnaiX">SnaiX</a>: @xmpp memcached的模型明显是比较简单的模型，为了实现方便而已。所以mc这种东西如果你不适用线程模式或者不对其进行一些特殊优化， 是很难用来吞吐大数据的，因为单线程会使得在write较多数据的时候占用的CPU时间太长，从而直接影响了对别的请求的响应。</p>
<p><a href="http://twitter.com/tangfl">tangfl</a>: @SnaiX @xmpp snaix 应该大力推销一下 csf 模式：前端 event driven，中间任务队列调度，后面线程池处理，完美了。。。</p>
<p><a href="http://twitter.com/eishn">eishn</a>: @xmpp 阙宏宇说webserv使用多线程是倒退，基本赞同。不过其mcachd例子不妥，常规evt负载亦不低。然单线程异步io性能甚于多线程，高并发场合由 是，故多线程非最佳。然实现逻辑，多线程是最易用的，故最佳形式是以模拟多线程写逻辑，而以单线程异步实现，这也是我的做法。</p>
<p><a href="http://twitter.com/jiaojing">jiaojing</a>: RT: @jeffz_cn: rt @xmpp RT: @yingfeng: @xmpp 读过POSA II便可知道event based只是解决了acceptor端的问题，对于任务的处理，&#8230;//多线程也只是用来做cpu时间片的分配,协程也是一个不错的选择.切换代价更 小</p>
<p><a href="http://twitter.com/SnaiX">SnaiX</a>: @xmpp 我认为，如果仅仅是为了避免多线程所造成的程序复杂度上升而在该使用多线程的地方却不使用多线程，是一种无能的表现。譬如说，有言论说：多线程造成你的程序一旦有问题，整个进程就core dump了，所以不稳定。可关键是，你的程序应该有问题么？</p>
<p><a href="http://twitter.com/SnaiX">SnaiX</a>: RT @<a href="http://twitter.com/tangfl">tangfl</a>: @SnaiX @xmpp 其实CSF也没什么可高深的，只是我觉得需要有这么一个东西，这样很多东西就可控了。做技术的，不能整天靠凑合来凑合去的过日子。</p>
<p><a href="http://twitter.com/eishn">eishn</a>: @xmpp stackless python 协程可以做到随时切换, 不过不能达到 erlang 那样的协程级别的多核分配, 尽管可以由用户自己非原生实现。协程虽然还是有切换开销, 但是没有无谓切换, 只在类似 io 等待的场合下才会发生切换, 所以切换次数远小于线程。</p>
<p><a href="http://twitter.com/jiaojing">jiaojing</a>: RT: @eishn: @xmpp stackless python 协程可以做到随时切换, 不过不能达到 erlang 那样的协程级别的多核分配, &#8230;。// erlang的smp也是用多线程(一个核一个线程,ps保证)跑多个scheduler.</p>
<p><a href="http://twitter.com/flierlu">flierlu</a>: 多线程领域也是在不停发展的，近几年 lock-free 和 wait-free 算法逐渐成熟，加上线程局部内存池等等技术，只要设计上不出大问题，肯定能超越多进程</p>
<p><a href="http://twitter.com/zhuzhaoyuan">zhuzhaoyuan</a>: @xmpp: @yingfeng: 读过POSA II便可知道event based只是解决了acceptor端的问题，对于任务的处理，不可避免会涉及到multithreading的问题 || 反对，要看服务类型是IO密集型还是计算密集型的，IO密集型的不需要多线程。</p>
<p><strong>附加说明</strong></p>
<ul>
<li>在Twitter中，@表示reply某人, 类似email中的答复，RT表示retweet,类似email中的转发。</li>
<li>从上面看到，Twitter在讨论上处理线索功能上还是比较弱，需要重复RT原文来串联上下文，很需要类似gmail那样conversation的功能。</li>
<li>我的twitter ID是<a href="http://twitter.com/xmpp">xmpp</a>，欢迎大家follow。</li>
</ul>
Similar Posts:<ul><li><a href="http://timyang.net/lua/lua-coroutine-vs-java-wait-notify/" rel="bookmark" title="April 27, 2009">Lua coroutine vs Java wait/notify</a></li>

<li><a href="http://timyang.net/python/python-webpy-lighttpd/" rel="bookmark" title="February 26, 2009">python web.py使用flup lighttpd优化过程</a></li>

<li><a href="http://timyang.net/architecture/sohu-im/" rel="bookmark" title="May 19, 2009">搜狐IM</a></li>

<li><a href="http://timyang.net/linux/linux-process/" rel="bookmark" title="May 3, 2009">了解Linux的进程与线程</a></li>

<li><a href="http://timyang.net/data/memcached-lru-evictions/" rel="bookmark" title="September 7, 2009">Memcached数据被踢(evictions>0)现象分析</a></li>
</ul><!-- Similar Posts took 15.421 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/programming/lighttpd-mod_cache-twitter/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
