负载均衡
负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据均匀分摊到多个操作单元上执行,负载均衡的关键在于均匀。
常见互联网分布式架构如上,分为客户端层、反向代理nginx层、站点层、服务层、数据层。
负载均衡要尽量避开以下问题:
1.有服务器崩溃不影响整体系统运行;
2.某几台服务器负荷很低,而另几台服务器负载很高、处理缓慢;
3.配置高的服务器分配到的请求少,而配置低的服务器分配到的请求多;
4.扩展性,直接加服务器,不影响现有运行
试用情况
什么情况下用负载均衡。我们需要对网站访问量有个准确的估值,并在此基础之上考虑需要几台集群,在哪些地方进行负载均衡。下面来介绍衡量服务器访问量的重要概念:
- PV(page view):页面浏览量,或点击量;通常是衡量一个网络新闻频道或网站甚至一条网络新闻的主要指标。同一人对相同页面的重复浏览在每天只计作一次。同一个人浏览你网站同一个页面,不重复计算pv量
- QPS(queries per second):单个进程每秒请求服务器的成功次数。用来考量服务系统一定时间内接收客户端请求的一个并发处理能力。
例如一小时总有效访问量为500w,QPS=500w/(60*60)≈1400QPS
如果是按天计算,一天按12小时计算即可。因为大部分请求都是发生在白天 - RPS(requests per second):对服务系统请求的响应能力,计算方法:并发数/平均响应时间
除了这些参数,还要考虑高峰期的访问量,服务器一定要承载住高峰期的访问量。以及对系统进行压力测试,分析访问量的瓶颈在系统的哪个部分。以此来确认集群每部分所需服务器数量以及选择何种负载均衡的策略。
哪些地方用负载均衡
DNS处负载均衡
大多数域名注册商都支持对统一主机添加多条A记录,这就是DNS轮询,DNS服务器将解析请求按照A记录的顺序,随机分配到不同的IP上,这样就完成了简单的负载均衡。
DNS由于成本较低,所以一般在小型的网站用的比较多。但是大型的网站一般也会将用它和其他负载均衡的方式结合起来一起使用
DNS轮询的优点:
零成本:只是在DNS服务器上绑定几个A记录,域名注册商一般都免费提供解析服务;
部署简单:就是在网络拓扑进行设备扩增,然后在DNS服务器上添加记录。
DNS轮询的缺点:
1、可靠性低
如果其中的一台服务器发生故障,那么所有的访问该服务器的请求将不会有所回应。即使从DNS中去掉该服务器的IP,但在Internet上,各地区电信、网通等宽带接入商将众多的DNS存放在缓存中,以节省访问时间,DNS记录全部生效需要几个小时,甚至更久。所以,尽管DNS轮询在一定程度上解决了负载均衡问题,但是却存在可靠性不高的缺点。
2、负载分配不均匀
DNS负载均衡采用的是简单的轮询算法,不能区分服务器的差异,不能反映服务器的当前运行状态,不能做到为性能较好的服务器多分配请求,甚至会出现客户请求集中在某一台服务器上的情况。
DNS服务器是按照一定的层次结构组织的,本地计算机或DNS服务器会缓存已解析的域名到IP地址的映射,这会导致使用该DNS服务器的用户在一段时间内访问的是同一台Web服务器,导致Web服务器间的负载不均匀。
站点接口处负载均衡
实现反向代理层到站点层的负载均衡,相比于在DNS实现负载均衡,自己搭建的负载均衡更有自主性,可以根据需求使用不同的负载均衡策略。常用的负载均衡策略如下:
1)请求轮询:和DNS轮询类似,请求依次路由到各个web-server
2)最少连接路由:哪个web-server的连接少,路由到哪个web-server
3)ip哈希:按照访问用户的ip哈希值来路由web-server,只要用户的ip分布是均匀的,请求理论上也是均匀的,ip哈希均衡方法可以做到,同一个用户的请求固定落到同一台web-server上,此策略适合有状态服务,例如session(可以这么做,但强烈不建议这么做,站点层无状态是分布式架构设计的基本原则之一,session最好放到数据层存储)
常用的负载均用工具有
1)nginx:一个高性能的web-server和实施反向代理的软件
2)lvs:Linux Virtual Server,使用集群技术,实现在linux操作系统层面的一个高性能、高可用、负载均衡服务器
3)keepalived:一款用来检测服务状态存活性的软件,常用来做高可用
4)f5:一个高性能、高可用、负载均衡的硬件设备(听上去和lvs功能差不多?)
ngnix是现在主流使用的,为了避免一台nginx挂掉导致系统不能访问,可以用keepalived+nginx做一个多机备份。如果ngnix访问不足以承载访问量,可以结合DNS轮训+ngnix访问的模式来扩展负载均衡能力,当然需要做到这种程度的负载均衡,基本上只有像阿里腾讯这种超大访问量的网站才需要。
服务接口处负载均衡
站点层到服务层的负载均衡,是通过“服务连接池”实现的。上游连接池会建立与下游服务多个连接,每次请求会“随机”选取连接来访问下游服务。一般是从RPC框架下手实现负载均衡。像是阿里的Dubbo就可以实现负载均衡
数据负载均衡
在数据量很大的情况下,由于数据层(db,cache)涉及数据的水平切分,所以数据层的负载均衡更为复杂一些,它分为“数据的均衡”,与“请求的均衡”。
数据的均衡是指:水平切分后的每个服务(db,cache),数据量是差不多的。
请求的均衡是指:水平切分后的每个服务(db,cache),请求量是差不多的。
一、按照range水平切分
user0服务,存储uid范围1-1kw
user1服务,存储uid范围1kw-2kw
这个方案的好处是:
(1)规则简单,service只需判断一下uid范围就能路由到对应的存储服务
(2)数据均衡性较好
(3)比较容易扩展,可以随时加一个uid[2kw,3kw]的数据服务
不足是:
(1)请求的负载不一定均衡,一般来说,新注册的用户会比老用户更活跃,大range的服务请求压力会更大
二、按照id哈希水平切分
user0服务,存储偶数uid数据
user1服务,存储奇数uid数据
这个方案的好处是:
(1)规则简单,service只需对uid进行hash能路由到对应的存储服务
(2)数据均衡性较好
(3)请求均匀性较好
不足是:
(1)不容易扩展,扩展一个数据服务,hash方法改变时候,可能需要进行数据迁移