Haproxy负载均衡及其调度算法详解
四层和七层负载均衡的特点
-
四层负载均衡:即在OSI第4层工作,就是TCP层,可以根据IP+端口进行负载均衡。此种Load Balance不理解应用协议(如HTTP/FTP/MySQL等等)。支持IPv4协议和IPv6协议,是基于流的服务器负载均衡,对报文进行逐流分发,将同一条流的报文分发给同一个服务器。四层负载均衡对基于HTTP的7层业务无法做到按内容进行分发,限制了负载均衡业务的适用范围。依据转发方式,四层负载均衡分为NAT方式和DR方式。
所谓四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器 -
七层负载均衡:工作在OSI的最高层,应用层,可以基于Http协议和URL内容进行负载均衡。此时负载均衡能理解应用协议。七层负载均衡只支持IPv4协议,是基于内容的服务器负载均衡,对报文的承载内容进行深度解析,包括HTTP协议、RTSP协议等,根据其中的内容进行逐包分发,按既定策略将连接导向指定的服务器,实现了业务使用范围更广泛的服务器负载均衡。七层负载均衡仅支持NAT方式。
所谓七层负载均衡,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
Haproxy/nginx与LVS之间的对比
-
LVS特点:
1、抗负载能力强。抗负载能力强、性能高,能达到F5硬件的60%;对内存和cpu资源消耗比较低
2、工作在网络4层,通过vrrp协议转发(仅作分发之用),具体的流量由linux内核处理,因此没有流量的产生。
2、稳定性、可靠性好,自身有完美的热备方案;(如:LVS+Keepalived)
3、应用范围比较广,可以对所有应用做负载均衡;
4、不支持正则处理,不能做动静分离。
5、支持负载均衡算法:rr(轮循)、wrr(带权轮循)、lc(最小连接)、wlc(权重最小连接)
6、配置 复杂,对网络依赖比较大,稳定性很高。 -
HAProxy的特点是:
1、支持两种代理模式:TCP(四层)和HTTP(七层),支持虚拟主机;
2、能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作
3、支持url检测后端的服务器出问题的检测会有很好的帮助。
4、更多的负载均衡策略比如:动态加权轮循(Dynamic Round Robin),加权源地址哈希(Weighted Source Hash),加权URL哈希和加权参数哈希(Weighted Parameter Hash)已经实现
5、单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度。
6、HAProxy可以对Mysql进行负载均衡,对后端的DB节点进行检测和负载均衡。
9、支持负载均衡算法:Round-robin(轮循)、Weight-round-robin(带权轮循)、source(原地址保持)、RI(请求URL)、rdp-cookie(根据cookie)
10、不能做Web服务器即Cache。 -
Ngnix:
1、工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构;
2、Nginx对网络的依赖比较小,理论上能ping通就就能进行负载功能;
3、Nginx安装和配置比较简单,测试起来比较方便;
4、也可以承担高的负载压力且稳定,一般能支撑超过1万次的并发;
5、对后端服务器的健康检查,只支持通过端口来检测,不支持通过url来检测。
6、Nginx对请求的异步处理可以帮助节点服务器减轻负载;
7、Nginx仅能支持http、https和Email协议,这样就在适用范围较小。
8、不支持Session的直接保持,但能通过ip_hash来解决。、对Big request header的支持不是很好,
9、支持负载均衡算法:Round-robin(轮循)、Weight-round-robin(带权轮循)、Ip-hash(Ip哈希)
10、Nginx还能做Web服务器即Cache功能。 -
衡量负载均衡器好坏的几个重要因素:
1、会话率 :单位时间内的处理的请求数
2、会话并发能力:并发处理能力
3、数据率:处理数据能力
Haproxy常见的负载均衡调度算法及应用场景
balance <algorithm> [ <arguments> ]
Define the load balancing algorithm to be used in a backend.定义后端使用的负载平衡算法。
<algorithm>(算法):
-
roundrobin:动态算法,(加权)轮询;
权重可动态调整动态生效;根据权重轮流使用每个服务器,支持权重的运行时调整及慢启动机制,最大支持4095个后端主机;默认权重为1;其它使用hash调度方式的都支持动静两种方式;动态算法指的是服务器权重,可以在运行时调整,以实现实例的慢启动;所以可以加新server进来,而且可定义权重且可动态调整,不会瞬间调度大量请求,时逐渐调度请求上来的;服务器权重不同时就是加权轮询,相同时就是轮询; -
static-rr:静态加权轮询;
静态算法,不支持权重的运行时调整及慢启动机制;权重在服务器运行时改变了也不生效,除非重启服务器,而重启会导致此前所有连接断开,然后才重新调度的;但后端主机无数量上限;当服务器掉线时,健康状态检测又恢复上线时,立即加入服务器列表中取,且立即调度大量连接请求至此服务器,没有慢启动功能;而roundrobin则会慢慢调度请求至服务器; -
leastconn:加权最少连接;动态算法;
后端具有最少连接数的服务器将接收到请求,根据后端服务器当前连接的活动个数少来调度;
haproxy一般推荐使用在较长时间会话场景中;例如,LDAP,MySQL等协议;并不适用用短时间连接,不是特别适用指的是由于leastconn在计算调度权重时,还得扫描后端服务器当前会话数量,所以性能有影响,消耗cpu资源,但是带来的收益是很低的;
支持权重的动态改变,支持慢启动,属于wlc调度算法;对于短时间的连接不超过5秒钟,或2秒,一般建议使用roundrobin算法; -
first:根据服务器在列表中的位置,自上而下进行调度;前面的服务器连接数达到上限时,才将新请求调度至下一个服务器;这种算法好处在于可省服务器;要保证单台服务器支撑多个连接时没有问题,性能还支撑一个没有什么区别时会很有用;
每一个后端主机要定义最大并发连接数上限;在定义最大连接数时可以定义在三个位置:全局的最大并发连接数上限、每个frontend或listen的最大并发连接数上限、后端主机最大并发连接数上限; -
source:相当于nginx的ip-hash或lvs的sh算法,原地址哈希hash,默认为取模法;静态调度;类似于uri算法,指不过是哈希的源ip,而不是uri;
将来自于同一个地址的请求,始终发往同一台后端主机;- 取模法:将原地址哈希计算后除以服务器总权重最后取模;结果落在哪个节点上,就有哪个节点发往器响应;服务器总数发生变化,会话会全局失效,会影响全局调度效果;在分布式场景中是相当不靠谱,尤其后端是缓存服务器时;默认为静态的,但是可使用hash-type指令设定支持动态;
- 一致性哈希:服务器变得仅影响局部调度;动态调度;第一次调度时,基于取模法进行调度,一旦分配了服务器,后面再访问时将始终发往同一台服务器;通常用在tcp模式中;没有插入cookie时才会使用;如果协议支持cookie插入,就可以根据cookie进行调度,实现会话保持;
-
uri: 基于uri做hash计算
广泛用于后端服务器是缓存服务器场景中,保持缓存命中率;这样能保证同一个uri一直定向到同一个服务器上;但是,当后端服务器有掉线时,就意味着所有uri的哈希取模的结果都可能会改变,那么所有后端服务器的缓存就全失效了,这种取模法,随着服务器的增多或减少是影响全局的,要使用一致性哈希减少这个情况发生,但是,uri默认就是取模法,要使用hash-type设定为一致性哈希;
对uri的左半部分或整个uri做hash计算,然后将哈希结果除以服务器的总权重取模后,派发至挑选出的后端主机;作用在于能够将对于同一个uri的请求始终发往同一个后端服务器,适用于后端为缓存服务器的场景;hash方式也有两种方法:取模发和一致性哈希;取决于hash-type的指令定义;而且,使用hash-type指定一致性哈希算法后,还是动态的,支持慢启动,支持动态调整;
因为基于uri的格式会很长,所以,支持指定len只计算指定左半部分长度的uri;支持depth只计算指定左半部分路径深度的uri; -
url_param:基于url指定参数做hash计算
对用户请求的uri中的<params>中的参数的值做hash计算,并由服务器的总权重相除取模后派发至某挑选出的后端主机;此算法通常用于追踪请求中的用户标识,尤其是登录类的电商站点,以确保来自同一个用户的请求始终发往同一个后端服务器;支持动静两种方式, 使用hash-type指定;
在每一个HTTP GET的请求方法中去查询URL的参数,就是url中分号隔开的参数部分;
对参数的值进行哈希,且把哈希结果除以所以运行的服务器权重之和;
同一个用户的所有请求将始终被定向到同一个服务器上去(用户就靠param首部定义的值计算的);
常用于后端服务器基于basic用户认的证场景中;请求会加用户名等信息;此前认证过了,用户再刷新如果调度另一台服务器时,则不会再要求输入用户名、密码;
默认静态算法,同uri,后端服务器增加或减少影响全局,要使用hash-type设定一致性哈希算法;
如果uri没有参数或参数里没有值,则根据roundrobin算法进行调度; -
hdr(<name>):指定某一首部做hash计算
类似于nginx中的hash,可哈希请求报文中的任意首部,可以基于任意首部做调度;
对于每个http请求,通过name指定的http首部会被取出,此首部如果没有有效值,则轮询调度;否则,对其值做hash计算,并由服务器的总权重相除后派发至某挑选出的后端主机;此算法通常用于追踪请求中的用户标识,以确保来自同一个用户的请求始终发往同一个后端服务器;
hdr(Cookie), hdr(Host)
明确指明根据http请求中的某特定首部进行调度;首部写在括号中且不区分大小写;
如果http请求中没有首部或首部中没有值,则根据roundrobin算法进行调度;
默认也是静态调度,把首部的值进行哈希计算,再除以服务器权重之和;使用动态方法,要使用hash-type设定一致性哈希算法;
常用于首部信息基于host时,host指定了后端的虚拟主机,尤其基于名称的虚拟主机时;
而对于host首部上,有一个专用参数use_domain_only,因为host首部对应的一般是虚拟主机名,而不同的虚拟主机名可以为同一个服务器;例如:
hdr(host)
host:www.magedu.com
host:web.magedu.com
如果基于主机名哈希,哈希后结果不同,会定向都不同主机上,因此,为了避免这种情况,只计算hash域名即可;
允许使用use_domain_only:在计算hash值时,仅使用域名;
常用于hdr(host)实现将对同一个虚拟主机的访问始终定向至同一个后端服务器; -
rdp-cookie(<name>):基于rdp(远程桌面)协议的cookie做hash计算进行调度;作用在于能将同一个用户请求始终发往同一个远程桌面,但是基于请求中cookie进行计算的;
只要是同一个rdp-cookie的信息都会定向到同一个远端服务器;
hash-type:
hash-type <method> <function> <modifier>
<method>:
要使用的hash类型
- map-based:就是取模法;默认方法,是静态算法,不支持权重运行时调整及慢启动;
- consistent:就是一致性哈希算法,动态算法,支持权重运行时调整及慢启动;
<function>:
要使用的哈希函数
- sdbm
- djb2
- wt6
<modifier>:
- avalanche