<?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>kafka0102的边城客栈 &#187; 架构</title>
	<atom:link href="http://www.kafka0102.com/tag/%e6%9e%b6%e6%9e%84/feed" rel="self" type="application/rss+xml" />
	<link>http://www.kafka0102.com</link>
	<description>要有最朴素的生活与最遥远的梦想，即使明日天寒地冻、路远马亡。</description>
	<lastBuildDate>Sat, 18 Jun 2011 04:20:42 +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>分享：Scalable System Design Patterns</title>
		<link>http://www.kafka0102.com/2010/10/350.html</link>
		<comments>http://www.kafka0102.com/2010/10/350.html#comments</comments>
		<pubDate>Sun, 17 Oct 2010 13:11:27 +0000</pubDate>
		<dc:creator>kafka0102</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[架构]]></category>
		<category><![CDATA[模式]]></category>

		<guid isPermaLink="false">http://www.kafka0102.com/?p=350</guid>
		<description><![CDATA[Scalable System Design Patterns 一文概括了几种常见的系统设计模式。配图很漂亮，我就索性摘过来，推荐感兴趣的继续围观其博客。]]></description>
			<content:encoded><![CDATA[<p><a href="http://horicky.blogspot.com/2010/10/scalable-system-design-patterns.html" target="_blank"> Scalable System Design Patterns </a>一文概括了几种常见的系统设计模式。配图很漂亮，我就索性摘过来，推荐感兴趣的继续围观其博客。</p>
<h2>1、Load Balancer</h2>
<p>该模式中，一个分发器基于某种策略确定由哪个worker实例处理请求。应用最好是无状态的，以使任何一个worker实例都能同等处理请求。大量的网站都会用到负载均衡器这个模式的。</p>
<p style="text-align: left;"><a href="http://www.kafka0102.com/wp-content/uploads/2010/10/p1.png"><img class="aligncenter size-full wp-image-351" title="p1" src="http://www.kafka0102.com/wp-content/uploads/2010/10/p1.png" alt="" width="611" height="409" /></a></p>
<h2>2、Scatter and Gather</h2>
<p>该模式中，分发器将请求转发给多个worker实例，每个worker实例处理完返回给分发器，分发器将worker们返回的结果再加工后再返回给客户端。以搜索为例，通常得AS、BS架构就是这种典型模式。</p>
<p style="text-align: left;"><a href="http://www.kafka0102.com/wp-content/uploads/2010/10/P2.png"><img class="alignleft size-full wp-image-353" title="P2" src="http://www.kafka0102.com/wp-content/uploads/2010/10/P2.png" alt="" width="619" height="358" /></a></p>
<h2>3、Result Cache</h2>
<p>承接上个模式，这个模式只是在分发器处理时加了一步查询结果缓存，这都能算是模式！</p>
<p style="text-align: left;"><a href="http://www.kafka0102.com/wp-content/uploads/2010/10/P3.png"><img class="alignleft size-full wp-image-354" title="P3" src="http://www.kafka0102.com/wp-content/uploads/2010/10/P3.png" alt="" width="619" height="358" /></a></p>
<h2>4、Shared Space</h2>
<p>这个模式还有个更广泛的名字&#8211;“黑板模式”。实现来说，就是在处理流程中，存在一个全局传递的对象，它可能包含了请求参数、中间状态、响应结果等各种信息，供流程中的各个组件对其进行操作。在一些web框架和应用框架中，都可见这个模式的使用。</p>
<p style="text-align: left;"><a href="http://www.kafka0102.com/wp-content/uploads/2010/10/P4.png"><img class="alignleft size-full wp-image-355" title="P4" src="http://www.kafka0102.com/wp-content/uploads/2010/10/P4.png" alt="" width="611" height="409"/></a></p>
<h2>5、Pipe and Filter</h2>
<p>这个模式又以“面向数据流编程”知名，是很通用的企业集成模式。</p>
<p style="text-align: left;"><a href="http://www.kafka0102.com/wp-content/uploads/2010/10/P5.png"><img class="alignleft size-full wp-image-356" title="P5" src="http://www.kafka0102.com/wp-content/uploads/2010/10/P5.png" alt="" width="611" height="409"/></a>
</p>
<h2>6、Map Reduce</h2>
<p>因为google和hadoop，这个模式几乎都了解些，尽管多数人都没亲身应用过。</p>
<p style="text-align: left;"><a href="http://www.kafka0102.com/wp-content/uploads/2010/10/P7.png"><img class="alignleft size-full wp-image-357" title="P7" src="http://www.kafka0102.com/wp-content/uploads/2010/10/P7.png" alt="" width="611" height="409"/></a>
</p>
<h2>7、Bulk Synchronous Parellel</h2>
<p>该模型基于一个master协调，所有的worker同步（lock-step）执行。<br />
该模式被用于Google Pregel Graph Processing  <a href="http://horicky.blogspot.com/2010/07/google-pregel-graph-processing.html">google-pregel-graph-processing</a> 和<a href="http://incubator.apache.org/hama/">Hama</a>。</p>
<p style="text-align: left;"><a href="http://www.kafka0102.com/wp-content/uploads/2010/10/P8.png"><img class="alignleft size-full wp-image-358" title="P8" src="http://www.kafka0102.com/wp-content/uploads/2010/10/P8.png" alt="" width="611" height="409"/></a></p>
<h2>8、Execution Orchestrator</h2>
<p>又一个不很了解的模式，似乎是一个和map reduce有一拼的分布式计算模型，似乎是微软的创造：<a href="http://research.microsoft.com/en-us/projects/dryad/ " target="_blank">Microsoft&#8217;s Dryad project</a>。</p>
<p style="text-align: left;"><a href="http://www.kafka0102.com/wp-content/uploads/2010/10/P82.png"><img class="alignleft size-full wp-image-359" title="P82" src="http://www.kafka0102.com/wp-content/uploads/2010/10/P82.png" alt="" width="611" height="409" /></a></p>
<p><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kafka0102.com/2010/10/350.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分享：Playfish&#8217;s Social Gaming Architecture</title>
		<link>http://www.kafka0102.com/2010/09/333.html</link>
		<comments>http://www.kafka0102.com/2010/09/333.html#comments</comments>
		<pubDate>Wed, 22 Sep 2010 15:21:09 +0000</pubDate>
		<dc:creator>kafka0102</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[架构]]></category>

		<guid isPermaLink="false">http://www.kafka0102.com/?p=333</guid>
		<description><![CDATA[highscalability.com上的Playfish's Social Gaming Architecture - 50 Million Monthly Users and Growing是篇很不错的大杂烩，内容涉及全球第二大social game公司Playfish的技术架构、产品设计、团队协作、产品运营等诸多经验之谈，尤其对初创团队很有借鉴意义。我这里还只是对文中提到的一些技术经验做些汇总，也推荐大家去浏览原文，重点看看自己感兴趣的段落。但说起架构的事情，其实看多了，往往都是大方向上相似，细节上有自己的考量和特点，以形成自己的架构风格。]]></description>
			<content:encoded><![CDATA[<p>highscalability.com上的<a href="http://highscalability.com/blog/2010/9/21/playfishs-social-gaming-architecture-50-million-monthly-user.html" target="_blank">Playfish&#8217;s Social Gaming Architecture &#8211; 50 Million Monthly Users and Growing</a>是篇很不错的大杂烩，内容涉及全球第二大social game公司Playfish的技术架构、产品设计、团队协作、产品运营等诸多经验之谈，尤其对初创团队很有借鉴意义。我这里还只是对文中提到的一些技术经验做些汇总，也推荐大家去浏览原文，重点看看自己感兴趣的段落。但说起架构的事情，其实看多了，往往都是大方向上相似，细节上有自己的考量和特点，以形成自己的架构风格。</p>
<h2>SOA</h2>
<p>SOA在企业应用中热火朝天，但在互联网应用中SOA被提及的很少。Playfish的SOA并不是使用SOA工业中的技术栈，其思想就是组件化设计。当系统变得复杂以后，松耦合的组件化是必然的趋势，系统内组件间通过约定的接口交互。对于复杂系统来说，组件间的低依赖性是很重要的，当一个组件不能正常提供服务，系统应该是优雅的降级，而不是雪崩般的集体挂掉。说起来简单，但相信很多平时跑的很健康的系统，往往只是在一个组件坏掉后，才发现系统原来并不是看起来的那样可靠。</p>
<h2>The Cloud</h2>
<p>从一开始，Playfish就使用Amazon的基础云服务，国外的很多初创公司都是这样做的。关于使用基础云服务的诸多优点，其实很多文章都有提到，对初创产品来说，对硬件资源的需求变动性很大，像social game，高峰期和平时对硬件的需求可能相差很大，如果自己搭建硬件资源，会有很大的资源浪费，而使用具有可扩展性的云服务无疑更会经济。更重要的是，不用操心于硬件资源管理，团队会更加专注于核心的服务。不过，国内使用基础云服务的似乎不多，《程序员》杂志以前倒是有过一篇介绍国内social game公司使用基础云的文章，但国人还是喜欢什么东西都自己掌控的好，所以能自己折腾就绝不麻烦别人。当然，Playfish并没有使用Amazon的所有云服务，比如Amazon的ELB（Elastic Load Balancing）和RDB（Rational Database），因为将他们的应用迁移过来无疑会很麻烦甚至危险。</p>
<h2>Java</h2>
<p>Playfish主要是基于Java平台的，也是得益于Java的诸多优点，比如甚是丰富的开源库，既可以用于开发Web程序也可以用于开发服务器端程序。当然，Playfish也需要花些精力对JVM做性能调优。而在数据处理分析方面，Hadoop那一套东西是必不可少的。文中提到，Playfish使用Jetty作为应用Server，窃以为可能是做嵌入式使用，如果是独立server，tomcat和resin应该是更好的选择。</p>
<h2>Database System</h2>
<p>数据库方面，Playfish使用的是mysql，从早期的master-slave发展到现在的shard。social game的特点是写多读少，所以传统的主从模式就不合适了。在shard方式，Playfish应该是基于用户id散的，所以可扩展性很强。在schema方面，Playfish将mysql kv化了，为了加快访问速度，将和用户相关的诸多信息塞到blob类型中，这样DB的写压力被分散到后端应用上，而应用又是能很好的扩展的。所以，Playfish对mysql的使用也是nosql化了，但Playfish没有直接使用现成的nosql产品，而是使用更成熟的mysql搭建适合自己的nosql存储方式。在读多写少应用中，像memcached这样的缓存系统是必不可少的，而对写多读少的场景，Playfish有效的利用了flash客户端，使得客户端就像个memcached，写操作时即时更新客户端而不需要从服务器端再次读，而服务器端可以使用消息队列来异步写。</p>
<h2>YAMI4 &#8211; Messaging</h2>
<p>YAMI4是个什么东西？YAMI4是<a href="http://www.inspirel.com/yami4/" target="_blank">http://www.inspirel.com/yami4/</a>，一个很轻量级的消息框架，google的结果很少，用的人似乎也不多。Playfish说是在做了很多的评估后采用了YAMI4。我粗略的浏览了YAMI4的文档，发现这个东西还是很有特点的。YAMI4支持如C++、Java、Python等多种语言，它不是一个独立的消息系统，而是一个嵌入式的消息框架（库）。消息传递有两种模式：1）是点对点的同步模式，可以使用如Thrift等RPC框架进行消息传递，但不适用于Playfish。2）是基于消息的异步模式，通常是使用如ActiveMQ等独立的消息系统（broker），但它会成为单点（当然可以花成本来去单点），并且消息的传递还要经过broker这一跳。而YAMI4是个可以嵌入producer的broker，这样消息可以点对点的传递给consumer，没有了broker的单点的困扰，并且调用可以是异步的。而对消息的数据格式，YAMI4像IDL一样提供了较友好的支持。</p>
<h2>总结</h2>
<p>写的匆忙，止笔于此，回头把YAMI4研究下。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kafka0102.com/2010/09/333.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分享“Top 10 Performance Problems taken from Zappos, Monster, Thomson and Co”</title>
		<link>http://www.kafka0102.com/2010/07/234.html</link>
		<comments>http://www.kafka0102.com/2010/07/234.html#comments</comments>
		<pubDate>Mon, 12 Jul 2010 13:36:23 +0000</pubDate>
		<dc:creator>kafka0102</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[分享]]></category>
		<category><![CDATA[架构]]></category>
		<category><![CDATA[经验]]></category>

		<guid isPermaLink="false">http://www.kafka0102.com/?p=234</guid>
		<description><![CDATA[Top 10 Performance Problems taken from Zappos, Monster, Thomson and Co 一文总结了一些关于性能问题方面的经验，虽然不是很“新奇”，但也算是中规中矩的有借鉴意义，这里分享之。没有对原文做完全的翻译，也欢迎大家直接看看原文，本文转过来还夹杂了一些个人理解，有理解不当的地方也望指正。]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.dynatrace.com/2010/06/15/top-10-performance-problems-taken-from-zappos-monster-and-co/" target="_blank">Top 10 Performance Problems taken from Zappos, Monster, Thomson and Co</a> 一文总结了一些关于性能问题方面的经验，虽然不是很“新奇”，但也算是中规中矩的有借鉴意义，这里分享之。没有对原文做完全的翻译，也欢迎大家直接看看原文，本文转过来还夹杂了一些个人理解，有理解不当的地方也望指正。</p>
<h3>1、Too Many Database Calls</h3>
<p>这一问题是说在一次请求/事务处理过程中有太多次的数据库调用。典型的情景是：<br />
1）请求了不必要的数据，比如程序员们为图省事而”select * ”出不必要的字段数据。<br />
2）相同的数据被请求多次。这通常出现在同一事务中，彼此独立的组件需要请求相同的数据，而在不同的上下文下，程序员又没有检查出重复的执行情况。<br />
3）为了获取特定的数据而使用了多次查询，这通常是没有有效的使用复杂的SQL或存储过程造成的（但话说两端，在一些反schema的表结构中，将复杂逻辑拆分成多条SQL是自然的）。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2009/04/30/linq2sql-prevent-performance-issues-when-operating-on-multiple-rows-with-stored-procedures" target="_blank">Blog on Linq2Sql Performance Issues on Database</a>,  <a href="http://blog.dynatrace.com/2009/10/16/video-on-common-performance-antipatterns-online/" target="_blank">Video on Performance Anti-Patterns</a></p>
<h3>2、Synchronized to Death</h3>
<p>在应用中使用同步来保护共享数据是无可厚非的。不过，程序员们在使用同步时，往往没有经过深思熟虑而不恰当地增大了同步代码段的范围。因为同步引起的性能问题一般在低负载的测试环境中没有体现，但在高负载的生产环境就表现出性能及可扩展性问题。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2009/04/02/performance-analysis-how-to-identify-synchronization-issues-under-load/" target="_blank">How to identify synchronization problems under load</a></p>
<h3>3、Too chatty on the remoting channels</h3>
<p>就开发来说，使用封装的API来处理远程调用就像处理本地调用一样简单。不过，它显然会比本地调用带来更多的问题，比如延迟性、数据的序列化、网络流量、内存使用等等。当应用的远程调用层次过多，这些开销就需要考虑。这让我想起EJB2盛行的时候，即便是很普通的web应用也要整没用的分布式，活活把性能降低好几个级别。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2009/09/28/performance-considerations-in-distributed-applications/" target="_blank">Performance Considerations in Distributed Applications</a></p>
<h3>4、Wrong usage of O/R-Mappers</h3>
<p>ORM很好，能简化程序员的开发负担，不过它的复杂性会带来一些性能问题。像Hibernate等框架，通过优化配置及使用一些高级的trick，可以避免性能陷阱，不过这就对使用者有很高的技能要求。否则，对于有性能要求的应用，还是对ORM的使用谨慎些。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2009/02/16/understanding-caching-in-hibernate-part-one-the-session-cache/" target="_blank">Understanding Hibernate Session Cache</a>, <a href="http://blog.dynatrace.com/2009/02/16/understanding-caching-in-hibernate-part-two-the-query-cache/" target="_blank">Understanding the Query Cache</a>, <a href="http://blog.dynatrace.com/2009/03/24/understanding-caching-in-hibernate-part-three-the-second-level-cache/" target="_blank">Understanding the Second Level Cache</a></p>
<h3>5、Memory Leaks</h3>
<p>尽管像Java和.NET平台有垃圾回收器来管理内存，使程序员摆脱了C/C++中的内存泄漏噩梦。不过内存泄漏仍是可能的，如果应用抛出了OutOfMemoryException，那就需要好好看看哪些不需要的引用没有被释放掉。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2010/03/03/week-5-hunting-lost-treasures-understanding-and-finding-memory-leaks/" target="_blank">Understanding and finding Memory Leaks</a></p>
<h3>6、Problematic 3rd Party Code/Components</h3>
<p>在应用中使用第三方软件是很正常的，尤其是对于热衷于使用开源软件的Java社区。在选择第三方软件时，要谨慎的选择成熟稳定并经过细致调研的软件，而很多使用第三方软件引发的问题往往是使用者没有正确使用造成的。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2010/03/18/how-to-avoid-the-top-5-sharepoint-performance-mistakes/" target="_blank">Top SharePoint Performance Mistakes</a></p>
<h3>7、Wasteful handling of scarce resources</h3>
<p>对于像内存、CPU、IO、文件句柄等资源，不正确地或浪费性的使用它们会导致性能及可扩展性问题。这方面的例子太多了，比如使用内存池、线程池、连接池等都是为了高效的使用这些资源。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2009/02/25/resource-leak-detection-in-net-applications/" target="_blank">Resource Leak detection in .NET Applications</a></p>
<h3>8、Bloated web frontends</h3>
<p>当应用出现性能问题时，我们往往将注意力集中在后端存储访问方面，而忽视对前端的优化。现在对前端的优化有很多现成的经验，并且可以高快好省地提高效果，比如雅虎的优化原则、《高性能网站建设进阶指南》等优秀图书，都是前端开发人员需要掌握和应用的。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2010/04/21/how-better-caching-helps-frankfurts-airport-website-to-handle-additional-load-caused-by-the-volcano/" target="_blank">How Better Caching would help speed up Frankfurt  Airport Web Site</a></p>
<h3>9、Wrong Cache Strategy leads to excessive Garbage Collection</h3>
<p>对于解决存储访问的性能问题，很多时候都是在DB前架上Cache。不过，不恰当的Cache策略可能并不会带来明显的效果，所以需要对Cache策略及效果做好评估和验证。如果是在Java程序中使用Cache，就更要注意GC问题。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2009/08/13/java-memory-problems/" target="_blank">Java Memory Problems</a>, <a href="http://blog.dynatrace.com/2009/04/08/performance-analysis-identify-gc-bottlenecks-in-distributed-heterogeneous-environments/" target="_blank">Identify GC Bottlenecks in Distributed Applications</a></p>
<h3>10、Intermittent Problems</h3>
<p>断断续续的问题。想让程序没有bug是很困难的，即便是很小的二分查找程序，也会在某个边界条件下出现异常。我们总能在生产环境中隔三差五的发现程序的问题，有的甚至初看起来是诡异的。要保证程序质量，就需要在单元测试、功能测试、覆盖率测试、性能测试等环节上做足功夫，尽早发现问题，尽管这样也不能保证程序在生产环境就没有诡异的问题。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2009/12/02/tracing-intermittent-errors-guest-blog-by-lucy-monahan-from-novell/" target="_blank">Tracing Intermittent Errors by Lucy Monahan from Novell</a>,  <a href="http://blog.dynatrace.com/2009/01/07/how-to-find-invisible-performance-problems/" target="_blank">How to find invisible performance problems</a></p>
<h3>11、(Bonus Problem) Expensive Serialization</h3>
<p>题目说好是10个问题的，不过作者又买10赠1,搭了个零头。前面有提到远程调用是昂贵的，这里着重说的是传输数据的序列化和反序列化开销。一些复杂或者低效的传输协议和数据包格式（比如SOAP协议、XML格式等），可能就会产生严重的性能问题。<br />
进一步阅读：<a href="http://blog.dynatrace.com/2009/09/28/performance-considerations-in-distributed-applications/" target="_blank">Performance Considerations in Distributed Applications</a></p>
<p>最后，很推荐有兴趣的点击各条中的“进一步阅读”的相关链接，有的还不错。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kafka0102.com/2010/07/234.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分享Sify.com的架构经验</title>
		<link>http://www.kafka0102.com/2010/05/144.html</link>
		<comments>http://www.kafka0102.com/2010/05/144.html#comments</comments>
		<pubDate>Sat, 15 May 2010 17:27:11 +0000</pubDate>
		<dc:creator>kafka0102</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[Sify.com]]></category>
		<category><![CDATA[solr]]></category>
		<category><![CDATA[架构]]></category>

		<guid isPermaLink="false">http://www.kafka0102.com/?p=144</guid>
		<description><![CDATA[今天分享的网站架构来自于Sify.com Architecture - A Portal at 3900 Requests Per Second（该标题有标题党嫌疑），对英文熟稔并不屑于我的中文简述的可以跳过该文。Sify.com是印度的一家portal网站，应该是信息集成类网站。它给出的月 pv是1.5亿次，每秒请求数是3900次（应该是针对所有服务的页面请求，包括异步的，并且是高峰的，否则就和pv对不上了）。按规模来说，算是个中等规模的网站，不过它的架构却是很值得说道的。]]></description>
			<content:encoded><![CDATA[<p>今天分享的网站架构来自于<a href="http://highscalability.com/blog/2010/5/10/sifycom-architecture-a-portal-at-3900-requests-per-second.html " target="_blank">Sify.com Architecture - A Portal at 3900 Requests Per Second</a>（该标题有标题党嫌疑），对英文熟稔并不屑于我的中文简述的可以跳过该文。Sify.com是印度的一家portal网站，应该是信息集成类网站。它给出的月pv是1.5亿次，每秒请求数是3900次（应该是针对所有服务的页面请求，包括异步的，并且是高峰的，否则就和pv对不上了）。按规模来说，算是个中等规模的网站，不过它的架构却是很值得说道的。</p>
<h2>网站架构</h2>
<p>1、为了节约机器资源并最大化利用机器资源，Sify.com也广泛采用了虚拟机。对于同一服务，Sify.com将其部署在多台机器上，使一台机器挂掉后仍有其他机器提供服务。对于冗余和负载均衡，目前Sify.com是将其做成配置手工修改，将来可能会自动化管理和扩展。对于运维来说，别说中小网站，就是一些大网站也没有做到自动化运维，很多还是收到报警后人肉解决。尽管自动化运维很酷，但从成本角度来说，大多中小网站不必追求这点，把监控做好，能在最快时间发现问题并解决问题就够了。</p>
<p>2、Sify.com的存储很特别，它没有使用通用的数据库，它的关系数据存在检索系统中，全文数据存在分布式文件系统中。这种围绕检索系统+kv文件系统的解决方案，我以前也读到过一篇文章。Sify.com的检索系统基于Solr，我最近也在看Solr，打算重做的检索系统也是基于Solr。Sify.com的查询会从检索系统检索出id，如果需要全文，再从文件系统（它用的是GFS，该GFS不是google的，而是一个开源的集群文件系统，我也不是很了解的说，感兴趣的可以访问http://sourceware.org/cluster/gfs/参观）取出全文内容。这个策略也是通常的检索系统处理策略。</p>
<p>3、Sify.com的提交操作采用异步处理模式，就是提交到ActiveMQ/Camel，然后分发到相应的服务处理。其中的Camel是开源的ESB实现，我也不甚了解。Sify.com各服务间似乎都是走HTTP协议，很有爱的表现。</p>
<h2>展望未来</h2>
<p>Sify.com提了一些愿景，我就不一一罗列，其中最吸引我的是，它打算采用Drools这个规则引擎做Cache失效处理。它提到Cache来源是Akamai和Varnish，所以失效的应该是来自CDN和本地的页面内容Cache。因为同一个URL请求可能会引起多个Cache项失效，而这种前端页面Cache失效让业务逻辑代码处理也不够友好，有个统一处理的系统在管理和操作上就方便很多。它的做法是，对于引起Cache失效的URL，将URL等信息打到日志中去，由Drools根据配置的规则来执行Cache失效策略。感觉上来说，还是很有意思的做法。</p>
<h2>经验教训</h2>
<p>Sify.com总结的经验都是和使用的软件的缺陷相关的，总结如下：</p>
<p>1、首先是ActiveMQ，把Sify.com搞得很狼狈。我目前对ActiveMQ只有初步的了解，也没什么发言权。它提到ActiveMQ的问题有两个：1）ActiveMQ耗尽socket资源的问题，尽管ActiveMQ5.0声称解决了，但Sify.com还是没看到效果，使得ActiveMQ需要不断重启，最后折中解决了，部署两台ActiveMQ，轮流切换，这解决方案真是够山寨的。2）它使用Topic订阅发布机制时有4个消费者，结果经常ActiveMQ会hang住数个小时，折中的解决是使用4个Queue代替（够囧），但运行还是不稳定，时有抛出异常或内存溢出的情况。按说ActiveMQ也够成熟了，也不知是真有问题还是Sify.com自己没用好。公司也有使用ActiveMQ，也打算有时间会对ActiveMQ和JMS做些深入的研究。</p>
<p>2、Solr的问题有3个：1）Solr有时会对请求没有响应或超时，就需要重启解决问题，这个可能我需要关注下。2）Solr对复杂查询（比如加NOT查询）处理慢，这个应该是lucene的问题了，只能尽可能规避，把复杂查询拆成多个简单查询后再合并处理。3）对实时检索的需求，目前Solr没有提供该功能，Sify.com打算采用LinkedIn的Zoie（有Solr plugin），不过因为Sify.com索引数据的主键是字母+数字组合，而Zoie的是数字的，需要Sify.com做些扩展工作。我前段时间也有专门对Zoie做了一些分析。</p>
<p>3、GFS锁问题造成GFS不能访问，显然是个很严重的臭虫，升级版本解决问题。</p>
<p>4、Sify.com使用Lighty和PHP合作的不是很愉快，说是PHP_FCGI不稳定，会使进程hang住CPU飚满，这个我没什么经验，也不发言。</p>
<h2>总结</h2>
<p>夜已深，睡意浓，到此为止。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kafka0102.com/2010/05/144.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>分享Poppen.de架构经验</title>
		<link>http://www.kafka0102.com/2010/04/96.html</link>
		<comments>http://www.kafka0102.com/2010/04/96.html#comments</comments>
		<pubDate>Sun, 25 Apr 2010 07:49:17 +0000</pubDate>
		<dc:creator>kafka0102</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php-fpm]]></category>
		<category><![CDATA[Poppen.de]]></category>
		<category><![CDATA[RabbitMQ]]></category>
		<category><![CDATA[架构]]></category>

		<guid isPermaLink="false">http://www.kafka0102.com/?p=96</guid>
		<description><![CDATA[Poppen.de是德国的一家婚姻中介网站，对于该网站的统计数字有：1）2.000.000的用户数，2）20.000的并发用户数，3）每天产生300.000的私信，4）250.000的日登录用户数。这样的网站也就是个中型规模的网站，下面看看这个网站在技术应用及经验方面带来的东西。]]></description>
			<content:encoded><![CDATA[<p>Poppen.de是德国的一家婚姻中介网站，对于该网站的统计数字有：1）2.000.000的用户数，2）20.000的并发用户数，3）每天产生300.000的私信，4）250.000的日登录用户数。这样的网站也就是个中型规模的网站，下面看看这个网站在技术应用及经验方面带来的东西。</p>
<p>原文链接：<a href="http://highscalability.com/blog/2010/4/12/poppende-architecture.html" target="_blank">http://highscalability.com/blog/2010/4/12/poppende-architecture.html</a></p>
<h2>Nginx</h2>
<p>Poppen.de使用nginx作为web server，包括静态请求和动态请求。特别的，Poppen.de通过nginx来直接从memcache中获取缓存的动态页面内容而不需要经过PHP，一个例子就是请求用户信息页。对于缓存整个动态请求页面内容，这是一种方法，更常见的是使用squid、varnish来做。在请求用户上传图片的处理方面，Poppen.de是将图片上传到统一的文件服务器，而前端的nginx在请求时会做本机的cache处理（不知道它的请求是如何落到nginx上的，如果是随机的，多台nginx本机cache的数据就重复了，有些浪费，但也最简单），对于图片量不大的情况倒是简单的处理方法。</p>
<h2>PHP-FPM</h2>
<p>Poppen.de使用了PHP 5.3.x、APC和PHP-FPM，PHP-FPM是启用了100个进程，也是个标配。使用APC使得PHP能减少30%的CPU和内存消耗。Poppen.de竟然使用了symfony作为开发框架，出发点自然是希望快速开发，但从我的使用经验来说，symfony还是太重的一个框架，无论是使用上还是性能上都不是最优的PHP框架。当然，它也提到，框架是有性能损失的，但还可以接受。就PHP框架来说，尽管开源的框架一筐一筐，但没一个真正流行的，而重复的轮子却不停的出现，此种现象很耐人寻味。Poppen.de还使用了Facebook出品的XHProf来分析PHP程序的性能问题。</p>
<h2>Mysql</h2>
<p>Poppen.de的数据存在Mysql中，主要就是主从模式。由于现在的数据量并不大，并没有做数据分区处理，当数据量上来时，像垂直和水平分区自然是扩展性能的简单方式。稍显意外的是，Poppen.de使用由4台机器构成的NDB cluster来存储写频繁的数据，比如某个用户页都被谁访问过这样的统计信息。如果NDB cluster能被一些大型应用证明其稳定性，对于解决写频繁的应用（比如Social game？）来说是个不错的选择。Poppen.de的表大多是MyISAM，自然不是很好的选择，不过他们竟然有计划转向XtraDB（自然是经过测试比较后的结果），真是够有个性的。尽管XtraDB很优秀，但官方的innodb显然会更成熟，并且新版也在吸收如XtraDB等存储引擎的优点，选择一个不明前途的第三方引擎还是有些风险的。</p>
<h2>Memcached</h2>
<p>cache为王，Poppen.de有45GB、51个结点的cache数据。并且还做了一个系统，当一个表数据变化时，自动作废cache数据，好处自然是减少了应用处理。当然，也可以做一个穿透的数据访问中间件来做cache填充与失效的事情（就像DAL）。Poppen.de似乎也在考虑使用Redis或MongoDB等来将cache操作和数据操作自然的绑在一起。</p>
<h2>RabbitMQ</h2>
<p>Poppen.de使用了RabbitMQ来做一些异步job处理。特别有趣的是，它使用了PHP-FPM的一个专有特性，即fastcgi_finish_request() 函数，能够在请求结束前，在把结果返回到客户端后，异步的做诸如连接关闭、发送消息的处理。在消费消息方面，Poppen.de使用了最简单的山寨方法，就是同时运行多个PHP脚本，每个脚本在消费250个job后退出，然后由监控脚本再新起一个消费脚本。当处理不过来时，或者多加脚本或者多加机器来解决。</p>
<h2>其他</h2>
<p>Poppen.de使用CouchDB来存储log而是代替人工直接分析日志文件，这个对于单机的日志分析或许会更快更方便些，并且他们有计划将日志可视化，但他们想必现在还没打算做分布式的日志存储与分析的工作。Poppen.de使用了叫做Red5的东西来存储视频（我是不了解了）。Poppen.de还使用Graphite来做数据监控，包括如Memcached的命中率、RabbitMQ状态监控、各机器的负载监控等。当一个网站有一定规模后，这种监控是必不可少的，而通常也是拿现成的工具使用，在必要时做些功能上的扩展。Poppen.de还使用Tsung来做基准测试，比如HTTP请求及各Mysql存储引擎方面的测试。</p>
<h2>经验</h2>
<p>1、背靠大树好乘凉，选择技术和工具时要挑成熟、活跃的社区，这样有问题也有途径及时解决。<br />
2、了解你所使用的技术的优缺点，发挥它的优点，避开它的缺点。<br />
3、扩展工具，让工具更好的满足你。<br />
4、敢于尝试。可以看到，越是大公司，在技术选型时越是缩手缩脚，生怕外面的东西不成熟有问题，总相信自己能造成更好的自己能掌控的轮子。而看看Poppen.de上面提到的东西，有多少是你不知道没用过的？再感慨一下，每天都有大量的开源项目出现，一些因为被人关注而众人拾柴，东西就存活下去，一些尽管东西很好但因为无人问津，也就悄无声息的死去。<br />
5、度量一切，对网站的各个模块、系统、流量等数字有清晰的认识。<br />
6、经验积累、全面把握。不要等到上线时发现新模块的功能不是需要的，不要等到上线时发现模块性能不满足需求。</p>
<h2>总结</h2>
<p>Poppen.de还做了些展望，比如将更多的使用erlang产品，这要是个国内的公司，估计很多人会膜拜的。而总结来说，Poppen.de分享的东西真是很实在很实用，是个很开放也很技术流的公司，对中小规模的网站来说是可充分借鉴的。</p>
<p><a href="http://www.poppen.de/"> </a></p>
<p><a href="http://www.poppen.de/"> </a></p>
<p><a href="http://www.poppen.de/"> </a></p>
<p><a href="http://www.poppen.de/"> </a></p>
<p><a href="http://www.poppen.de/"> </a></p>
<p><span style="font-family: 'AR PL UMing CN', serif;"><a href="http://www.poppen.de/"> </a></span></p>
<p><span style="font-family: 'AR PL UMing CN', serif;"><a href="http://www.poppen.de/"> </a></span></p>
<p><span style="font-family: 'AR PL UMing CN', serif;"><a href="http://www.poppen.de/"> </a></span></p>
<p><span style="font-family: 'AR PL UMing CN', serif;"><a href="http://www.poppen.de/"> </a></span></p>
<p><span style="font-family: 'AR PL UMing CN', serif;"><a href="http://www.poppen.de/"> </a></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kafka0102.com/2010/04/96.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

