总结HAProxy各调度算法的实现方式及其应用场景

休言女子非英物,夜夜龙泉壁上鸣。这篇文章主要讲述总结HAProxy各调度算法的实现方式及其应用场景相关的知识,希望能为你提供帮助。
      HAProxy通过固定参数balance指明对后端服务器的调度算法,该参数可以配置在listen或backend选项中。HAProxy的调度算法分为静态和动态调度算法,但是有些算法可以根据参数在静态和动态算法中相互转换。
      在使用keepalived算法时,我们可以安装socat服务,它是Linux系统中的一个多功能的网络工具,主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式。利用socat,我们可以对服务器动态权重和其它状态进行调整。

    为了更直观的显示各类算法的效果,笔者这边准备另外准备了三台虚拟机,一台作为客户端,两台作为后端web服务器,并在主页显示各自ip。



  1. 静态算法
    在HAProxy中,静态算法会按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。
1.1  static-rr算法
      static-rr算法是基于权重的轮询调度,不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的wrr。
    笔者这边使用的子配置文件形式,同时将上一篇编译安装的子配置文件listen拆分成前端frontend和后端backend两部分,这样看起来更直观。前端frontend部分设置80端口监听在本机,当收到来自80端口的服务请求时就自动往后端backend集群上调度;后端backend添加对应的主机ip信息,并开启健康性检查,在后端web服务器前添加一行“balance static-rr”即视为使用了该算法。

    由于未进行其他设置,此时客户端访问haproxy服务器时,会按照1:1的比例向后端两台web服务器进行请求转发。

    此时在配置文件中设置两台web服务器的权重分别是1和2,再通过客户端访问时,已经按照1:2的比例去转发访问请求了。


1.2 first算法
    first算法根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少。first算法不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效。
    例如笔者在配置文件中使用first算法,由于是第一台服务器连接数达到上限,即达到全局设置中的10万连接数才会转发到第二台服务器,而客户端访问并发量通常不会达到这个数值,因此只会调度到第一台。


    此时将第一台的最大连接数改为1,客户端开两个窗口同时访问,可见右侧的访问已转发到10.0.0.157的服务器上。




  1. 动态算法
    动态算法可以基于后端服务器状态进行调度适当调整,新请求将优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。
2.1  roundrobin算法
      roundrobin算法是基于权重的轮询动态调度算法,支持权重的运行时调整,不同于lvs中的rr轮询模式,HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中最多支持4095个real server,支持对real server权重动态调整,roundrobin为默认调度算法,此算法使用广泛。
    例如笔者将算法改为roundrobin,因为默认的两台web服务器权重均未1,客户端测试时按照1:1的比例进行转发。


    此时可以用上socat软件了,因为socat在静态算法中不支持0和1(即只能让后端web服务下线或上线)之外的值,故没有在上述操作中演示。在动态算法中,我们可以利用socat来动态修改后端web服务器的权重等,例如笔者将10.0.0.156这台服务器的权重设为4,此时子配置文件中虽没变,但客户端测试时已经按照4:1的比例来进行请求转发。


2.2  leastconn算法
    leastconn算法属于加权的最少连接的动态算法,支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接),比较适合长连接的场景使用,比如:mysql等场景。
    例如笔者将算法改为leastconn算法,客户端开启四个窗口同时测试,因为默认的是1:1进行调度,所以两台后端web各接收了2次请求转发。


    此时利用socat将第一台web服务器的权重改为2,则客户端再去访问时,以前三个窗口显示的内容看效果,可见同一时刻websv1接收到的请求转发多一个(笔者使用的是免费版xshell,各位如果是付费版,可以多开几台看下是否是此效果)


2.3  random算法
      random算法是在HAProxy1.9版本后新加的负载平衡算法,其基于随机数作为一致性哈希的key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持权重的动态调整,权重较大的主机有更大概率获取新请求。
    笔者将算法改成random算法,此时客户端去访问时,没有一定的规律,是任意调度的。


?
  1. 其它算法
      其它算法既可作为静态算法,又可以通过选项成为动态算法。
3.1 source算法
    即源地址哈希算法,基于用户源地址哈希并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。使用source算法时,当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type支持的选项更改。
    这个算法一般是在不插入Cookie的TCP模式下使用,也可给拒绝会话cookie的客户提供最好的会话粘性,适用于session会话保持但不支持cookie和缓存的场景。源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是map-base取模法和一致性哈希。
3.1.1  map-base取模法
      map-base取模法可以对source地址进行哈希计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法。
      例如笔者使用该算法,此刻在不同的客户端访问,可能会被调度至不同的后端web服务器,但同一客户端第一次访问的是哪一台服务器,后面会继续被调度至该服务器。



3.1.2  一致性哈希算法
    使用一次性哈希算法时,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动,hash(o)mod n ,该哈希算法是动态的,支持使用socat等工具进行在线权重调整,支持慢启动。该方法的实现与之前nginx负载均衡调度中的一致性哈希算法相似,也是加入consistent参数。由于这里定义的是源地址一致性哈希,所以修改后,客户端访问的效果与上面取模法的结果相似。



3.2 uri算法
    uri算法是基于对用户请求的URI的左半部分或整个uri做哈希运算,再将哈希结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,适用于后端是缓存服务器场景,默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性哈希。要注意的是,此算法基于应用层,所以只支持mode http,不支持mode tcp。
    笔者以此算法,并定义使用一致性哈希算法来演示,它的效果与Nginx调度算法的中针对URI做一致性哈希算法效果相同。




3.3 url_param算法
    url_param算法对用户请求的url中的 params 部分中的一个参数key对应的value值作哈希计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server,如果无没key,将按roundrobin算法。
    例如笔者使用该算法,并将userid设为key,此时客户端测试时,将fang和xu作为value值,首次测试时可能会被调度到不同的服务器,但之后无论uri怎么改变,都会被调度到首次调度到的同一台服务器上,实现了会话绑定。


3.4 hdr算法
      hdr算法针对用户每个http头部(header)请求中的指定信息做哈希运算,此处由name指定的http首部将会被取出并做哈希计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
    例如我们希望根据客户端的浏览器来进行调度,可以在配置文件中添加“User-Agent”这一头部,客户端去访问时,如果来自同一浏览器会始终被调度至同一后端服务器;当客户端端使用的浏览器发生变动时,会重新计算并进行调度。


3.5  rdp-cookie算法
      rdp-cookie算法可以实现对windows远程桌面的负载均衡,使用cookie保持会话,默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。
    由于该算法的演示需要电脑支持远程桌面功能,而笔者的电脑是家庭版,故该算法部分无法进行演示。



  1. 应用场景
算法
应用场景
static-rr
做了session共享的web服务集群
first
很少使用
roundrobin
做了session共享的web服务集群
leastconn
数据库
random
做了session共享的web服务集群
source
客户端和服务器端的会话绑定
uri
适用于后端缓存服务器
url_param
客户端和服务器端的会话绑定
hdr
基于客户端请求报文头部做下一步处理
rdp-cookie
【总结HAProxy各调度算法的实现方式及其应用场景】基于Windows系统,很少使用

    推荐阅读