【译】通俗讲解网站扩展

【译】通俗讲解网站扩展

译者注:本文译自 Arcentry 文章《Scaling webapps for newbs & non-techies》,点击此处查看原文

本文简要的介绍了网站如何从一台服务器到承受数百万用户的架构部署演化,主要为新入门开发者和非从业人员而写。

网站扩展

现在,假设你刚刚完成了你的网站,在线商店、社交 APP 或者别的什么,当项目上线时,感觉一切都好极了:每天有几百个用户访问你的网站,网站快速做出请求响应,一切都在有条不紊地进行着。

但是之后一件可怕的事情出现了:你的网站一夜爆红!

越来越多的用户开始涌向你的网站,每小时、每分钟、每秒钟成千上万的用户发来请求……这对老板来说,真是一个天大的好消息,但对基础运维来说,简直就是一场噩梦,因为现在,你需要做网站的扩展来承受洪水般的流量。这意味着你需要:

  • 同时处理更多的请求
  • 除了光纤被挖断,服务的高可用
  • 服务来自世界各地的用户

如何扩展

几年前,这样的问题会从水平扩展与垂直扩展的角度开始讨论。垂直扩展是指通过提升单机的处理能力来处理更多的请求,而水平扩展则是通过复制当前架构模型来提升处理能力。

今天,几乎没有人再使用垂直扩展,原因很简单:

  • 计算机的价格越来越昂贵,而性能提升却微乎其微
  • 单台服务器的性能存在天花板
  • 多核CPU也就是多个单核CPU的并行处理效率,那为什么不进行水平扩展呢?
    OK,我们选用水平扩展来提升网站,但又需要怎么做呢?

1. 单一服务器

这可能是你最初的架构。一台服务器既运行着业务,又存储着数据,简单又实用,但为了满足更高的要求,这种架构只能运行在性能更强的服务器上,这不是我们所希望的。

2. 增加反向代理

为了应付大流量,你第一步需要做的是增加反向代理。就像是酒店的前台,你可以让客人直接到他的客房,但事实上,你需要一位大堂经理,判断客人是否可以进入,是否已经提前预定好客房,如果客房已满,你应该友好地告知客人,而不是让客人自己挨个去查看。这个例子很好的解释了反向代理,反向代理通常只是接收与转发请求,然后这些请求在处理完成后从我们的服务器返回给用户。当用户向服务器发起请求时,这些请求需要路由到我们的服务器上,所以我们称之为“反向代理”。

反向代理的作用如下:

  • 可用性检查。确保我们的服务正常运行
  • 路由。转发请求到正确的处理终端
  • 鉴权。确保用户有权限访问服务
  • 防火墙。确保仅被授权的用户可以访问

3. 负载均衡

大多数的反向代理服务器还有一个作用:负载均衡。负载均衡是一个较为简单的概念:想象一下,有100个用户准备在限定的时间内进行支付,不幸的是,你的支付服务只能同时处理50笔交易,该怎么解决呢?你只需要同时运行两台支付服务就可以了。

负载均衡服务器现在需要将支付请求分流到两台服务器上,用户A的支付在S1上处理,用户B的支付在S2上处理,用户C的支付在S3上处理……

如果同时有500个用户发起支付请求该怎么办呢?没错!你只需将支付服务器扩展到10台来分发处理这些请求即可。

4. 增强数据库

负载均衡可以将用户的请求在多台服务器进行处理,但你注意到其中的问题了吗?我们可以扩展几十台、几百台甚至几千台服务器来处理请求,但所有的数据都储存在了同一个数据库中。

所以,我们可以用同样的办法来扩展数据库吗?答案是 No!这里涉及到了数据一致性的问题。我们需要保证系统所使用的数据是一致的,不一致的数据会导致一系列的问题,比如:同一个订单被多次处理,我们从一个100元的账户进行了两次扣款操作……那我们又该如何调整数据库来确保数据的一致性呢?

首先我们要做的就是将数据库功能拆分,一部分只负责接收与存储数据,其他部分只进行数据的检索。这种解决方案被称为主从复制或者读写分离。假设数据被读取的频率高于写入频率,我们可以将数据一处写入,多处读取(被读取的数据是写入数据的副本)。这里的缺点是我们只能在一处写入数据,这对于中小型网站来说没有问题,但不适用 Facebook 这样的网站,我们将在第9章进一步讨论如何扩展这样级别的数据库。

5. 微服务

Microservices

到现在为止,我们还是用一台服务器来处理所有的事情:处理支付、订单、库存查询、网站运行、管理账户等。

这或许不是件坏事——单一服务器意味着更低的复杂度、也更利于开发人员。但随着服务器的扩展,事情开始变得复杂与低效:

  • 不同服务器处理相同的事情——对每个登陆的用户而言,可能有几百个页面需要处理,但这些都是由同一个服务器完成的。
  • 开发团队随着业务扩张——随着越来越多的开发者在同一台服务器上工作,冲突也越来越多
  • 单一服务器意味着当我们想要完成新版本的迭代时,必须完成所有的工作。当一个团队想要快速发布更新时,由于依赖的另一个团队只完成了一半,导致了危险的相互依赖性。

微服务的出现很好的解决了这些问题。微服务的概念很简单——将你的服务以功能单元进行拆分,并进行独立部署。微服务具有以下优点:

  • 每个服务能都被独立扩展,让我们能更加灵活地调整以适应业务发展(译者注:比如邀请注册的网站限时开放注册,此时有大量的注册请求,我们可以扩展注册账户服务器的处理能力;当双十一进行大量支付处理时,我们可以扩展支付系统的处理能力,活动结束后,再将处理能力进行恢复,此为弹性扩容
  • 运维团队能够独立处理各功能单元,他们能负责微服务的整个生命周期(创建、部署、升级等)
  • 每个微服务可以使用所需资源。如第4章那样,需要数据库的扩展

6. 缓存与CDN

有什么比工作更高效的方法吗?(What’s better than working more efficiently?)答案是什么都不做!我们所使用的网站或APP由大量的静态资源所组成,如图片、JavaScript 和 CSS 文件,某些产品的预渲染登陆页等。相对于在每次请求时重新计算或者重新生成这些资源,我们使用“缓存”来加速响应并节约服务器资源——缓存记录最新的结果,并直接返回给再次请求的用户。

大型的缓存服务被称为CDN(Content Delivery Network,内容分发网络)——大量的缓存内容被存放在世界各地。CDN能让用户就近快速获取到所需资源,而不需要每次跨越千山万水到中央服务器获取。

7. 消息队列

Message Queues

你去过游乐场吗?是不是经常需要排队购票呢?地铁闸机口、银行柜台、游乐场售票处都是解释“子容量并行性”(sub-capacity parallelism)概念非常好的例子。没错,他们都是并行处理的:多个售票窗口同时售票,但他们又无法同时为每个人服务,因此,在每个窗口后开了排队。

同样的,在大型网站中。每分钟有成百上千的图片上传到 Instagram、Facebook,每张图片都需要被处理、裁剪、分析与打标签(译者注:如反恐扫黄系统),这是非常耗时的。所以,与其让用户等待图片上传完成及所有的处理过程,不如服务器在接收到图片后再做以下三件事:

  • 存储原始图片,不做任何处理
  • 向用户返回图片上传成功
  • 对待处理图片增加标识,指定待处理部分

其他服务通过检索待处理标识来逐一处理,直到完成所有待处理任务。管理这样任务的系统被称为“消息队列”。使用消息队列有很多好处:

  • 将任务与处理异步化。有时许多图片需要被处理,有时只有几张;有时有很多CPU资源可用,有时却只有部分CPU资源可用。通过将待处理任务堆积,而不是直接处理,我们可以确保我们的系统可用性,而且任务不会丢失。
  • 缓冲请求,扩展处理资源。当有大量用户上传图片时,我们需要时间来调拨更多的处理资源,如果没有消息队列,可能直接导致宕机。相反,有消息队列系统时,我们可以将请求添加到任务队列中,在处理资源到位后再进行处理,保证网站的可用性。

好了,现在我们的网站可以承受相当大的流量请求了,但如果我们想要承受更大的流量该怎么做?好吧,我们还需要做以下的一些工作:

8. 分片

什么是分片呢?“分片是一种通过将服务拆分为多个单元来并行处理的一种技术,每个单元只负责某些部分”(”Sharding is a technique of parallelizing an application’s stacks by separating them into multiple units, each responsible for a certain key or namespace”)

所以,到底什么是分片呢?分片其实是一个非常简单的概念:想要像 Facebook 那样服务20亿用户?将你的架构改造成类似于26个 mini 版的 Facebook,每个用户通过不同的英语字母表来区分。Aaron Abrahams?应该被A服务器处理;Zacharias Zuckerberg? 应该被Z服务器处理……

分片不仅仅基于字母,也可以基于数字或者其他规则,如位置、使用频率等。你可以分片你的服务器、数据库或者其他服务资源,这完全取决于你的业务需要。

译者注:分片技术,简而言之,就是将功能模块进行打包复制,类似于第3章的方案,提高并行处理能力。

9. DNS

到目前为止,你部署了单一的负载均衡服务器——即使你花费高昂的价格购买了性能更强劲的服务器,由于硬件的物理限制,仍然难以满足大量的请求。幸运的是,在世界范围内,分布着一个在流量到达我们服务器前非常稳定的负载均衡工具——DNS(Domain Name System,域名系统)。该系统能将域名”arcentry.com”映射到具体的网络地址(IP),如143.204.47.77,该系统也允许我们为同一个域名指定多个不同的IP,从而在不同的机器上处理相同请求。

非常感谢你能耐心看到这里,我希望这篇文章能对你有些用处。但是,如果你是IT从业人员,或许你在读了这篇文章后,又想到了一个困扰你很久的问题:什么是云服务?

云服务

云服务又是什么呢?已经2018年了,解决上述许多问题的最便宜和最有效的办法很明显:不用亲自解决!相反,由你的云服务提供商来为你扩展系统,而无需亲自处理这些问题,你只需关注自身业务。(译者注:据统计显示,目前中国有40%的网站在阿里云托管,最近的阿里云事故导致大量的企业受损,这对一些小型企业来说,是灭顶之灾,因此如果自身有能力,还是要掌控局面,毕竟数据无价,如果必须选择云服务商,在选择靠谱的服务商外,不要把鸡蛋放在一个篮子里

以我的网站为例,我不需要做以上扩展的任何事情(除了数据的读写分离),只需要将网站托管在AWS上,没有服务器,没有烦恼。

但云服务也不是银弹,它也有自身一些问题与权衡。请继续关注本系列的下篇文章,以了解有关“面向新手与非技术人员云服务”的更多信息。


个人总结:应对大规模流量的处理层级为:DNS ==> CDN缓存 ==> 负载均衡服务器 ==> 消息队列 ==> 容器集群 ==> 分片 ==> 数据库读写分离

因为热爱,所以执着。