主题:【原创】wikipedia架构学习笔记(一)他们的骄傲 -- 羽羊
写得太细显得罗嗦,写得太粗显得草率。
我也时时遇到类似问题。没有好办法。
回想起来,最终决定是粗还是细的,恐怕是写的时候的状态,如果忙,就粗,如果闲,就细。
。。。
打住,看样子,不是在交流经验吧。
你那个flickr的坑,该填填了吧?
web该怎么做?怎么运营?
写wikipedia架构这篇文章的过程中,脑子里总是想着37signals这个公司,这一家公司和wikimedia基金会简直就是两个极端,前者致力于知识传播、和谐社会、世界和平,37signals从一开始就钻到钱眼儿里头坚决不出来(Free is bull****,What's so good about free ? I don't get that,Having 4 million users use your free thing doesn't mean anything. If you charged $1,,you'd probably lose almost all of them,so is it any good at all ?——Jason fried) ,酷吧,让小羊想起了微软关于“用户/客户”的八卦。但是人家赚钱,在geek们看来,却是很少铜臭味道,并且怎么着都透出一股子特立独行的味道,作产品,做出ruby on rails一炮而红,卖服务,捎带着写出一本《getting real》,吸引无数startup.com追捧,公开个人形象都好像美剧剧照——精心装扮、味道十足,西装领带站人家跟前那真是不好意思打招呼,明星人物DHH更是青年才俊,一时风流无限。你说都是做生意,这差距,唉~~~
说实话,真不知道该怎么说37signals的架构,和wikipedia不同,wikipedia架构庞大精细严整,透出一股大巧若拙的正规军味道,37signals就显得有些向剑走偏锋的土包子了,跟wikipedia比,真没什么好谈的了。
37signals的王牌产品bashcamp,用rails写成,关于rails,开发的速度毋庸置疑,而性能和伸缩性则一直是非不断,例如和twitter之间那些扯不清的口水官司,至于DHH本人,对于系统架构的看法,颇有些另类:
听其言,观其行,再结合rails一些特点:
1、默认适用cookie维持状态,share nothing的一个重要条件。
2、部署推荐fast cgi 或者 mongel cluster,天生适合横向扩展。
3、active record拼装出的SQL, 有些故意的引发N+1问题。
4、多数据库支持,rails核心没有,想要的自己找plugin。
基本上脉络比较清楚了:
1、比较重视程序本身横向扩展的潜力,由于rails框架某种程度上强制程序实现了share nothing架构,所以在加入应用服务器的时候,程序本身不会构成障碍。
2、部署方式无论单台server还是cluster,都是一样的,甚至虚拟机,无非是改改配置文件,加入一个节点就得。
以上两条,决定架构在应用层面都很容易一路横向复制下去,所以rails社区甚至对于ruby本身性能的不满都能容忍下来,反正性能不够,机器来凑。
3、默认ROM拼装出来的SQL都简单至极,从sqlite到oracle都有很好的适应能力,数据量上去了,换更好的dbms都不太用改代码。
4、对于多数据库是漠视的,这样想玩儿shard就比较有难度了。
DBA为什么能拿高薪?sql语句优化,数据库性能调优,shard的维护和管理这些都得拿钱买。rails生成的sql语句基本上都能用的上主键索引,而且语句极其简单,老实说,看不出什么能优化的地方了,如果效率低下了,要么dbms级别太低,要么服务器性能太差,这两条问题都可以很方便的定位,DHH的看法是于其花钱雇人,不如花钱升级服务器,赤裸裸的资本家思维阿。
综上,多么简洁明了的架构阿:
前端nginx或者haproxy或者apache作负载均衡,请求分发到数个分布在N台服务器上的ruby进程或者mongrel服务,然后统一访问一个big ass数据库服务器。
另外,截止07年的数据,5.9 T 用户上传的数据,888 GB 上传文件 (900,000 请求),2 TB 文件下载 (8,500,000 请求),到今天应该更多了,37signals更绝,连买硬盘租带宽的钱都抠,人家直接扔到amazon的s3上头去了。最新的消息,原先37signals用了xen做了一部分虚拟化,前些日子人家做了个实验,比较下面两幅图:
看起来还是硬碰硬踏实,虚拟化堪忧。
总而言之,这帮家伙真没在性能上费神太多,至少比不上wikipedia花的精力,人家的态度太明确了,挣钱——然后砸钱——然后解决性能问题。
他们的架构师是谁?分明是intel和amd阿。
本帖一共被 1 帖 引用 (帖内工具实现)
赚钱的geek!
网站做大了,一台服务器是不够的。
服务器多了,其实真不是好事儿,大有大的难处。
wikipedia的服务器有好几百台,其中web的至少要超过二分之一,这么多的服务器,扑面而来的,不是好处而是问题。
不信?往下看
再看看wikipedia的:
这里头可以说道说道了。
前一个例子(就叫A网站吧)其实和wikipedia一样,部署了CDN,区别在于wikipedia的CDN有统一的入口,A网站采用了要求用户自行选择的方式,作为一个用户,首先肯定感觉晕菜,作为一个搞web的,个人能理解网站技术人员的难处,同时替他们可惜,这么多镜像站点的维护,本身就足够nb了,可惜万里长征就是不愿意走完最后一步,再花点力气整合一下多好,但是反过来想想,是不是读西厢流泪了?A网站实现wikipedia的模式应该不会有技术上不可逾越的问题,那么这种选择肯定有他们的原因。
挂一漏万的分析一下A网站模式的好处:
1、用户自主选择入口,对于运营商之间存在瓶颈,而且瓶颈本身都不稳定的环境,有必要,至少用户可以多试几次,找到对于自己来说最快的节点。
2、网站的部署简单,只要关注内容的同步即可,甚至某些特殊情况下可以故意造成内容不同步,且不用考虑缓存、反向代理因素,技术复杂度低。
3、如果是商业站点,那么就类似与连锁加盟的模式,在共担投资,分享收益方面责权利清晰。
4、有利于提升用户知识水平。
这些好处当中,第三条和wikipedia半毛钱关系都没有;第四条虽然也是wikipedia立站之本,但好像wikipedia没打算通过行为艺术的方式达到目的;至于第二条,对于一个大网站来说,缓存和反向代理是必要的技术手段,A网站看似规避了这样的问题,但是某一个镜像站点如果压力过大,那么终归还是躲不过去的,难不成到时候再弄个XX镜像2?在这样的技术问题上,wikipedia的性格取向就是“硬扛”,用技术的方法解决技术问题;第一条在某些特殊环境下有效,比如中国内地,但大部分场景并不靠谱,河友就有精彩论断“物理距离近,速度未必快”,原因就在于还存在着诸如镜像服务器负载、机房接入带宽、运营商抽风、奥运开幕、CCTV曝光等等靠用户本身并不能确定的因素。
再看看Wikipedia模式的好处:
1、统一的网站入口,用户体验好。这一点很重要,内容的提取和返回是网站的义务,提升网站性能,还是要 靠 自己。
2、具备内部的负载均衡和健康检查机制,节点负载比较均衡,网站整体性能较好。
3、可以部署统一的缓存或者反向代理方案,进一步提升网站整体性能。缓存和反向代理是个好东西。但是在部署管理方面困难不少,如果非要部署的话,那么还是设计好整体架构,然后一次部署的好,反过来说,镜像网站存在部署N次的风险,wikipedia的模式看似“硬扛”,事实上还是走了捷径。
4、可以把自己的方案综合起来,做个技术网站,或者到会议上做presentation,让人家学习并且景仰。
这样子来说,局外人看起来,还是wikipedia模式好阿。
慢着,这篇两次提到了“硬扛”这个词。
“硬扛” ——状中短语,扛:两手举重物,硬:倔强,执拗地。举重物,还倔强、执拗的,看起来搞wikipedia模式这活儿不轻阿。
其实真不轻。
花俺都上了,它说俺没有看帖子。又这样的送花党吗?
这个我也注意到了,有点儿意思,我还以为太守学雷锋呢。
一个企业,骨干员工很重要,一个好的骨干,往往能够带动一个部门,再NB点的,甚至能够形成一种氛围,如果和企业文化能够结合起来,甚至比严酷的制度以及狡诈的激励更有利于管理和生产率的提高。如果骨干员工跟企业对着干,嘿嘿,企业这颗蛋离散黄儿可就不远了。
对于wikipedia来说,mediawiki程序无疑就是它的骨干员工,对于mediawiki,他们没少费功夫。
首先,要清扫外围,把mediawiki有可能消极怠工的借口全部打掉,为防止mediawiki同学拉PHP出来当肉盾,首先部署了APC,apc是个PHP的优化器,会缓存PHP的bytecode,对于提高程序运行速度非常有好处。(对于用PHP做站的朋友,小羊的建议首要就是部署APC,免费,而且效果显著,配置工作量小,而且有完善的监测工具。这玩意儿快有点儿银弹的味道了,好像facebook也在用。)
接下来,wikipedia就开始收拾那些有可能成为性能热区的枝枝蔓蔓:
第一、用Imagemagick替换GD进行图片的处理,GD和ImageMagick相比,首先是功能上面有区别。
GD ImageMagick
GIF No Yes
JPEG Yes Yes
PNG Yes Yes
Cropping Good Good
Scaling Fair Very Good
Rotation Poor Very Good
Flip Good Good
其次,在处理结果,也就是画质上有区别,可以参见
其三,最重要的,性能上有差距,可以参见
关于性能比较,其实还是存在一点争议,有的测试结果指出,使用某些ImageMagick的API,处理速度反倒不如GD,有的测试结果也指出,少量图片的处理GD的速度也比ImageMagick要快,随着图片数量和大小的上升,ImageMagick基本不受影响。但是无论如何,在性能方面,ImageMagick有一个重要的优势:GD作为PHP的一个模块,因为PHP接到请求后初始化资源,响应后释放一切的工作模式,在大负载的情况下,GD无疑会拖慢PHP,反过来说,ImageMagick和PHP完全是松耦合的关系,如果PHP使用命令行调用ImageMagick的话,那么甚至可以说没什么联系。ImageMagick享用OS的资源,给PHP提供服务,如果图片处理成为性能热区,就干脆把imagemagick切出去,然后就一了百了。解耦、然后横向扩展,是大型网站架构设计的一个重要思路。
接下来,对字符串搜索替换开刀,strtr() 是php常用的字符串替换函数,速度其实不慢,但是还是满足不了要求,对于wikipedia这样的网站来说,字符串的搜索替换简直就是一个海量的工作,比如用户编辑内容的格式化、敏感字符包括有安全隐患字符的替换,还有大量的中文繁简体转换,于是他们使用Tim Starling(wikipedia的开发人员和系统管理员)编写的php扩展fast string search 替换掉了strtr()。
这个链接里头还有不少好东西,自己找找看吧
然后,wikipedia是一个用户编纂的百科全书,作为一个使用者,应该认真的研究每个用户提交的修改,毕竟wikipedia声称中立,而用户总有倾向,所以,diff功能是wikipedia使用频度极高的模块,这部分,他们使用了wikidiff作为diff引擎
好了,外围的“皇协军”算是清扫的差不多了,就剩下mediawiki同学老老实实的抱着数据库CRUD,下一步干吗?当然是向八路学习:
安插内线
获取情报
然后……
大刀向鬼子们的头上砍去~
性能调优是个非常头疼的事情,一般而言,很多网站性能出了问题,上来三板斧,第一拆数据库,第二拆应用服务器,第三上memcached,这三招使出来,问题往往会消停一段时间,但不过是饮鸩止渴而已,这三招,基本涵盖了有可能出现问题的方方面面,在不清楚性能问题症结的情况下,这种全方位火力覆盖的方法规避而不是真正解决了问题,拆拆补补总有个限度,一旦性能再次恶化,就很难收拾。
在两眼一抹黑的情况下,没有办法精准的定位问题所在,仅仅是不停的三板斧耍下去,实际上是在不停的增加复杂度,因为三板斧本身也是两眼一抹黑的,这样,早晚有一天,整个架构,会被自己的复杂度压垮,这样的例子很多。所以,做网站的性能优化,首先要在profiling上做好足够的功课,首先要明确哪些地方用的多,然后还要弄清楚哪些地方跑得最慢,换句话说,要在庞大的网站黑箱里头掺沙子,安插余则成上报敌方动向,否则,hoho,要不然就是狗咬刺猬,要不然就是费了牛劲优化的是一个十年也用不上的地方,另一方面,一个慢速的socket连接正在逐渐的把网站性能拖向深渊。
Wikipedia的余则成在哪里呢?
mediawiki程序主要的代码段调用了profiling函数wfProfileIn和wiProfileOut,(函数代码在include/profiler.php文件中,另外还有5个profile开头的php文件,也负责profile工作。恐怕以某些OOfans的眼光来看,代码写的不算漂亮,这有php自身的原因,但简洁实用),这两个函数会把性能数据存入数据库或者发给一个监听3188端口的后台守护进程(守护进程的代码在外链出处),这个守护进程会形成一个实时的性能数据报告。,我们跳过无聊的代码分析,直接看看生成的报告
外链出处,
有了这样的报表,程序性能热区在什么地方,一目了然。
一个哥们儿说过,开源的世界里,好东西的多少,仅仅取决于我们的视野,诚哉斯言。即使面对上图这样的性能报表,wikipedia仍然不满足,于是我们在他们的指引下,又见识到了一颗闪耀的珍珠-kcachegrind,外链出处,这是一个性能数据的可视化工具,能够输出可读性非常好的性能数据报表。
到此为止,有了meidawiki程序内部的余则成,还有了监听3811端口的联络站,最后还有 kcachegrind坐镇特科情报分析中心,wikipedia这一套组合拳打出,性能问题门户洞开,只等兵临城下、一战成功了。
面对这样的性能监测结果,小羊首先感觉到的是震撼,从wikipedia的profiling动作中,体会如下:
1、没有性能监测就没有性能调优
2、性能监测要从代码抓起
3、监测结果要充分的可视化以便分析
4、监测功能要简洁快速,免得自身的负载干扰监测结果,同时要有灵活的开启和关闭能力(mediawiki程序当中的startprofile.php文件提供了关闭profile的功能)。
震撼完毕,开始仔细研究这张报表。
好像,发现了一个问题?
您也看出来了吧,这事儿咱们下回接着聊。
Wikipedia这个坑,是个宝藏呢。值得说道说道的东东实在太多。
fgets吃掉了1/4的时间,说明memcache命中率不佳?
cache ? ,it's a question...
这个系列不是一篇可以领悟的,需要反复看。
反复看的东西,最好有个打印件,躺在床上,站着等地铁,蹲在某处,等等场合,都方便阅读才好。
元旦之前这段时间实在是太忙了,跟飞人似的。。。
pdf文档填坑完成后会同期放出的。
PS:PDF好东西哦,老邓你的东西我做成了PDF,打印出来放在案头有空就看呢,不过要声讨一下几个烂尾坑。。。为了表示愤怒,烂尾坑做的PDF拒绝排版,哈哈,前两天跟子山MM分享了一下,估计那几个没有排版的文档她看的正头疼呢,呵呵罪过罪过。