一分钟了解负载均衡的一切

1. 什么是负载均衡

        负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据【均匀】分摊到多个操作单元上执行,负载均衡的关键在于【均匀】。

2. 常见的负载均衡方案

一分钟了解负载均衡的一切_第1张图片
        常见互联网分布式架构如上,分为客户端层、反向代理nginx层、站点层、服务层、数据层。可以看到,每一个下游都有多个上游调用,只需要做到,每一个上游都均匀访问每一个下游,就能实现“将请求/数据【均匀】分摊到多个操作单元上执行”。

2.1【客户端层->反向代理层】的负载均衡

一分钟了解负载均衡的一切_第2张图片
【客户端层】到【反向代理层】的负载均衡,是通过“DNS轮询”实现的:DNS-server对于一个域名配置了多个解析ip,每次DNS解析请求来访问DNS-server,会轮询返回这些ip,保证每个ip的解析概率是相同的。这些ip就是nginx的外网ip,以做到每台nginx的请求分配也是均衡的。

2.2【反向代理层->站点层】的负载均衡

一分钟了解负载均衡的一切_第3张图片
【反向代理层】到【站点层】的负载均衡,是通过“nginx”实现的。通过修改nginx.conf,可以实现多种负载均衡策略:

1)请求轮询:和DNS轮询类似,请求依次路由到各个web-server;

2)最少连接路由:哪个web-server的连接少,路由到哪个web-server;

3)ip哈希:按照访问用户的ip哈希值来路由web-server,只要用户的ip分布是均匀的,请求理论上也是均匀的,ip哈希均衡方法可以做到,同一个用户的请求固定落到同一台web-server上,此策略适合有状态服务,例如session(可以这么做,但强烈不建议这么做,站点层无状态是分布式架构设计的基本原则之一,session最好放到数据层存储)。

2.3【站点层->服务层】的负载均衡

一分钟了解负载均衡的一切_第4张图片
【站点层】到【服务层】的负载均衡,是通过“服务连接池”实现的。

上游连接池会建立与下游服务多个连接,每次请求会“随机”选取连接来访问下游服务。

上一篇文章《RPC-client实现细节》中有详细的负载均衡、故障转移、超时处理的细节描述,欢迎点击link查阅,此处不再展开。

2.4【数据层】的负载均衡

在数据量很大的情况下,由于数据层(db,cache)涉及数据的水平切分,所以数据层的负载均衡更为复杂一些,它分为“数据的均衡”,与“请求的均衡”。

数据的均衡是指:水平切分后的每个服务(db,cache),数据量是差不多的。

请求的均衡是指:水平切分后的每个服务(db,cache),请求量是差不多的。

业内常见的水平切分方式有这么几种:

1)按照range水平切分

一分钟了解负载均衡的一切_第5张图片
每一个数据服务,存储一定范围的数据,上图为例:

user0服务,存储uid范围1-1kw

user1服务,存储uid范围1kw-2kw

这个方案的好处是:

(1)规则简单,service只需判断一下uid范围就能路由到对应的存储服务;

(2)数据均衡性较好;

(3)比较容易扩展,可以随时加一个uid[2kw,3kw]的数据服务;

不足是:

(1)请求的负载不一定均衡,一般来说,新注册的用户会比老用户更活跃,大range的服务请求压力会更大;

2)按照id哈希水平切分

一分钟了解负载均衡的一切_第6张图片
每一个数据服务,存储某个key值hash后的部分数据,上图为例:

user0服务,存储偶数uid数据;

user1服务,存储奇数uid数据;

这个方案的好处是:

(1)规则简单,service只需对uid进行hash能路由到对应的存储服务;

(2)数据均衡性较好;

(3)请求均匀性较好。

不足是:

(1)不容易扩展,扩展一个数据服务,hash方法改变时候,可能需要进行数据迁移

3. 负载均衡常用算法

3.1 轮询法(Round Robin)

        轮询法基本上算是最简单的负载均衡算法了,它的思想就是不管啥情况,对所有的服务器节点全部按顺序来,将请求按照顺序轮流地分配到各个服务器上。这种算法会使每台服务器处理的请求是相同的,所以适合用于服务器硬件条件基本都相同的场景。

3.2 加权轮询法(Weight Robin)

        在轮询算法的基础上添加了权重的条件,刚才提到轮询算法对所有服务器“一视同仁”,那么加权轮询算法无疑就是对各个服务器有了“高低贵贱之分”,没办法,服务器的处理水平不同,只能是让那些强悍的机器优先并多处理些请求,比较弱的机器嘛就让它稍稍压力小一点。

3.3 随机法(Random)

        随机算法也是一种适用场景比较多的负载均衡算法,这种算法基本思想也很简单,随机生成一个数字(或者随机挑一个IP地址)出来,然后挑到谁就去谁家,当然,如果随机数是等概况生成的,那时间长了,基本上跟轮询算法也没啥区别了,当然区别最主要的还是在顺序,随机么就没那么严格的顺序了。

3.4 加权随机法(Weight Random)

        加权随机法是在随机法的基础上加了加权的条件,随机法时间长了,基本上跟一般轮询算法就没啥区别了,刚才也提到了,如果服务器的配置都差不多,那也就算了,但是如果服务器处理能力差异比较大,那水平高的和水平低的服务器都给这么多任务,那对于高配置来讲就有点浪费,对于低配置的服务器来讲却有点吃不消,所以在这种配置差异性比较大的情况下,加权的工作还是十分必要的。加权随机算法就是适用于这样的场景。

3.5 最小连接法(Least Connections)

         这个算法思想也很简单,顾名思义,哪个服务器的连接少,就分配给哪个服务器新的请求,合情合理,但是这种算法的缺点就是,跟我们上面分析的几种算法一个意思,一个比较弱的服务器和一个比较彪悍的服务器,本来就是前者连接要少,后者要大,如果非得谁的少新请求给谁,那就是弱服务器的连接要等于强服务器的连接,无疑这样会让弱服务器吃不消,或者让强服务器造成资源浪费,所以在这里依然可以用加权的方法来解决这个问题——加权最小连接法。

3.6 最快响应时间(Fast Reponse time)

        新的连接传递给那些响应最快的服务器。当其中某个服务器发生故障,AX就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。

3.7 源地址哈希法(Hash)

        Hash法对于大部分码农来讲并不陌生,当年《数据机构》课程上这一节依然能够栩栩如生地浮现在脑海中。源地址哈希法就是可以把客户端的IP地址拿出来,然后计算出IP地址的hash值,hash值是一个很大的正整数,那么问题来了,怎么才能映射到相对应的服务器了,答案很简单:serverPosition=hashCode%serverListSize。

3.8 基于策略的负载均衡

针对不同的数据流设置导向规则,用户可自行编辑流量分配策略,利用这些策略对通过的数据流实施导向控制。

3.9 基于数据包的内容分发

例如判断HTTP的URL,如果URL中带有.jpg的扩展名,就把数据包转发到指定的服务器。

4. 总结

        负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据【均匀】分摊到多个操作单元上执行,负载均衡的关键在于【均匀】。

(1)【客户端层】到【反向代理层】的负载均衡,是通过“DNS轮询”实现的

(2)【反向代理层】到【站点层】的负载均衡,是通过“nginx”实现的

(3)【站点层】到【服务层】的负载均衡,是通过“服务连接池”实现的

(4)【数据层】的负载均衡,要考虑“数据的均衡”与“请求的均衡”两个点,常见的方式有“按照范围水平切分”与“hash水平切分

--------------------

参考:微信公众号《架构师之路》、《负载均衡常见架构》、《服务器负载均衡的基本功能和实现原理》

你可能感兴趣的:(架构,负载均衡,运维)