读《大型网站技术架构》的一些总结-(3)伸缩性设计

3. 架构优化-伸缩性

伸缩大白话就是给网站增添服务器,强如谷歌创立之初也是一台服务器,而现在已经有百万级的服务器了。任何网站随着业务的变化服务器的数量也会跟着变化,往往是慢慢增长,当然也有因为脉冲网站并发量一段时间内猛增然后回归正常的如淘宝双十一,回归正常后则需要减少服务器实现根据需求对资源最大化利用。

3.1 网站整体的伸缩性设计

(1) 根据程序类型分离

网站最初往往是一台服务器上跑服务程序、跑数据库、跑缓存等,此时需要扩展服务器首先要考虑的就是将不同类型的程序拆出来部署到不同的物理机上。这样不仅分散了服务器的压力,还方便运维。

(2) 根据业务流程分离-纵向分离

如果网站业务量初有起色,就要考虑根据流程分离部署。一个业务首先是由前端页面发出请求,经由多个模块处理,最终反映到数据库。根据这一流程,将不同阶段的服务分离出来,让某一阶段的流程单独部署到服务器。如前后端分离。

(3) 根据功能模块分离-横向分离

如果网站业务量非常大,可以考虑将一些功能模块拆出来作为一个服务独立部署,这其实就是微服务模式。如淘宝的搜索功能、列表功能,这些单个页面的后端接口就可以作为一个服务,这样核心功能可以视情况搞成一个集群,做大集群规模,非核心功能集群规模则小一些,非常灵活。

(4) 单个功能通过集群实现伸缩

如果将一些功能模块拆分的很细了,而某个功能的服务的负载还是过大,此时则可以考虑在不同服务器上部署同一个服务,成为一个集群,通过负载均衡分散服务器的压力。数据库服务不同于后端程序等服务,数据库服务不像后端程序无状态可以同一个请求交给哪个服务器处理都一样,因为每个服务器的数据不同,是一定有状态的,集群技术与后端程序的集群技术有一些不同。

3.2 业务处理程序集群的伸缩性设计

最重要的是用何种手段实现负载均衡,以及决定一个请求落到哪台机器的具体算法。

(1) 负载均衡手段

  • http重定向:负载均衡服务器收到客户端发送的请求后,经过某种算法决定这个请求由哪个机器处理,则发送一个302的重定向状态码报文,让客户端再向真正的服务器发起请求。这种方法虽然简单,但是重定向会浪费不少性能集群的伸缩性规模有限,而且可能被搜索引擎判断为作弊,所以很少使用。
  • DNS域名解析:在域名解析服务器就进行负载均衡,同一个域名两次解析后得到的ip可能不一样,而是根据某种算法得来,这样效率很高。但是不够灵活,一是域名服务器的控制权在域名服务商那里,二是域名往往有多级缓存,当集群某机器下线后即使能及时修改DNS服务器相关配置,由于缓存的原因用户请求可能还会在一段时间内落到已经下线的服务器。一般,可以将DNS负载均衡作为第一级负载均衡,即DNS服务器不是最终决定请求要落在哪台服务器。
  • 反向代理:反向代理服务器就是靠在服务集群这一边的代理,是整个集群的入口,需要配置两块网卡一块公网地址供客户端访问,一块内网地址与集群服务器通信,根据某一算法转发用户请求到集群中的机器。虽然反向代理集负载均衡、保护集群、且部署简单等特点于一身,但是其本身是所有请求的中转站,可能会成为系统的性能瓶颈。
  • ip层:这种模式下,负载均衡服务器收到客户端数据报后直接在内核将目的ip地址修改为集群中某台机器的ip地址,无需到用户态所以速度很快。均衡服务器在修改目的ip时还把源ip改为自己的内网ip,这样集群处理完后响应数据报还发回均衡服务器,然后再把响应数据报的源ip改为自己的外网ip即可。虽然速度很快,但是整个集群的流量还是受制于负载均衡服务器这个流量出入口,不适合下载服务、视频服务集群。
  • 数据链路层(直接路由):因为这种技术将整个集群和负载均衡服务器都设置为同一个虚拟ip,所以可以直接修改链路层的MAC地址而不是ip地址就可以把数据报发到集群中的某台服务器,集群处理完毕后响应数据报直接就可以通过网关发给客户端,这都是因为ip自始至终没改变。这种方法流量需要通过负载均衡服务器进入集群,但是无需经过其出去,性能很好,广泛使用的LVS就是这种方法。

(2) 负载均衡算法
负载均衡算法是指具体决定请求落到哪一台服务器。

  • 轮询:将请求挨个落到各个服务器,适合服务器配置差不多的情况。
  • 加权轮询:按照权重提高一些服务器分配到请求的频数,适合服务器配置有差别的情况。
  • 随机:将请求随机落到一个服务器,大多数场景下简单实用,服务器配置有差别也可使用。
  • 最少连接:将请求发给当前连接最少的服务器,最能体现负载均衡思想。
  • 源地址散列:根据ip得到散列值,将请求落到对应的服务器,好处是一个客户总是落到同一台机器可以实现会话粘滞。
3.3 缓存、关系数据库的集群伸缩性

这些存储数据的服务程序是有状态的,因此一个请求必须落到特定的机器上而不是随便哪台都可以,还可以为一个服务设置一个从节点与其数据完全同步从而实现数据冗余和读写分离。所以数据类型的服务集群要实现额外几个功能:

(1) 数据落库策略

  • 哈希取余:数据的哈希值对数据库节点进行取模运算,决定落到哪个节点。但是数据迁移不方便。
  • 一致性哈希:将整个哈希值得域首尾相连看做一个环,数据库结点均匀的落在环上,数据哈希值落在环上任一点都顺时针找到对应得数据库结点。结点个数少时迁移后分布不均。
  • 虚拟结点的哈希:先将数据哈希运算分配到槽,再手动分配槽到数据库节点,每次迁移只需重新分配对应的槽。

(2) 路由算法:根据数据的落库策略将访问请求发到对应的机器。

(3) 数据迁移:集群发生伸缩时要将数据进行同步。

读《大型网站技术架构》的一些总结-(3)伸缩性设计

上一篇:php实现ajax请求的方法


下一篇:java.lang.IndexOutOfBoundException错误、通用Mapper插件 String index out of range: 0错误