7、Haproxy调度算法
Haproxy根据后端服务器的负载,或其他的计算的标准,判断挑选哪台RS来进行请求处理
Haproxy调度算法语法,可用于defaults、listen、backend
balance <algorithm|算法> [ <arguments> ]
balance url_param <param> [check_post [<max_wait>]]
7.1、roundrobin
roundrobin:基于权重进行轮询,保持均匀分布,这是最平衡、最公平的算法
此算法是动态的,这表示其权重可以在运行时进行调整,不过,在设计上,每个后端服务器仅能最多接受4128个连接
7.1.1、配置示例
cat /etc/haproxy/haproxy.cfg
frontend main
bind *:80
mode http
use_backend webcluster
backend webcluster
balance roundrobin
server web1 172.16.1.7:80 check
server web2 172.16.1.8:80 check
7.1.2、调度算法测试
curl -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node1
curl -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node2
7.1.3、动态调整
通过socat命令动态调整权重,将web1节点的权重调整为3
#查看当前权重
echo "get weight webcluster/web1" | socat stdio /var/lib/haproxy/stats #==> 1
echo "get weight webcluster/web2" | socat stdio /var/lib/haproxy/stats #==> 1
#调整web1权重为3,调整后测试,会发现立即生效
echo "set weight webcluster/web1 3" | socat stdio /var/lib/haproxy/stats
7.2、static-rr
static-rr:加权轮询调度算法,根据服务器的硬件情况、以及处理能力,为每台服务器分配不同的权值,使其能够接受相应权值的服务请求
此算法是静态的,这表示其权重不可以在运行时进行调整
7.2.1、配置示例
cat /etc/haproxy/haproxy.cfg
frontend main
bind *:80
mode http
use_backend webcluster
backend webcluster
balance static-rr
server web1 172.16.1.7:80 check weight 2
server web2 172.16.1.8:80 check weight 1
7.2.2、调度算法测试
curl -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node1
curl -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node1
curl -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node2
7.3、leastconn
leastconn:新的连接请求被派发至具有最少连接数目的后端服务器
此算法是动态的,可以在运行时调整其权重
7.3.1、配置示例
cat /etc/haproxy/haproxy.cfg
frontend main
bind *:80
mode http
use_backend webcluster
backend webcluster
balance leastconn
server web1 172.16.1.7:80 check
server web2 172.16.1.8:80 check
7.3.2、调度算法测试
7.4、source
source:源地址hash调度算法,将请求的源地址进行hash运算,得到一个具体的数值,同时对后端服务器进行编号,按照运行结果将请求分发到对应编号的服务器上
这可对不同源IP的访问进行负载分发,对同一个客户端IP的请求始终被派发至某特定的服务器
注意:如某服务器宕机或新添加了服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;不过也可以使用hash-type修改此特性
7.4.1、配置示例
cat /etc/haproxy/haproxy.cfg
frontend main
bind *:80
mode http
use_backend webcluster
backend webcluster
balance source
# hash-type { map-based | consistent }
server web1 172.16.1.7:80 check
server web2 172.16.1.8:80 check
7.4.2、调度算法测试
curl -HHost:proxy.qingchen.com http://10.0.0.5:80
7.5、uri
uri:基于对用户请求的uri做hash,并将请求转发到后端指定服务器
理解:同一个节点访问不同的uri可能会被调度到不同的后端服务器处理,但是不同的节点访问相同的uri则会被调度到同一台服务器处理
因为基于uri调度是在服务端完成的而非客户端,这种调度算法多用在缓存场景,能有效提高命中率
注意:此算法仅应用于HTTP后端服务器场景,其默认为静态算法,不过也可以使用hash-type修改此特性
7.5.1、页面准备
后端集群uri页面准备
#web1
mkdir /opt/{app1,app2} -p
echo "web1 app1" > /opt/app1/index.html
echo "web1 app2" > /opt/app2/index.html
#web2
mkdir /opt/{app1,app2} -p
echo "web2 app1" > /opt/app1/index.html
echo "web2 app2" > /opt/app2/index.html
7.5.2、配置示例
cat /etc/haproxy/haproxy.cfg
frontend main
bind *:80
mode http
use_backend webcluster
backend webcluster
balance uri
# hash-type { map-based | consistent }
server web1 172.16.1.7:80 check
server web2 172.16.1.8:80 check
7.5.3、调度算法测试
client测试,访问不同url测试,不同uri会被调度到不同的后端节点处理
7.6、url
url_param:对用户请求url中的<param>参数中的name作hash计算
通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个Backend Server(使用较少)
7.6.1、配置示例
url_param调度算法配置示例,(基于用户请求中携带的user做hash)
cat /etc/haproxy/haproxy.cfg
frontend main
bind *:80
mode http
use_backend webcluster
backend webcluster
balance url_param user
# hash-type { map-based | consistent }
server web1 172.16.1.7:80 check
server web2 172.16.1.8:80 check
7.6.2、调度算法测试
client测试,不带参数请求,默认为轮询调度
curl -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node1
curl -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node2
client测试,携带相同的User参数请求,会发现始终定向到同一台后端节点
curl http://10.0.0.5:80?user=qingchen12
7.7、hdr
hdr(<name>):针对用户发起HTTP请求中Header中的<name>关键字进行hash计算,假如无有效的值,则会被轮询调度
此算法默认为静态的,不过其yekeyi使用hash-type修改此特性(使用较少)
7.7.1、配置示例
hdr(<name>)调度算法配置示例(基于浏览器客户端来调度)
cat /etc/haproxy/haproxy.cfg
frontend main
bind *:80
mode http
use_backend webcluster
backend webcluster
balance hdr(User-Agent)
# hash-type { map-based | consistent }
server web1 172.16.1.7:80 check
server web2 172.16.1.8:80 check
7.7.2、调度算法测试
client测试,置空User-Agent字段,会发现进入了轮询
curl -A '' -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node1
curl -A '' -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node2
client测试,将User-Agent设置为具体浏览器,则指向同一个后端
curl -A 'Chrome' -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node1
curl -A 'Chrome' -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node1
curl -A 'Firefox' -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node2
curl -A 'Firefox' -HHost:proxy.qingchen.com http://10.0.0.5:80
Web Page RS-Node2
7.8、hash-type
hash-type <method>用于将hash映射至后端服务器的方法
可用方法有map-based|consistent
大多数场景下使用默认map-based方法
7.8.1、map-based
map-based算法实现公式:hash(ip) % node_counts = index
map-based算法问题:如果下线一台节点,会出现重新计算hash值,造成大规模变化
7.8.2、consistent
consistent:一致性哈希,该hash是动态的,当服务器节点下线,或新增一台节点,对调度结果影响是局部的,不会引起大的变动
一致性hash算法也是使用取模的方法,但不是对服务器节点数量进行取模,而是对2的32方取模,
即一致性hash算法将整个hash空间组织成一个虚拟的圆环,hash函数值的空间为0 ~ 2^32 - 1,整个哈希环如下:
一致性hash文档
一致性hash参考地址
hash算法原理
hash算法增加节点
hash算法减少节点
hash算法数据倾斜问题