没有任何经验,学习如何扩展一个网站是相当困难的。假设你现在有很多像highscalability.com这样的网站,你需要一些好的方案来扩展它们,但是没有“灵丹妙药”。
没有一种解决方案可以满足所有网站的需求。你得自己去做,通过不断的思考找到一个能满足你需求的解决方案。我就是这么做的。
几年前,我的老板找到我说,“我们想给你一个新项目。主要是一个网站的重建。一个月内,这个网站就有100万用户。你必须重建这个网站,
以确保我们能够应对未来不断增长的用户数量。我已经是一个有经验的程序员了,但是我不擅长这些方面,所以我要开始学习如何扩展一个网站。
(相关文章推荐:重构:“为什么”和“如何”)
这个网站的后台软件是一个基于Smarty和mysql的php内容管理系统。首要任务是找到合适的托管公司,需要有丰富的经验,能为我们管理服务器。经过一些调查研究,
我们找到了这样一家公司,然后把我们的要求告诉了他们,他们给我们推荐的配置如下:
负载平衡器(后备)
2台网络服务器
Relational database server (fallback)
开发机器
他们说,这就是我们所需要的。我们对此毫不怀疑。我们得到的最终配置是:
负载平衡器(单核,1GB内存,磅)
2台网络服务器(双核、4GB内存、Apache)
MySQL服务器(四核,8GB内存)
开发机器(单核,1GB内存)
这个配置非常基础,没有进一步优化。为了同步文件(PHP和媒体文件),他们建立了一个主动-主动DRBD。终于,重建开始了。当然,我们很兴奋。一大早,
我们将域名切换到新的IP,运行我们的监控脚本,然后盯着屏幕。我们立即看到了这些机器上的流量,一切似乎都运行良好。页面加载很快,MySQL承担了大量的查询任务,这让我们都很开心。
然后,突然我们的电话开始响起:“我们无法访问您的网站。怎么了?”我们看了一下我们的监控软件,确实是——服务器被冻结了,站点离线了!当然,
我们做的第一件事是给我们的主机服务提供商打电话:“我们所有的服务器都崩溃了。这是什么?”他们答应检查机器,过一会儿再打来。这个电话来了:“你的系统根本无法干预。你做了什么?完全搞砸了。
“他们停止了负载平衡器,然后让我查看其中一台Web服务器。看到index.php的文件,我很震惊。它包含一些奇怪的C代码片段、错误消息和一些看起来像日志文件的东西。经过进一步调查,
我们发现DRBD造成了事故。
“杀死”您的服务器的方法之一
把Smarty编译器和模板缓存放在一个高负载的主动-主动DRBD集群上,你的服务器就会挂掉!当我们的主机服务提供商修复网络服务器时,
为了在这些服务器的本地文件系统上存储Smarty缓存文件,我重写了一些CMS代码。我们又上线了!
现在是下午。这个网站通常在下午晚些时候到晚上达到高峰。晚上,几乎没有车流量。我们一直盯着监控软件,所有人都异常紧张。这个网站可以加载,但是后来系统负载越高,响应越慢。
我增加了Smarty模板缓存的生存期,希望它能产生——的效果,可惜没有产生效果!很快,服务器开始给出超时提示、空白页和错误信息。两台机器承受不了这么大的负荷。
我们的客户这个时候有点紧张,但是他说,好吧,重构通常会产生一些问题。只要你能快点修好,就没事了!
我们需要一个计划来减少负载,然后,我们和我们的托管服务提供商讨论了这个问题。他们的一个系统管理员提出了一个好主意:“伙计,你的服务器现在运行在一个非常常见的Apache+mod_php架构上。
把你的Web服务器换成Lighttpd怎么样?它是一个相当小项目,但是维基百科都在使用它。”我们同意了。(相关文章推荐:更好的选择细数Apache服务器的四个替代者)
'杀死'你的服务器的方法之二
把一个开箱即用的Web服务器架设在你的机器上,并且一点也没有对它进行优化,那么你的服务器将会挂掉!那个管理员尽了他的最大努力,尽快地重新配置了所有的Web服务器。他抛弃了Apache,
然后切换到Lighttpd+FastCGI+Xcache上来。后来,当我们重新上线的时候,我们几乎没有再感受到压力。这次,这些服务器会维持多长时间呢?
这些服务器运行的出奇地好。负载比以前低很多,平均响应时间也不错。我们彻底放心了,然后我们都回家睡觉了。天已经很晚了,我们认为没有其他的事情需要我们做了。第二天,网站运行的相当好,但是在高峰时段,
它一直接近于崩溃的边缘。我们发现MySQL是瓶颈,我们再次打电话给我们的托管服务提供商。他们建议在每个Web服务器上用MySQL从服务器进行MySQL的主-从同步。
'杀死'你的服务器的方法之三
再强大的数据库服务器也有它的极限,当你到达它的极限的时候,你的服务器将会挂掉!在这种情况下,某些时候你的数据库会变得十分缓慢,以至于队列中大量的网络连接会再次“杀死”我们的Web服务器。
不幸的是这个问题很难修复。内容管理系统在这方面十分的简单,它本身并不支持单独地读取和写入SQL查询。重写这一切花了很长时间,但是相对于每分钟都遭遇到挂起休眠来说,是相当值得的。
MySQL同步真的成功了,网站最终稳定了!在接下来的几周,几个月里,网站取得了成功,用户的数量开始不断地增加。流量再次超过我们的资源限制,这只是时间的问题。
'杀死'你的服务器的方法之四
不提前作规划,你的服务器可能会挂掉!
幸运的是,我们一直在思考,并且一直在做规划。我们优化了代码,减少了每个页面载入的时候需要的SQL查询的数量,我们意外地发现了MemCached这个好东东。首先,
我们在一些核心功能上添加了对MemCached的支持,在一些重量级(运行缓慢)的功能上我们也添加了对MemCached的支持。当我们把这些变更部署以后,
我们简直不能相信这个结果——这感觉有点像发现了“圣杯”。我们每秒查询的数量至少降低了50%。我们决定更多地使用MemCached,而不是购买另外一个Web服务器。
'杀死'你的服务器的方法之五
忘记做缓存,你会浪费很多钱,而且,你的服务器还会挂掉!事实证明,MemCached帮助我们减少了70%-80%的MySQL服务器上负载,同时,在Web服务器上,也产生了巨大的性能提升。
页面载入的相当快。
最终,我们的配置看起来似乎是完美的。即使在高峰时段,我们也无须再担心崩溃或页面响应缓慢了。我们搞定它了吗?不!一台蓝色的Web服务器开始有一点响应缓慢了。然后出现了一些错误消息,空白页面等等。
这个系统负载能力很不错,在大多数情况下服务器也都在工作,但是只是在“大多数情况下”而已。
'杀死'你的服务器的方法之六
把成百上千个小文件放在一个文件夹里,当索引节点耗尽的时候,你的服务器将会挂掉!
是的,你没有看错。我们过去只是关注MySQL,PHP和Web服务器本身,并没有太关注文件系统。Smarty缓存文件存储在本地文件系统里——所有的缓存文件都存储在同一个目录下。
解决方案是把Smarty放在一个专用的ReiserFS分区里。另外,我们还打开了Smarty的“use_subdirs”选项。
在过去的几年里,我们一直在优化页面。我们把Smarty缓存放到了memcached中。为了更快速地处理静态文件,我们安装了Varnish来减少I/O负载。
我们还切换到了nginx(Lighttpd会随机的产生error 500的消息),安装了更多的内存,购买了更好的硬件,更多的硬件.这个列表永远不会结束。
总结
扩展一个网站是一个永远不会结束的过程。当你解决了一个瓶颈以后,很可能马上会遇到下一个瓶颈。永远都不要这样想:“就是这样,我们大功告成了”然后就靠边站了。这会“杀死”你的服务器,甚至是你的业务。
规划和学习是一个持续的过程。如果你因为缺乏经验或资源而不能自己完成这个工作,那么可以找一个有能力胜任这个工作,而且很可靠的合作伙伴,和它一起来做这个工作。
永远都不要停止和你的团队和合作伙伴沟通当前遇到的一些问题和即将会遇到的一些问题。思考在前才能争取主动。