Sean Hull是Heavyweight Internet Group的创始人兼高级顾问,拥有20年以上技术顾问相关经验,曾为多家知名机构提供咨询,其中包括The Hollywood Reporter、Billboard、NBC Universal、Zagats、Rent the Runway及ideeli,这些高速增加的公司每月处理接近1亿的独立访客。Hull在Amazon EC2部署和Linux及MySQL性能上有着丰富的经验。巨大流量的处理需涉及多个方面,其中包括网站扩展性、业务连续性、安全及架构挑战等。近日,Hull分享了高性能Web应用打造的经验,剖析了扩展之路上20个最大的绊脚石。如下为译文:
1. 二阶段提交
一般状况下,当数据库中的数据发生改变时,它须要同时被写入内存和硬盘。当一个提交发生时,传统数据库须要负责数据在真实存储媒质上的持久化。牢记,内存的数据在崩溃或者重启后都会消失。即便数据已经在数据库中缓存,数据库仍然须要将其持久化到磁盘上,MySQL的二进制日志及Oracle的redo日志都符合这个要求。
经过MySQL集群或者相似DRBD(Distributed Replicated Block Device)或者Amazon Multi-AZ(Multi-Availability Zone)的分布式文件系统,提交并不只仅是在本地发生,同时也在远端。二阶段提交意味着须要从远端获得反馈,鉴于网络及一些其它的延时,提交速度可能会被毫秒级的下降,仿佛高速公路上的全部汽车都因重载变慢。若有考虑使用Multi-AZ或者读备份,不妨查看Amazon RDS(Relational Database Service)与MySQL的比较。
同步复制一样会出现这些问题,所以MySQL解决方案是半同步的,这也能够看作是在二阶段提交上的一些让步。
2. 缓存不足
在全部层中缓存的做用都相当重要,那么什么地方最须要使用缓存:浏览器、页面、对象仍是数据库存?下面不妨通通试一下。
浏览器缓存彷佛高不可攀,除非你清楚浏览器是从Web Server中取出指令及其渲染的页面。所以,若是包含的对象有一个比较长的生命周期,浏览器将会缓存他们,不须要再次进行读取。这不只会加快用户的浏览速度,一样会有益于Server对网站的托管,由于会切实的减小用户的二次读取。
猛戳这里查看更多浏览器缓存相关,确保设置了期满头文件及缓存控制。
页面缓存须要使用相似Varnish的技术,能够将它当作一个迷你的高速、低开销Web Server。它不能够支撑相似Apache能够的复杂页面,可是它可让很是简单的页面更快。所以位于Apache以前,用于减小负载,让Apache能够处理更加复杂的页面。就像交通警察,在专一更复杂的机动车前,先给自行车放行。
对象缓存由相似memcache的组件完成,能够把它当作是应用程序的便利贴。作数据库查询时会先访问缓存寻求数据,若是发现了所需的数据,那么结果返回的时间将比访问数据库快10-100倍,这样就能够快速的构建页面,从而在眨眼间为用户呈现。若是它没有发现所需的数据,或者只发现了一部分,那么将会创建数据库请求并将返回的数据放于缓存中,让更多的后来者受益。
3. 缓慢的磁盘I/O、RAID 五、多租户存储
数据库中的一切都受到存储的限制,这里既包含了空间问题,也受设备读写的速度掣肘。
若是你使用实体服务器,那么必定要小心RAID 5,独立磁盘冗余阵列的一种,数据保护和奇偶性将严重的影响写操做。同时,若是其中一个磁盘损坏,那么这个阵列在磁盘重建时将变得很是缓慢。
这个方案通常使用RAID 10,它将为你提供独立的镜像集。这致使没有奇偶校验计算,从而不会影响重建时的速度。
云环境可能会涉及到相似于Amazon EBS(Elastic Block Store,一个相似于SAN的虚拟化磁盘)的技术。鉴于其基于网络,你必须与其它租户竞争存储的读写。由于每一个存储能支撑的读写速度是固定的,因此你的邻居可能会影响到你网站及应用程序的读写速度。
最近,Amazon又公布了一个重量级产品Provisioned IOPS(每秒I/O操做)。对于技术专家来讲看起来很是不错,可是对于其它人来讲毫无价值。尽管如此,其依然重要,这意味着你能够锁定你数据库所需的磁盘性能。若是你想在Amazon上托管数据库,那么不妨多关注一下这个。
4. 串行处理
在超市结帐时,若是有10个收银台开放,那么从事的是并行处理。若是每一个收银台都在休息,只有一个登记处开放,那么从事的是串行操做。那么结帐的队伍将变得很是长,不只是结帐人的心情受到影响,购物者也一样如此。这点常常发生在线路不够的大桥收费站以及许多人一块儿离场的体育场所。
网络应用须要严格的避免串行,因等待API调用而产生的阻塞,全部的后端节点都在等待一个搜索服务器,只要你应用程序的某处造成一个线就表明了串行化的发生,那么必须不惜一切代价去清除它。
5. 缺乏Feature Flag
在给业务部门创建应用时,开发者通常从特性和功能入手。Feature Flag将相当重要,它让人们能够经过后端配置文件或管理员UI页面关闭或者打开特性。
为何他们如此重要?若是你有早上4点的救火经验,那么你将明白启动应急计划的必要性。你须要能够关闭评级、评论以及应用程序其它的一些特性,这将不会致使整个系统崩溃。更重要的是,在新特性发布时,有些时候问题并不明显,直到一群互联网用户同时涌入。Feature Flag让你能够选择性的关闭一些功能,而不是关掉整个网站。
6. 单一的数据库副本
你必须使用一个以上的读副本或者MySQL从节点,这容许在主节点出问题时的快速故障转移。
拥有数据库的多个副本意味着横向扩展。若是你有两个,你就会看到3-4个会对你基础设施的提高。
7. 使用数据库进行排队
MySQL数据库很是适合储存表格、数据以及他们之间的关系,不幸的是,它并不适合处理应用程序的队列。尽管如此,许多开发者都习惯使用一个表格来达到这个目的。好比,让你的应用程序包含一些做业表格,或者一个状态列,拥有一些相似“in-process”、“in-queue” 及“finished”的值。
由于锁竞争、scan及 poll进程将形成更多的工做,这些解决方案会带来一些扩展性问题,它们将会显著的下降数据库速度。幸运的是这里存在不少有效的开源解决方案,好比RabbitMQ及Amazon的SQS。
8. 使用一个作全文查询的数据库
页面搜索是掣肘应用程序的另外一个方面,尽管MySQL一段时间也支撑了full-text索引。可是它们只对MyISAM表格有效,其它类型表格都不买帐,一直困扰着开发者。
一个解决方案是使用相似Solr的专业搜索引擎,这些技术拥有许多很好的库去支撑你的编程语言,同时会提供一个更快的搜索速度。这些方案一样易于扩展,而且不会让你的数据库成为累赘。
替代方案是Sphinx SE,一个MySQL存储引擎,将Sphinx服务器整合进数据库。此外,MySQL 5.6版本中还使用了InnoDB作全文搜索的默认搜索引擎。
9. 对象关系模型
ORM,就像毒药同样,一旦进行使用,就很难摆脱。有利的一面是ORM有益于快速原型,而且容许非专家级MySQL开发者使用对象或者内存模式进行读写访问。若是你不进行扩展,那么他们的速度将很是快,并让功能的快速交付获得保障。
而后DBA(数据库管理员)会由于缓慢且丑陋的查询来到开发团队而且说:“这个查询在应用程序什么地方,咱们须要进行修复,它须要被重写。”开发团队则会说:“咱们也不知道!”从而会收到来自运营组一些质疑的眼神。
有能力对bad sql进行跟踪并将其指出是很是重要的。DBA团队须要必定的指引找到bad sql的源头。若是查询是来自ORM,他们并不具有这些指引。这样你的团队将面对一个巨大的技术负债,一样也是个很是难以解决的挑战。
10. 缺乏Instrumentation
Instrumentation(仪表盘)为应用程序提供了码表和油表,这是汽车不可缺乏的两个部分。他们提供了应用程序的内部工做信息:他们记录了时间信息,而且提供了应用程序耗时最多的环节。
一个很是人气的网络解决方案就是New Relic,它提供了一个很是全面的可视化界面,针对各个领域工做者——项目经理、开发者、运营团队,甚至是业务部门均可以从图中发现问题所在。固然,如今已经有不少的开源Instrumentation。
11. 缺乏代码仓库及版本管理
尽管如今这个问题已很是少见,可是还有有些互联网公司在没有版本控制下去创建应用程序。固然那些使用了的人,很清楚它将给团队带来的平常优点和组织控制。
若是你没有使用,随着应用程序变得更加复杂,你将被卷入技术负债的漩涡,为应用不一样部分添加员工将变得异常困难。
一旦你使用版本控制,确保囊括了全部的组件,包含配置文件以及其它要素。而丢失部署时须要用到的部分,将带来额外的风险。
12. 单点故障
若是你的数据只存在一个主数据库上,这就是一个单点故障。若是你的服务器位于一个单独的磁盘上,这也是个单点故障。单点故障能够比做“阿基里斯之踵”技术用语。
不惜任何代价,单点故障都要在应用程序中移除。麻烦的是如何去认识单点故障,即便是选择单一的云供应商均可以称为单点故障,若是拥有多个供应商,或者使用Amazon不一样的部分,那么AirBNB的服务将幸免Amazon 2012年10月的部分宕机。
13. 缺少只浏览模式
若是你深夜在Yelp、Facebook或者是Tumblr上发布评论,你可能就会收到这样的信息:“该特性不可用,请稍后再试”。稍后多是50或者60分钟,也许可能还需多试几回。对于非技术用户,他们仍然感受网站在正常运行,只是奇怪了一点而已。
实际状况是,应用程序只容许你去浏览网站,可是不能够作任何改变。多是主数据库或者是一些存储组件不可用了。
只浏览模式能够经过保留主数据库的多个读备份来实现,使用MySQL副本或者是Amazon读副本相似途径。这样就能够在没有主数据库状况下,保留网站所有浏览功能正常,这一点很是重要。
14. 脆弱的沟通
在扩展上谈沟通可能很是奇怪,可是应用程序技术层不可能由于团队间社交和文化上的差别分离。
强大的通讯线路是必要的,队员必需要知道在错误发生时将找谁。好的交流须要自信及知识渊博的领导,普遍的听取意见并加以改善。
15. 缺乏文档
当Web应用程序包含许多层时,文档相当重要。开发者须要给程序、功能、页面作文档,让后来者看代码时能够清晰的发现所需的提示及看法。当有程序发生故障时,运营程序须要在配置文件上添加评论去代表更改历史。业务流程及关系一样应该出如今公司的wiki里,让人们发现本身问题的解决方案。
文档能够在各个层次起到帮助做用,每一个人都应该拥抱这个爱好。
16 缺乏应急演习
应急一般状况下总会被忽视,团队可能会有“咱们覆盖的地方都有备份”这类的说辞。不错备份、恢复的途径很通吃,关键是确保备份的文件万无一失。一旦在故障转移时发现备份有缺失,那么你不肯意发生的事情必然发生。
应急演习让事情发生以前有了相应的经验,公司应该将此做为运营团队工做的一部分,每一年都须要进行几回。在云时代,应急演习已经变得比之前轻松许多。为保证全部组件都被备份而启动服务器是很是值得的,在这个过程当中你将学到这项操做该持续多长时间,以及困难所在的地方,更知道须要当心些什么。
17. 缺乏监视和指标
监视有着与版本控制一样的重要性:很是基本,缺乏它工做将没法进行;然而确实有一些网站没有监视,或者是监视力度不够——有些服务器或者是核心组件并未被监视。
不间断的收集系统及服务器数据,同时,应用程序和业务级别的可用性也同等重要。若是你不想亲自动手,不妨考虑一个Web服务方案。
18. 莽撞的运营
你骑着马在街道上飞奔,明着带枪进入酒吧,你认为这是在交朋友?确定不是,你在暴力的胁迫别人遵循,全部人都不会有归属感。强大的信心是好的,可是团队的合做是不可缺乏的,团队的智慧高于任何我的。
团队须要不断的对改变作交流,用管理的角度进行,准备好应对失败等等。采起当心及规避风险的态度,永远都有备用计划,你应该有能力撤销全部改变,而且认真对待破坏性的改变,以及那些不可恢复的地方。
19. 日益增加的技术负债
随着应用不断的增加,队伍须要花愈来愈多的时间在老代码的维护和支持上,消除漏洞及缺陷。所以,花在新特性上的时间将愈来愈少。必须谨慎的维护好新特性与技术负债上投入时间的平衡。若是你发现你的技术负债增长,可能就是横下决心重写的时候了。重写可能会影响到短时间新特性及客户特性的开发,可是从长远的角度上看是很是好的。
技术负债并不老是能被轻易的认知,在你创建特性或者是修复bug时,你更习惯于聚焦局部的细节,很是容易失去全局观,这也是为何全面人才更益于Web扩展的缘由。
20. 不足的日志
日志直接影响到度量及监视。你在寻找故障和排错时确定但愿获得更多的日志,可是在一个不间断运行的状况下,你一样会须要一些关键服务的日志。服务器系统日志、Apache及MySQL日志、缓存日志等,这些都须要被保存。而在日志太多时,你老是会减小一些地方的日志,或者裁剪及循环日志文件,从而丢弃旧的。