Thursday, February 12th, 2009
前言:
关于Digg的架构,之前Fenng已经写过一篇Digg 网站架构的文章,Fenng在文章开头说“越来越发现其实都是自我重复的劳动,后续的信息都是嚼别人剩下的甘蔗。”,其实是Fenng过谦了,我就是从DBA notes一点一滴开始学习的。
原文在Scaling Digg and Other Web Applications,Todd Hoff总能给我们带来一些有意思的文章。这里既不直译也不全译,保持原文骨干加上肤浅的理解。
Digg用户在3000W左右,网站每秒请求数达到13000个,规模算是很大了,Lamp(Linux+Apache+MySQL+PHP)结构,Web2.0网站中钟情PHP的不少,国外的Facebook、Digg、Flickr...,国内的新浪博客、开心网、51.com等等,扩展的不是编程语言而是网站架构,因为编程语言从来都不会是网站瓶颈,每种语言都有自己适合做和不适合做的事情。喜欢比较语言快慢的可以看看http://shootout.alioth.debian.org/,看看而已不要用速度去衡量编程语言的优劣。
Digg的扩展战略:
扩展是有特殊性的,当已有的方案不能满足需求时,你需要根据自己的特殊需求来建立方案。要熟悉自己的业务需求,找出系统的短板,解决问题,避免过度优化。
编程语言不需要扩展,因为语言从来都不是瓶颈,把PHP提速300%不会是什么大问题。
去中心化,分布式处理高并发请求。
水平扩展,用更多更便宜的机器代替更高效更昂贵的机器。
数据库驱动的网站需要作水平分区和垂直分区扩展,水平分区就是把数据放到不同的机器上,比如按照时间划分:2009年的数据一组服务器,2009年的数据一组服务器,或者按照用户ID划分:每200W用户一组服务器;垂直分区把一个表分成多个表,每个表只包含一部分字段,可以按照业务分或者常用的“动静分离”,比如对文章计数的字段大可以和文章内容字段分开。
建立数据应用层,程序不要直接操作数据库分区,这样可以保持好的扩展性。这一点非常重要,如果没有数据应用层API,一旦对数据库分区做了修改,你的程序就需要大改了。程序的稳定性和持续性就不能保证。比较常见的MVC开发模式,数据层和逻辑层分开,一旦数据库底层改变了,只需要对数据层做简单的修改,不影响既有业务。
一致性、高可用性、分区容忍性(Partition Tolerance)三者只能取其二,具体的阅读http://camelcase.blogspot.com/2007/08/cap-theorem.html,一致性:每个人看到的都一样,哪怕当时就有更新;高可用性:部分故障不影响使用;分区容忍性:数据分区还能保持系统所有属性。
数据分区要求反常规化,这是在Digg是大问题,同样的数据要复制到多个对象上去,而且还好保持同步。
采用异步的队列架构,把任务放到队列中交由多台机器处理,而不是一次同步处理,关于异步任务处理可以阅读 Flickr - Do the Essential Work Up-front and Queue the Rest和The Canonical Cloud Architecture
icons和图片采用MogileFS存储,MogileFS是一个分布式的文件系统,由memcached作者开发,国内的好看簿也有使用MogileFS。
采用APC作为PHP加速器,Facebook用的也是这个,PHP5.30以后将自带APC加速器,同样的产品还有eAccelerator和Xcache,国内可能用eAccelerator的比较多,windows的版本我一般用这个网站编译的
缓存策略:永久性缓存和失效期缓存;基本不更新的内容采用文件缓存;动态缓存采用memcached;极少修改的数据采用APC缓存,APC不是分布式缓存,直接缓存的机器内存中,所以速度更快,适合缓存那些配置文件,比如MySQL的配置信息;缓存采用链责任模式,首先看PHP全局变量,如果没有就查APC,再没有就查memcached,最后没有就查数据库,这个觉得不太必要,你的缓存存在哪来你自己还不清楚阿。
Digg的推荐引擎是一个自定义的图形数据库,数据库最终保证一致性,先写如一个分区,然后再逐步写到其他的分区。在更新的过程中,可能取出来的数据不一致,是因为有不同的数据库分区处理,最终将会是一致。
MemcacheDB:性能革命性的一步
想象一下Kevin Rose,Digg的创建者,当前有4000个追随者,如果Kevin Rose一天digg一次,将会有4000个写操作,最热门的digg有最多的追随者,这会导致巨大的性能瓶颈:
你不能同时更新4000个追随者的帐号信息,幸运的是我们可以通过前面提到的异步队列方式解决。
Digg面临的海量写操作,如果平均每个人有100个追随者,一天就有3亿条写操作,平均到每秒有3000个写操作,每天有5GB的数据存储,在50~60台服务器之间有5TB的数据交换。
如果是MySQL的话估计早就挂了,Digg在笔记本上的测试是memcachedb每秒可以处理15000个写操作,memcachedb的测试结果表明每秒可以支持23000个写操作或者64000个读操作,足以应付Digg洪水般的请求。
memcachedb是一个分布式的kye-value型数据持久化解决方案,提供兼容memcached协议接口,由Sina工程师Steve Chu开发。
提到Digg为什么采用memcachedb,Digg的工程师给出的理由是:需要持久化缓存数据,与memcached协议兼容,Digg已经有很多业务应用了memcached,可以很方便的切换到memcachedb上去,开源。
后记:
很高兴的看到除了Sina,memcachedb又有一个超重量级的应用了,性能和可靠性都得到了极大的检验,大可放心应用生产环境中。我还说今年有空写个玩具版的类memcachedb项目,还是不要了,有时间还是去做些更有意义的事情,无谓重复发明。
Posted in Arch, PHP | No Comments »
Saturday, January 10th, 2009
本博客所有原创文章采用知识共享署名-非商业性使用-相同方式共享,转载请保留链接http://chaoqun.17348.com/2009/01/cu-net-opt-salon/
特意把调休放在1.9,主要是想去听听CU组织的网络优化论坛,报名的时候有点意外,貌似丢失了报名信息,和组织者沟通了一下,感谢周平同学的热心帮助,说到的时候找他就可以,去的时候其实也没有查邀请函什么的,还给了件CU的T-Shirt,甚是感谢,一般这种开源技术研讨会都是很开放的。
首先是TOM网的曹刚带来的“浅析系统架构”,主要讲的是Myspace和SOHU社区架构的演变过程,基本的内容可以参考构建可扩展网络应用的七个步骤,一般他们的历程都是从第一步到第四步,大体上差不多,我这里列举这个关键词:
64位:Myspace为了让服务器管理更多的内容,操作系统由32位升级到64位,我们都知道32位的操作系统最多支持4G内存(当然有方法可以实现超过4G,不推荐。),64位操作系统理论上支持4G个G,估计我是看不到用完的那天,这里要注意的是32位操作系统下,一个处理器最多处理2G内存,所以如果是Memcached服务器,不要一个进程给超过2G内存,浪费。好的做法是多开几个服务,或者直接把Memcached服务器和APP服务器合二为一,很多公司都这样。
分表:论坛的特点是数据一般是按照板块分组,所以对于论坛这样的应用来说,最好是按照板块ID分表甚至分库分机器。
板块帖子列表页:论坛的特性是新帖子、新更新的帖子排在最前面,所以可能的情况是每次刷新的时候页面都在变,SOHU社区的做法是把板块新帖子保持在一个链表里面,链表的特点是插入和删除都很快,问题是查询的时候只能遍历。
其实对于一个论坛板块来说,热门的帖子不会太多,估计大家也就翻前几页,大可以把这个数据放进缓存中,比如维护一个队列,最新的500个帖子ID,帖子Title,新帖子放在最前面,自动顶掉最后一个,大可以用数组而不用链表,虽然插入的时候慢点,读取的时候却不用遍历链表。
对于跟帖数据,一般都是按照时间顺序排列,新增加的帖子自动在最后,压力不会很大。
google去搜一下Carp算法,一致性哈希算法consistent hashing(可以参考http://tech.idv2.com/2008/08/17/memcached-pdf/),Amazon S3 环形算法(是不是就是consistent hashing?不知)。
曹刚最后做了个总结,个人觉得:熟悉业务需求应该是核心。
第二位演讲者是来自占座网的吴炳锡,讲的是LVS和Nginx的负载均衡,这块以前只是从资料上看过,接触比较少,不过炳锡的介绍深入浅出,以前觉得LVS晦涩难懂,不敢动手,听完之后无知者无畏了,有机会试试看去。其实很多事情都这样,看上去挺难,做起来就容易了,下面是几个关键字:
DR模式:LVS有NAT、TUN、DR模式,推荐使用DR模式,更多的信息去google吧。
LVS->Nginx->Squid:组合的模式,LVS是四层的转发,Nginx是七层的转发,可以支持URL规则的转发,组合起来用就可以随心所欲了。
性能:Nginx的性能和LVS NAT模式相当,都是很好的解决方案,熟悉哪个就用哪个吧,性能都不是问题。
keepalived:LVS居家旅行、杀人灭口必配武器。
搜房网:搜房网前端采用LVS做负载均衡,中间用Nginx做URL负载均衡,动态的URL跳到App服务器,静态的URL跳转到Squid服务器。
第三位演讲者来自某个赞助商,感谢他们对活动的赞助,就不做广告了,一句话概括:适合钱多人傻。
第四位演讲者来自SOHU的MySQL DBA叶金荣,报告的内容网上大多有,这里也列出一些关键字:
发现问题:系统响应慢、load avg >=5、IO wait >= 10、swap使用情况、mysql status、mysql report、mysql 5.1 profline
xfs:如果可能,mysql数据文件系统分区采用xfs,效果高30%~50%
innodb_buffer_pool_size:如果是专用的数据库服务器,设定为内存的80%吧
MyIsam适合低并发、低更新、高读取的需求,InnoDB适合高并发、高更新、高读取的需求,MyIsam读取的速度比InnoDB快许多。
Explain:查询检查、查询优化
联合索引:貌似MySQL一次查询只用到一个索引,联合索引要注意先后顺序的问题,“左派”比较吃香。
字段按需配置,能用TinyINT的不用INT,字段越短越好,具体差别可以参见:http://chaoqun.17348.com/2008/11/mysql-data-types-int/
把大表拆成小表,如果表字段里面有Text,尽量拆开吧。
缩短事务周期
字符型的字段,最好采用前缀索引。
复杂的查询拆成小的简单的查询,比如用循环查询替代。这点不敢苟同,还是按照自己的业务测试一下吧。一条sql语句总比N条要快吧,除非有问题。
left join:把条目数少的放左边,如果你了解left join的话,这个是肯定的。
实时备份:用slave做实时备份吧,一个slave就是一个备份。
第五个演讲最为精彩,走了的人实在可惜,掌声和笑声不断,田逸这个家伙说话太有意思的,有机会要认识一下。讲的是CDN方面的事情,关键字:策略,技术很重要,策略更重要。
昨天的网络优化论坛受益匪浅,演讲者都有丰富的经验,其实网站架构就那么点事情,多分享才能共同进步,不过从互动环节可以看出国内做技术的对这方面关注还是比较少,有些问题比较原始,多关注一些就不会那样了。
PS:报告盖茨:我上周四叛逃到Linux了。
Posted in Arch, Open Source | 3 Comments »
Monday, October 20th, 2008
本博客所有原创文章采用知识共享署名-非商业性使用-相同方式共享,转载请保留链接http://chaoqun.17348.com/2008/10/qclub-ruby-on-rails/
周日(2008-10-19)下午,去听了听QClub组织的Ruby网站架构案例分享──财帮子&FreeWheel,本意是冲着架构案例分享去的,对Ruby On Rails知之甚少,很久以前和BLUG的一位外国朋友聊天,他说是做Ruby的,我说Ruby是日本人开发的语言,还没等我说完,这位外国的朋友说:It's just a language,nothin to do with Japanese,其实我的本意是这是日本人开发的语言,国际化方面可能会差一些,比如最原始的文档应该是日文的吧。看来我们总是被人误会啊。
首先是财帮子的Robin Lu(陆亦斌)给我们分享了一下他们的建站经历,先介绍一下财帮子的基本情况:
财帮子目前大概是100万PV/天,注册用户大概十几万
人均访问PV大概在15~20个左右
网站访问的峰值大约在基金净值出来之后,最高大概是430 Rec/Sec
最开始只有一台1U的服务器,应用和数据库都在上面,现在两台1U的服务器,应用服务一台,数据库一台
系统构建在Ruby On Rails上
使用lighttpd做负载均衡,30个左右mongrel实例
使用Munin和monit做服务器监控,跑了一些的cron任务(如数据备份)
他们遇到的第一个问题是前端负载均衡效率不高,最开始用apache的mod_proxy_balancer,发现有阻塞的情况存在,现在用的是lighttpd做负载均衡,他们觉得效果不错,据说还毙掉了nginx的方案,由于久做PHP,印象中前端负载均衡应该是把请求均衡到多台服务器上,初一听他们的负载均衡是把请求均衡到多个实例上,觉得甚是费解,一打听才知道mongrel一次大概只能处理一个请求,不太了解,不好评论。
他们的第二个问题是发现Ruby On Rails里面的数据库操作有大的瓶颈,大概是对数据库的操作始终在一个事务中,不到最后不commit,所以导致死锁的情况屡有发生。这让我想起Rasmus Lerdorf老大对PHP Framework的批判Simple is Hard(用IE会被鄙视的),Framework大大提高了开发的效率,却捆住了我们的双手。如果想要高的效率,那么就让ORM见鬼去吧。
他们还有一个好的建议是把动态内容和静态文件分开处理(当然这个建议已经被无数人说过了),这个确实非常有必要。
听完报告,问了下财帮子目前的瓶颈在什么地方,答曰:内存缺乏,跑了30个mongrel直接就吃掉了2G多的内存,确实够凶猛。这方面PHP算是不错了。
另外报告中还提到他们每天需要2~3小时去处理用户的账单,比如基金净值出来了,然后他们会计算每个用户的账单情况,这种做法不太看好,想想现在十几万用户可以算出来,将来多了呢?多台服务器并行计算?可计算成本呢?提前计算网站的活跃用户足够了,那些几百年才来一次的用户或者注册了再也不上的用户大可不必,等他们访问的时候再实时计算吧。
后面分享的FreeWheel讲的大多是项目开发方面的经验,我倒是觉得FreeWheel的做法不错,各种Framewok适合快速开发网站,不见得适合开发快速的网站。
感谢财帮子和FreeWheel的分享,技术其实就那么点事,还是开放一点好。
对Ruby On Rails实在了解甚少,上述内容如有不到之处,请不吝赐教。
Posted in Arch | No Comments »
Saturday, September 27th, 2008
本博客所有原创文章采用知识共享署名-非商业性使用-相同方式共享,转载请保留链接http://chaoqun.17348.com/2008/09/7-stages-scaling-of-web-apps/
几天前看到The 7 Stages of Scaling Web Apps,觉得很是不错,想写点什么,奈何一直很忙,整天忙着那些quick&dirty的项目,让人也堕落了许多。
今天找到报告的原文看了一下,内容丰满了许多。
要构建一个可扩展的网络应用,大多是数据库分表分库、分布式缓存、负载均衡、统一存储,诸如此类,前面我也翻译了一些国外网站架构文章,John Engales的文章高明之处是分7个步骤阐述了一个网络应用从简单到高度可扩展的构建过程。对比这七个步骤,想想我们的应用处在第几步呢?
报告的一开始解释了Performance(性能)和Scalability(扩展性)的区别,里面有两幅图片很好的诠释了,高性能就是买个好车(高配服务器)在高速公路(充足带宽)跑,高扩展性是一堆车跑在立交桥N通道上,不一定跑的很快,至少不会堵车。
第一步:开始阶段
简单的结构:防火墙+负载均衡、一对服务器、数据库服务器、内部存储,结构简单,没有冗余,维护成本低,很是适合开始阶段。
这样的应用结构应该撑个50W~100W的访问没问题吧,一般的应用话。
很多的应用可能还不到这个水平,一台服务器扔在托管机房里,应用和数据库跑在同一台服务器上,这样的应该是“第零步”吧,如果要扩展这样的应用,升级到第一步吧,应该对程序和数据库不需要怎么修改,效果可能还会不错(如果你的应用不是特别大的话)。
第二步:和第一步一样,只是规模大了些
应用很成功,加更多防火墙、负载均衡,增加更多的应用服务器,找个DBA来优化一下数据库,增加数据库存储备份,把数据库存到SAN或者DAS(这个不太赞同,有几个有这个钱的啊),仍然是个简单的应用。
第二步也很有用,估计能撑到300W左右。如果钱能解决的问题,都不是问题,访问量大了,有钱了,多买点服务器能解决问题何乐而不为?
第三步:痛苦的开始
访问量大了,加个Squid或者Varnish做反向代理吧,或者更高级的负载均衡,以缓存静态内容。加更多的应用服务器,数据库做个Master-Slave,一台Master负责写操作,N台Slave负责读操作,可能会需要做一些代码修改。
到这一步就有点像模像样了,这应该是硬件方面能做到的极限吧,估计撑了500W左右问题不大。
第四步:更加痛苦了
访问量更大了,做个memcache分布式缓存吧,数据库主从复制出现问题了,大量的写堆积到一台服务器上,复制时间过长(数据库从服务器不能即时同步),然后可以做做数据库分区(或者分表),内容统一存储,需要大量重构应用和数据库结构。
终于引入memcache了,可以大大减轻服务器硬盘读取的负载,当数据库(数据库表)变的过大的时候,再多服务器都不管用,想想你的一个数据表有100G,索引有10个G,服务器内存才4个G,光放索引都放不下。这个时候分表会是一个不错的选择,简单的分表可以自定义一个hash函数或者按照ID主键分表,只是这种固定的分表方法将来数据迁移会费事很多,还是推荐Flickr的中心数据库做法,后面会讲到。
到第四步的规模,估计1000W问题不大了
第五步:真正的痛苦开始了
开始恐慌了,开始考虑整个应用模式了,仅仅是通过业务分区还不够,可以通过地理位置啊(比如北方的用户都用北京的服务器),用户ID啊什么的分服务器分区,建立服务器集群,对于每个集群,所有功能都是可用的(这样可以很好的做数据迁移以及冗余),使用一个hash结构或者主服务器来判断用户属于哪个服务器集群(^_^中心数据库)
第五步?估计很多应用都到不了这一步,已经分完善了,估计5000W左右都没问题。
第六步:一点点痛苦
扩展应用和数据库架构,提高性能,增加新功能,优化代码,访问还在增长,但是可控。
比较惬意的阶段了,1个亿的访问量轻松应对吧。
第七步:进入未知的领域
开始找系统的瓶颈了,电源、存储、CDN什么的,更多的数据中心,可能难题是夸地区的数据复制。
呵呵,这个应该是Google考虑的问题了.
想想我们的应用瓶颈在那里,不要一下子什么都想想全了,一步到位的做法是不存在的,知道那里不足,解决它,发现其他的不足,再解决,无休止的循环,直到你失业(什么问题都没有,还要你做什么啊)或者退休(该歇歇了)。
Posted in Arch, 默认分类 | 1 Comment »
Wednesday, August 6th, 2008
本博客所有原创文章采用知识共享署名-非商业性使用-相同方式共享,转载请保留链接http://chaoqun.17348.com/2008/08/flickr_architecture_part_ii/
Flickr的架构不能说是完美的,没有完美的架构,ebay对于扩展有以下建议:
不要预先去为性能扩展,出现问题之后找到问题再寻扩展;
不要想寻找到一个一劳永逸的方案,因为你不知道下一个瓶颈在哪里;
访问量大了,出了问题,修改架构,稳定运行,访问量再大了,又出问题了,再修改,这个是解决问题的唯一方案。
Flickr是Lamp架构比较成功的案例之一,抛出Flickr的架构是因为看到国内很多的架构设计盲目、迷信以及短视,不过相对于架构来说,程序的结构更让人担忧,后面的我会写一些关于程序结构的文章,希望能和大家一起讨论成长,好了,我们继续Flickr的架构。
"Statelessness"设计,@fininan提示是“无状态”设计,比我开始译的达意许多,不过还是不太明白具体细节,原文"Statelessness means they can bounce people around servers and it's easier to make their APIs.",希望懂得朋友补充。
通过master-save的设计能解决一部分问题,但很快你就会发现不行了,常见的master-slave只能解决读的问题,但存在单点失败故障,而且当负载比较重的时候会存在复制延迟的问题,很多公司都会碰到。
搜索功能由专门的服务器群来支持,通过复制需要搜索的内容到搜索服务器去搜索,和App servers分开。
集群
1、分表:按照一定主键拆分数据表,比如按照用户划分;
2、一个用户的所有信息在同一组服务器上
3、数据能够在不同的服务器组上迁移(Statelessness)
4、一组中心服务器负责查询,比如定位某个用户在哪个服务器组
5、不要以用户ID作为分组的依据(Non-Statelessness)
服务器组中每台服务保持50%的负载,当某台服务器down机或者维护时,另外一台服务器100%负载
访问高峰时,每台服务器的负载可能高于50%,现在Flickr通过增加服务器来让服务器负载在50%以下
每个页面大概有27~35个mysql query(够高的),点击数统计、API调用数据库都是实时的(太恐怖了,估计只有Dathan Pattishall会这么变态的使用mysql)
每组服务器处理40万+的用户数据,很多数据存储了双份,比如A用户对B用户的博客进行了评论,那么评论的数据在A的数据表里面和B的数据表里面都存储了一份,Flickr通过事务来保证同步。(这样做的目的是保证同一个用户的数据都存放在同一组服务器上,省去复制的成本。)
Flickr的硬件设置:Intel EMT64处理器/红帽RHEL4/16GB内存/6块15000转的硬盘做RAID-10/12TB用户数据(仅仅是数据库而不是图片)/2U服务器,每个服务大概有120GB数据
备份:每天不同时刻跑cron,每天晚上做数据库快照,专门的服务组来备份(和线上业务分开),交叉备份(比如每天、每周、每月)
每张图片都有自己的档案,档案包括大小、尺寸、像素等等,储存在数据中
每组服务器最多400个连接,45个线程缓存
Tag标签,Flickr发现常见的数据库结构不能很好的处理巨大的标签库,他们采用的是类似倒排索引以及大量的缓存来处理,并且Tag标签不是实时的,他们会在线下进行统计
Flickr目标是所有的事务都做成实时的,没有延迟(个人觉得倒是没有这个必要)
Todd Hoff总结的经验:
不要把你的应用简单的看成一个Web应用,可能会有REST APIs, SOAP APIs, RSS feeds, Atom feeds等等的应用
无“状态”设计,不要把你的用户死死的绑定在某个服务器上
产品设计时需要做扩容的计划以及预算
慢慢来,不要一开始就买一堆服务器
实地考察,不要臆想,获得实际数据之后再做决定
内建日志系统,记录服务器和应用日志
Cache,缓存是必不可少的
抽象层,由于你的架构随时可能变,架构的变化必定要带来底层的变化,这就需要你在底层的基础上根据业务封装一层中间层,这样底层的改动不至于影响业务(这个太重要了,不要因为扩展把原来的程序推倒重来)
迭代开发,随时改进
忘记那些调优的小技巧吧,比如很多人对与PHP里面的require和require_once的性能差别,这些性能的差异和架构上的短板比起来根本不足为道
在线上测试你的效果
忘记用工具测试出来的结果,这些结果只能给你一个大概的印象而已
找出你的系统短板,一台服务器的最大处理能力是多少?现在离最大负载还有多远?mysql的瓶颈在哪里?是不是磁盘IO?memcache的瓶颈在哪里?CPU还是网络传输?
注意你的用户使用规律,比如Flickr发现每年的第一个工作日比平时多20%~40%的上传量,周日的访问量比平时要多40%~50%
要注意指数型的增长
你的计划是为你访问的峰值设计的
补充:阅读完原文的评论,有一个评论翻译出来给大家分享:
Flickr如何存储图片的呢?
标准的Flickr图片Url是这样的http://farm1.static.flickr.com/104/301293250_dc284905d0_m.jpg,其中farm1是Flickr的服务器群,static.flickr.com是Flickr静态图片服务器,104是服务器ID,301293250是图片ID,dc284905d0是Flickr的加密串,防止盗链,m表示图片的尺寸。m表示中等尺寸
后记:
终于“翻译”(姑且用这个词)完了,看到原文的一个评论是"Hmm... i can not beleive flickr written on php...",借用好像也是Flickr的人说的一句话:扩展的不是语言,而是架构。国内很多大的企业都在用PHP(比如我所在的sina),PHP总给人是草根语言的感觉,是因为没有人肯分享自己的架构,以及程序员写程序的时候不注意自己的结构(设计模式),好的架构只能让你的程序跑的更快,好的结构让你的程序更易于维护,更容易让别人看的懂,更容易团队合作。
Posted in Arch | 3 Comments »
Monday, August 4th, 2008
本博客所有原创文章采用知识共享署名-非商业性使用-相同方式共享,转载请保留链接http://chaoqun.17348.com/2008/08/flickr_architecture_part_i/
Flickr(http://www.flickr.com/)是国外一个领先的图片分享网站,现在应该在yahoo门下,感觉yahoo还是有很多好东西,奈何资本要抛弃他了。这个轮回其实挺有意思的,起先是做实业被microsoft郁闷了,说软件是虚的值不能那么多钱,然后microsoft被yahoo郁闷了,说互联网是虚的不值那么多钱,然后是yahoo被google郁闷了,yahoo比较厚道没说什么,现在microsoft要收购yahoo了(折腾好久了,估计要落听了吧),不知道google将来要被谁郁闷了。成功建立在相同的失败上,反过来失败都是建立在相同的成功上也成立,进入正题吧。
原文地址是http://highscalability.com/flickr-architecture,本文不是原文的严谨翻译,带有我的理解以及补充,由于水平有限,文中的错误请各位斧正。
Flickr处理的数据:
多达40亿次的请求(http request or database query?不知道了,不管是哪个,都够大的吧。)
squid总计约有3500万张图片(硬盘+内存)
squid内存中约有200万张图片
总计有大约4亿7000万张图片,每张图片大概4~5MB
每秒3,8000次请求 (存储了1200万对象在里面)
2 PB 存储(星期天要消费~1.5TB)
每天新增图片超过 400,000
吓死人不偿命....
Flickr用到的技术:
PHP
MySQL
Shards
Memcached 作为中间缓存层,memcached在web2.0网站中可能是引用最广泛的产品之一,开源&强大.
Squid 作反向代理服务器(reverse-proxy for html and images).
Linux (RedHat),如果你想用RedHat企业版又不想付费,试试这个CentOS,基本上100%克隆RedHat企业版(估计传说中1%的RedHat代码没有),我用的就是这个。
Smarty 作为模板解析,很多人在讨论smarty这不好那不好,但是大网站都在用,稳定而且功能强大,系统的瓶颈从来不会再smarty这里,我保证。
Perl 估计用perl做一些系统层面的东西吧,比如日志处理(猜测)
PEAR 做XML和Email解析,和我们一样,Flickr用的也是PHP4,不过新项目还是用PHP5吧
ImageMagick 图像处理的不二选择
Java, for the node service,Java就不太了解了,希望读者补充
Apache 大家都在用,尝鲜的用户nginx或者lighttpd(适合静态文件,youtube用它做媒体文件服务器),出了问题你会抓狂的。
SystemImager 作为服务器部署
Ganglia 分布式系统监控,或者你可以试试nagios,据我所知也很多公司在用
Subcon 用SVN维护服务器配置文件并且可以部署不同的配置文件到服务器集群中去(这个我没用过,系统运维的可能会喜欢)
Cvsup 文件分发,是否类似rsync?
Wackamole前端负载均衡,类似的产品有http://haproxy.1wt.eu/
Flickr架构
常见的Squid反向代理、PHP App Servers、Net App's、Storage Manager我在这里就不讲,我们关注一些让人兴奋的特征:
Mysql的Master-Master结构,mysql的常见的master-slave结构,大家都知道存在"single point of failure"(单点故障的问题),且只对读操作有好处,对于写频繁的网站却不是一个好的解决方案,Flickr的双master方案据我推测用的就是这个http://code.google.com/p/mysql-master-master/,原理就是master轮询,保证同时只有一个master负责写,解决了单点故障的问题。
Dual Tree Structure,看看下面的图就知道什么是“双树结构”(姑且这么翻译)
示例图中上方的2台机器为master,下方的4台为slave,这种“双树结构”的设计保证一个slave只有一台master,易于扩展也不会形成环路。原文中说这种设计是1+1=200%的设计,简单高效。为了防止自增长冲突,数据表中无自增长列。
补充:对于大型应用的分表设计,防止自增长冲突是个问题,有个简单的方案:比如分3张表,可以设第一张表从1开始以3跳跃递增,那么第一张表存储的序列为1,4,7,10……,第二张表从2开始也以3跳跃递增,第二张表存储的序列为2,5,8,11……,第三张表从3开始以3跳跃递增,第三张表存储的序列为3,6,9,12……,保证不会有重复的序号,但这种方案的缺点是如果数据爆炸,3张表不够,你分4张表呢?需要手工迁移数据,如果程序写的不好,底层又要大动了。
Flickr采用的方案是一个中心'users' table(用户表),记录的信息是用户主键以及此用户对以的数据库片区(有点类似Key->Value的设计,这样的数据结构查询起来是非常迅速的,据说Google的用户登录数据用的就是这样的设计,通过改进版的BDB数据库存储用户名和密码,这样登录起来就不用去查那个大表了),从中心用户表中查出用户数据所在位置,然后直接从目标位置中取出数据。
用专门的服务器存储静态内容,这个容易做到,比如专门的图片服务器。
"Use a share nothing architecture"这个比较费解了,字面上的意思是使用一个无共享的架构,其实就是解除架构上的依赖,类似我们写程序解耦合一样。
除图片外,所有的数据都存在数据库中,这里他们提到了PHP session,我们知道php的session是存储在服务器文件系统的,而且默认没有做hash目录,这就意味着如果你的网站访问量大,比如有10万个人在线,你的session目录下就有10万个文件,如果你的文件格式是NTFS(windows)或者Ext3(Linux),你要定位到某个文件,系统基本上会假死,有个好的建议是不要在一个文件夹下放超过1000个文件。使用默认的php session还有另外一个问题:服务器session同步,用户在A服务器登录后,session存储在A服务器上,然后应用跳转到B服务器,B服务器上的session没有同步就出问题了,当然解决这个问题的方法很多,比如统一存储session,所有服务器的session都存储在一个vfs设备上,或者通过cookie重新生成一个session在B服务器上
写一篇这样的文章非常的辛苦,第一部分就先写到这里,待续……
Posted in Arch, 默认分类 | 6 Comments »