Scale Fail (part 2)
May 20, 2011
This article was contributed by Josh Berkus
Scale Fail (part 2)
翻译:刘晓佳
在上一部分中,讨论了若干影响网站扩展性能的问题,而大部分其实是管理的问题。上一篇文章主要涉及到了公司所做出的一些欠缺长期考虑的决策-或者叫它“反模式”,比如compulsive trendiness, lack of metrics, "barn door troubleshooting", and single-process programming。这一期,我们将探索导致停工的一些更一般的技术管理失败。
No Caching
“报告显示每秒完成了7000次读查询。你确定它们都能被缓存吗?” “我们已经安装了memcached” “memcached是如何配置的?缓存了哪些数据?如何使缓存更新?” “我…不太确定。我们都留给Django解决吧。”
我有时对web公司愿意在更快的硬件上花多少钱,和愿意在一些能够使得他们的应用在平稳的方式下运行的更快的简单事上所花的努力感到非常吃惊。比如,如果你打算扩展一个网站,首先应该问问自己:“我该在哪加一个更有用的缓存呢?”
上面提到的memcached,并不仅仅指简单的数据cache。对任何一个真正可扩展的网站,你可以加入多级缓存,每一级都大有用处:
- database connection, parse and plan caching
- complex data caching and materialized views
- simple data caching
- object caching
- server web page caching
详细分析不同类型的缓存和如何使用这些缓存需要一系列的文章来阐述。然而,每种形式的缓存都共享了将数据发给用户而不管用户在哪和减少响应次数的能力。更为重要的是,通过降低重复应用请求所需要的资源,能够提高你的平台的效率,从而使得它更具扩展性。
看起来很明显,不是吗?但我一只手就能数出在雇佣我们之前就已经具备有效缓存策略的公司。
客户在数据缓冲方面常犯的一个错误是让ORM来完全决定缓冲。问题主要在于作为一个即开即用的方案, ORM无法有效的使用cache,对于完全一致的用户请求才请求缓存,导致命中率几乎为0
我所见过的一种最坏的情况是一个在线拍卖的应用程序。用户做的每件事,如每次点击,每次翻页,每次鼠标移动,都会导致对后台PostgreSQL数据库的查询。加上拍卖的桌面精灵轮询查询拍卖数据库,每用户每秒更新30次。这意味着每个程序的用户每秒将会完成查询内核事务处理数据库100次。
缺乏缓存是个非常常见的错误,下面是另一个我喜欢称之为反模式的一种症状:
伸缩不可能的事情
“在发展的第三阶段,我们会将数据表根据统计出的用户分组分割成12个shard。 没有被分割的数据需要在每个shard上复制,并且我也发明了一种复制机制来 完成这个任务。” “看起来很复杂。你考虑过仅仅缓冲最常用的搜索吗?” “那不行。我们的数据太动态了。” “确定吗?我做了一些分析,当前数据库的90%的访问属于四种模式之一。” “我告诉过你,它将不工作。我才是这里的CTO!”
你的应用程序所需要的某些东西很难扩展,但消耗了大量的系统资源,管理时间和员工的创造性来做这种无意义的事情。这包括事务性数据库,队列,共享文件系统,复杂的web框架(如Django或Rails),和ORMs。
你的基础架构的其他部分很容易扩展许多用户的请求,如web服务器,static content delivery,缓存,本地存储,客户端软件(如javascript)。
基本上,当一个架构越状态化,复杂化,特色化,每个应用的用户使用的资源就会越多,越容易出问题-因此也就越难扩展。通过这个,你也许会认为与快速解决扩展化问题斗争的公司会首先集中扩展容易扩展的,并尽可能推迟那些难以扩展的。
这你就错了。
相反,开发部门的领导貌似热衷于先解决架构中最难扩展的问题。数据库Sharding,负载均衡主从服务器复制,转发事务性队列,200个节点的集群文件系统-这些都会令IT民工们兴奋,而且得到大量的资金上的支持。而有时只需要通过增加一个低成本/简单的Varnish(Varnish是一款高性能的开源HTTP加速器)节点就能解决问题,或修补程序中资源消耗的大户。
比如,我们有个客户的Django服务器过载后down掉了。他们的服务器数量从四台增加到八台,仍旧需要定期重启,需要将应用服务器的数量再加一倍,而这需要扩展数据库服务器。相反,我们做了一些流量分析,发现大部分Django服务器的资源利用在服务静态图像上。我们就把所有的静态图像移到了CDN上,然后就能够减少服务器的数量了。
故障的单点/SPoF
“我们如何负载平衡中间件服务器和数据库服务器之间的连接?” “通过Zeus负载均衡群。“ “从web服务器到中间件服务器呢?“ “同样是Zeus群。“ “Web服务器到网络文件存储呢?数据中心之间的VPN呢?SSH访问?“ “Zeus。“ “该网络上的一切都通过Zeus吗?“ “是的,相当的多“ “好吧,什么可能导致错误呢?“
SPoF,当然,代表着Single Point of Failure。特别的是,它指的是这样一个部件,如果它失效,将会导致整个系统不能工作,而不管其它地方有多么冗余。令人失望的是多少公司花费了大量的硬件和工程时间来使得它们的很多部件高可靠性,却没能移除SPoFs。最终你的系统的可靠性是由最不可靠的部件决定的。
上面对话中的公司在那次会话后的几周的某天就垮掉了。一个系统管理员下载了一个buggy配置到Zeus上,立马整个网络就瘫痪了。数据库服务器,web服务器,和其它服务器都正常运行着,但是甚至就是管理员都无法访问它们。
有时,你的SPoF是一个人。比如,你有一台服务器或甚至一个数据中心,它们只有通过手动操作才能失效,仅有一个员工了解相关知识或者能够登录进去操作。更险恶地是,这些SPoF经常潜伏在你的开发或恢复过程中。我曾目睹过一个公司为了防御DDOS攻击而部署了一套热代码,仅仅让热代码仓库down掉,系统就无法修复了。
"Cascading SPoF"是指那些看起来有冗余措施的SPoF。这里有个简单的数学练习:你有三台应用程序服务器。每台都工作在它们最大能力的80%上。当其中一台失效后,且它的流量均衡到另外两台上面会发生什么情况呢?
并不是说某个组件是唯一的才成为单点;它仅仅需要成为导致失效的一种情况而已。如果所有的组件都工作在接近最大能力的情况下,那么你就有麻烦了,因为少数的服务器故障或者中等的流量增加就可以导致一系列级联的服务器失效。
云成瘾
“……所以如果你一直待在AWS平台上,你将不得不主要进行 横行的扩展,这将需要40K美金的咨询费的工程。如果你转 到传统的托管上,你大约需要10K美金的咨询费用完成迁移, 同时得到更好的应用性能。云服务的价格大约是自己租用机 架服务器的三倍。“ “不到明年我绝对不考虑迁移“ “所以你想花40K美金的合同吗?“
今年年初我曾参与一个火热的讨论,我逐渐发现了一种新的反模式,我们叫它“云成瘾“。我们的几个客户拒绝移走他们的云托管,甚至当它们几乎要毁掉它们的业务时。最糟糕的是AWS,因为亚马逊不支持仅迁移云的一部分(要么就全迁移走),其它的公有云也有类似问题。
云托管的优势在于它不需要预先的基础设施的投资就能启动新的应用和服务用户。作为一种降低创新门槛的方式,云托管拥有巨大的优势。
当应用扩展达到云服务器的资源限制时问题就出现了,不得不转换到新的平台。通常公司会通过超时,运行中断,逐渐增加服务器数量却不能改善性能等方式发现这些限制。提到限制,我指的是这种大规模的公有云自身的内存,处理能力,存储吞吐量和网络配置方面的限制,而且购买繁忙云实例的费用高昂。云服务支撑一个项目起飞是足够的,但是当你需要每个节点上严格的性能需求时就会启动失败。
那就是关于云的伸缩性问题。之所以会这样,是公司没有经验来管理基础设施,没有系统方面的人员,没有迁移的预算。更危险的是,管理人员没有做任何关于基础设施的决策。Advice that a change of hosting is required are met with blank stares or even panic.下一财政年度在启动,实际上是委婉的说永远不会启动。
结论
当然,这些并不全是扩展反模式。个人管理不善,没有预期到需要峰值,缺乏部署工程,依赖不可靠的第三方社团,以及其它一些问题,和我之前所概括的那八个问题一样都可能造成严重的损害。也可能有许多不扩展的方式。我无法一一列出。
只是希望这篇文章能有助于你认识到发生在你自己公司或客户中的这些“scale fail“的模式。我所概括的这些问题主要归结于失误的决策-而不是任何技术方面的限制。就我所经历的,技术方面的问题很少抑制web生意的增长,往往都是来自管理方面的问题造成的。如果你能识别出反模式,你就能够犯更少的错误。
最新评论