网站伸缩性可以分为两类,一种是按功能进行物理分离实现伸缩性,一类是单一功能通过集群实现伸缩。
不同功能物理分离:数据库、缓存、静态资源、可复用服务等纵向分离以及登录、搜索等也逻辑对应的横向分离。
单一功能集群伸缩:通过集群增强服务器计算能力,但需要注意可用性。
具体来说,集群伸缩性又分为应用服务器集群伸缩性和数据服务器集群伸缩性。数据服务器集群伸缩性又分为缓存数据服务集群和存储数据服务器集群。
应用服务器集群伸缩性设计
应用服务器应该设计成无状态的,即应用服务器不存储请求上下文信息,集群中任意一台服务器对于相同请求结果应该相同。
如果Http请求分发装置能够感知或配置集群服务器数量,可以及时发现集群中新上线或下线的服务器,那么就实现了应用服务器集群的伸缩性。这个分发装置就被称作负载均衡服务器。而负载均衡技术主要有以下几种。
Http重定向负载均衡
利用http重定向协议实现负载均衡。用户访问网站被DNS解析到负载均衡服务器,然后通过计算得到并使用户访问另一台物理服务器。
这种方案有点事比较简单。缺少是浏览器完成访问需要两次请求服务器,性能较差,且负载服务器可能成为性能瓶颈。使用Http302响应码重定向,有可能时搜索引擎判断为SEO作弊,降低排名。
DNS域名解析负载均衡
在DNS上配置多个域名解析记录,当用户访问某域名时通过负载均衡算法计算一个不同的IP记录返回并访问。
该方案的优点是讲负载均衡工作转交DNS,省掉了网站管理维护负载均衡服务器的麻烦,同时DNS支持基于地理位置的域名解析,这样用户可以访问距离自己最近的服务器,改善了性能。但是DNS多级解析,每一台DNS都可能缓存解析记录,这样如果应用服务器状态发生变化,不能即时的反映到网站上去,造成网站不可访问等问题,另外DNS控制权在域名服务商那里,网站管理太局限。
大型网站总是部分使用DNS域名解析,利用域名解析作为第一级负载均衡,将域名解析到网站提供负载均衡的内部服务器在进行计算得到真实服务器地址。
反向代理负载均衡
利用反向代理服务器实现负载均衡。此时真实服务器不对外提供直接访问,反向代理服务器接收用户请求并返回从真实服务器中得到的数据。
由于反向服务器转发请求在Http协议层面,因此也被称为应用负载均衡。优点是集成反向代理与负载均衡,部署简单,缺点是所有请求和响应必须经过该服务器,其性能可能成为瓶颈。
IP负载均衡
在网络层通过修改请求目标地址进行负载均衡。
数据链路层负载均衡
在通信协议的数据链路层修改mac地址进行负载均衡。
这种方式又被称作三角传输模式,配置真实物理服务器集群所有机器的虚拟IP和负载均衡服务器IP地址一致,负载均衡数据分发过程中不修改IP地址,只修改MAC地址。这样由于实际请求的真实物理服务器IP和请求数据目的IP一致,则不通过负载均衡服务器进行地址转换就可将相依数据包返回给用户。这种负载均衡方式成为直接路由方式(DR)。
该方案是目前大型网站使用最广的一种手段,Linux上最好的相关开源技术是LVS(Linux Virtual Server)。
负载均衡算法
轮询(Round Robin, RR)
所有请求一次分发到每台服务器上,每台服务器请求数目相同。
加权轮询(Weighted Round Robin, WRR)
根据应用服务器性能,轮询基础上根据配置的权重分发请求。
随机(Random)
随机分发,也可以实现加权随机。
最少连接(Least Connection)
记录每台服务器上连接数,分发新请求到最少服务器,也可实现加权最少连接。
源地址散列(Source Hashing)
根据来源IP进行Hash计算,这样同一个IP地址可以在同一台服务器上请求,这样可以存储一些上下文信息。
分布式缓存集群的伸缩性设计
分布式缓存集群通过传入KEY值计算得到缓存服务器地址,从而进行读取或者写入。
余数Hash是一种计算服务器地址的路由算法,但是余数Hash对于集群扩容支持太差。只能在网站访问量小时扩容并预热缓存备份数据,这需要业务场景合适并且技术团队辛苦加班(半夜访问量小)。
**一致性Hash算法
**是广泛应用的一种Hash算法。
详见五分钟理解一致性哈希算法(consistent hashing)
数据存储服务器的伸缩性设计
数据存储服务器必须保证数据的可靠存储,任何情况下都必须保证数据的可用性和正确性。
关系型数据库的伸缩性
数据库主从读写分离,写操作在主服务器上进行,并有主服务器同步到从服务器,读操作和数据分析等在从服务器上进行。
除了读写分离也可以按照业务分离,即数据分库。这种方式制约条件是跨库的表不能进行Join操作。
对于一些超大型的数据库还需要进行 **数据分片
**,拆分一张表到多个数据库中。
目前比较成熟的支持数据分片和分布式关系型数据库产品主要有Cobar和Amoeba。
阿里开源分布式数据库中间件Cobar
基于阿里开源的Cobar的数据库分库分表中间件
MySQL Cluster与MongoDB复制群集分片设计及原理
数据库水平切分的实现原理解析