负载均衡分类及算法

负载均衡分类及算法
概述
随着系统⽇益庞⼤、逻辑业务越来越复杂,系统架构由原来的单⼀系统到垂直系统,发展到现在的分布式系统。分布式系统中,可以做到公共业务模块的⾼可⽤,⾼容错性,⾼扩展性,然⽽,当系统越来越复杂时,需要考虑的东西⾃然也越来越多,要求也越来越⾼,⽐如服务路由、负载均衡等
⽬的
负载均衡的⽬的就是通过调度集,达到最佳化资源使⽤,最⼤化吞吐率,最⼩化响应时间,避免单点过载的问题。
分类
主要分为 DNS负载均衡 和 ⼆、三、四、七层负载均衡 。
DNS负载均衡
这种是属于较早出现的技术,其利⽤域名解析实现负载均衡,在DNS服务器配置多个A记录,这些A记录对应的服务器构成集互相减轻服务压⼒。⼤型⽹站总是部分使⽤DNS解析,作为第⼀级负载均衡
⼆、三、四、七层负载均衡
是以ISO模型为准,从下到上分为:物理层,数据链路层,⽹络层,传输层,会话层,表⽰层,应⽤层,这⾥其实正好符合tcp/ip的分界。* ⼆层负载均衡(MAC)
⼆层负债均衡是基于数据链路层的负债均衡,即让负债均衡服务器和业务服务器绑定同⼀个虚拟IP(即VIP),客户端直接通过这个VIP进⾏请求,那么如何区分相同IP下的不同机器呢?没错,通过MAC物理地址,每台机器的MAC物理地址都不⼀样,当负载均衡服务器接收到请求之后,通过改写HTTP报⽂中以太⽹⾸部的MAC地址,按照某种算法将请求转发到⽬标机器上,实现负载均衡。
这种⽅式负载⽅式虽然控制粒度⽐较粗,但是优点是负载均衡服务器的压⼒会⽐较⼩,负载均衡服务器只负责请求的进⼊,不负责请求的响应(响应是有后端业务服务器直接响应给客户端),吞吐量会⽐较⾼。
* 三层负载均衡(IP)
三层负载均衡是基于⽹络层的负载均衡,通俗的说就是按照不同机器不同IP地址进⾏转发请求到不同的机器上。
这种⽅式虽然⽐⼆层负载多了⼀层,但从控制的颗粒度上看,并没有⽐⼆层负载均衡更有优势,并且,由于请求的进出都要经过负载均衡服务器,会对其造成⽐较⼤的压⼒,性能也⽐⼆层负载均衡要差。
* 四层负载均衡(TCP)
本地导航四层负载均衡是基于传输层的负载均衡,传输层的代表协议就是TCP/UDP协议,除了包含IP之外,还有区分了端⼝号,通俗的说就是基于IP+端⼝号进⾏请求的转发。相对于上⾯两种,控制⼒度缩⼩到了端⼝,可以针对同⼀机器上的不⽤服务进⾏负载。
这⼀层以LVS为代表。
* 七层负载均衡(HTTP)
七层负载均衡是基于应⽤层的负载均衡,应⽤层的代表协议有HTTP,DNS等,可以根据请求的url进
⾏转发负载,⽐起四层负载,会更加的灵活,所控制到的粒度也是最细的,使得整个⽹络更"智能化"。例如访问⼀个⽹站的⽤户流量,可以通过七层的⽅式,将对图⽚类的请求转发到特定的图⽚服务器并可以使⽤缓存技术;将对⽂字类的请求可以转发到特定的⽂字服务器并可以使⽤压缩技术。可以说功能是⾮常强⼤的负载。
这⼀层以Nginx为代表。
> 分类总结:
在普通的应⽤架构中,使⽤Nginx完全可以满⾜需求,对于⼀些⼤型应⽤,⼀般会采⽤DNS+LVS+Nginx的⽅式进⾏多层次负债均衡,以上这些说明都是基于软件层⾯的负载均衡,在⼀些超⼤型的应⽤中,还会在前⾯多加⼀层物理负载均衡,⽐如知名的F5
负载均衡算法
⼀般分为静态负载均衡和动态负载均衡
静态负载均衡
1. 轮询法
将请求按顺序轮流地分配到每个节点上,不关⼼每个节点实际的连接数和当前的系统负载。
优点:简单⾼效,易于⽔平扩展,每个节点满⾜字⾯意义上的均衡;
缺点:没有考虑机器的性能问题,根据⽊桶最短⽊板理论,集性能瓶颈更多的会受性能差的服务器影响。
public class RoundRobin {
private static Map<String, Integer> serviceWeightMap =new ConcurrentHashMap<>();
static{
serviceWeightMap.put("192.168.1.100",1);
serviceWeightMap.put("192.168.1.101",1);
serviceWeightMap.put("192.168.1.102",4);
serviceWeightMap.put("192.168.1.103",1);
serviceWeightMap.put("192.168.1.104",1);
serviceWeightMap.put("192.168.1.105",3);
火花塞中心电极
serviceWeightMap.put("192.168.1.106",1);
serviceWeightMap.put("192.168.1.107",2);
serviceWeightMap.put("192.168.1.108",1);
serviceWeightMap.put("192.168.1.109",1);
serviceWeightMap.put("192.168.1.110",1);
}
private static Integer pos =0;
public static String testRoundRobin(){
Set<String> keySet = serviceWeightMap.keySet();
ArrayList<String> keyList =new ArrayList<String>();//为了保证线程安全,做⼀个类似快照的东西
按钮指示灯
keyList.addAll(keySet);
String server = null;
synchronized(pos){
if(pos > keySet.size()){
pos =0;
}
server = (pos);
pos++;
}
return server;
}
}
2. 随机法
将请求随机分配到各个节点。由概率统计理论得知,随着客户端调⽤服务端的次数增多,其实际效果越来越接近于平均分配,也就是轮询的结果。
优缺点和轮询相似。
public static String testRandom(){
Set<String> keySet = serviceWeightMap.keySet();
重金属快速检测ArrayList<String> keyList =new ArrayList<String>();
keyList.addAll(keySet);
Random random =new Random();
int randomPos = Int(keyList.size());
String server = (randomPos);
return server;
}
3. 源地址哈希法
源地址哈希的思想是根据客户端的IP地址,通过哈希函数计算得到⼀个数值,⽤该数值对服务器节点数进⾏取模,得到的结果便是要访问节点序号。采⽤源地址哈希法进⾏负载均衡,同⼀IP地址的客户端,当后端服务器列表不变时,它每次都会落到到同⼀台服务器进⾏访问。
优点:相同的IP每次落在同⼀个节点,可以⼈为⼲预客户端请求⽅向,例如灰度发布;
缺点:如果某个节点出现故障,会导致这个节点上的客户端⽆法使⽤,⽆法保证⾼可⽤。当某⼀⽤户成为热点⽤户,那么会有巨⼤的流量涌向这个节点,导致冷热分布不均衡,⽆法有效利⽤起集的性能。所以当热点事件出现时,⼀般会将源地址哈希法切换成轮询法。
public static String testConsumerHash(String remoteIp){
Set<String> keySet = serviceWeightMap.keySet();
ArrayList<String> keyList =new ArrayList<String>();
keyList.addAll(keySet);
int hashCode = remoteIp.hashCode();确定取消
int pos = hashCode % keyList.size();
(pos);
}
4. 加权轮询法
不同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能⼒也不相同。给配置⾼、负载低的机器配置更⾼的权重,让其处理更多的请;⽽配置低、负载⾼的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这⼀问题,并将请求顺序且按照权重分配到后端。
加权轮询算法要⽣成⼀个服务器序列,该序列中包含n个服务器。n是所有服务器的权重之和。在该序列中,每个服务器的出现的次数,等于其权重值。并且,⽣成的序列中,服务器的分布应该尽可能的均匀。⽐如序列{a, a, a, a, a, b, c}中,前五个请求都会分配给服务器a,这就是⼀种不均匀的分配⽅法,更好的序列应该是:{a, a, b, a, c, a, a}。
优点:可以将不同机器的性能问题纳⼊到考量范围,集性能最优最⼤化;
缺点:⽣产环境复杂多变,服务器抗压能⼒也⽆法精确估算,静态算法导致⽆法实时动态调整节点权重,只能粗糙优化。
public static String testWeightRoundRobin(){
Set<String> keySet = serviceWeightMap.keySet();
Iterator<String> it = keySet.iterator();
榄香烯乳状注射液List<String> serverList =new ArrayList<String>();
while(it.hasNext()){
String server = it.next();
Integer weight = (server);
for(int i=0; i<weight; i++){
serverList.add(server);
}
Collections.shuffle(serverList);
}
String server = null;
synchronized(pos){
if(pos > serverList.size()){
pos =0;
}
server = (pos);
pos++;
}
return server;
}
5. 加权随机法
与加权轮询法⼀样,加权随机法也根据后端机器的配置,系统的负载分配不同的权重。不同的是,它是按照权重随机请求后端服务器,⽽⾮顺序。
public static String testWeightRandom(){
Set<String> keySet = serviceWeightMap.keySet();
List<String> serverList =new ArrayList<String>();
Iterator<String> it = keySet.iterator();
while(it.hasNext()){
String server = it.next();
Integer weight = (server);
for(int i=0; i<weight; i++){
serverList.add(server);
}
}
Random random =new Random();
int randomPos = Int(serverList.size());
String server = (randomPos);
return server;
}
动态负载均衡
1. 最⼩连接数法
根据每个节点当前的连接情况,动态地选取其中当前积压连接数最少的⼀个节点处理当前请求,尽可能地提⾼后端服务的利⽤效率,将请求合理地分流到每⼀台服务器。俗称闲的⼈不能闲着,⼤家⼀起动起来。
优点:动态,根据节点状况实时变化;
缺点:提⾼了复杂度,每次连接断开需要进⾏计数;
实现:将连接数的倒数当权重值。
2. 最快响应速度法
根据请求的响应时间,来动态调整每个节点的权重,将响应速度快的服务节点分配更多的请求,响应 速度慢的服务节点分配更少的请求,俗称能者多劳,扶贫救弱。
优点:动态,实时变化,控制的粒度更细,跟灵敏;
缺点:复杂度更⾼,每次需要计算请求的响应速度;
实现:可以根据响应时间进⾏打分,计算权重。
3. 观察模式法
观察者模式是综合了最⼩连接数和最快响应度,同时考量这两个指标数,进⾏⼀个权重的分配。

本文发布于:2024-09-21 22:16:47,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/161425.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:负载   服务器   节点   请求
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议