dubbo负载均衡算法及源码解析

dubbo负载均衡算法及源码解析

dubbo中的负载均衡策略有四种如下:随机(Random)、轮询(RoundRobin)、最少活跃调用数(LeastActive)、一致性Hash(ConsistentHash),缺省配置默认为 Random 随机负载均衡策略

一、一致性Hash负载均衡算法介绍及源码实现解析(ConsistentHash LoadBalance)
1.一致性Hash算法介绍
  1. 虚拟圆环:一致性哈希将整个哈希值空间组织成一个虚拟的圆环。如假设某哈希函数的值空间为0~2^32 -1(即:哈希值为一个32位无符号整形),
    整个空间按照顺时针方向组织,0和2^32 -1在零点出重合。
  2. 映射服务器到虚拟圆环(虚拟)节点:将所有服务器使用指定Hash函数计算Hash值,并且映射到虚拟圆环的对应位置,即:服务对应的节点;
  3. 定位数据访问的服务器:将数据key使用相同的Hash函数计算出Hash值,并确定此数据在Hash环上的位置,从此位置沿环顺时针寻找到的第一个服务器
    节点,即为当前数据key要访问的服务器。
  4. 服务器使用虚拟节点的目的:可以保证在服务器数量变动的情况下,仍然使得资源能够均匀分布(即:负载均衡)。
  5. KETAMA_HASH算法的好处:解决Hash值分布不均的问题。
  6. 经常使用TreeMap来表示Hash环的原因:用TreeMap的时间复杂度是O(logN),相对效率比较高,且TreeMap使用了红黑树结构存储实体对象。
2.一致性Hash解决的问题
  1. 一致性哈希算法常用于负载均衡中要求资源被均匀的分布到所有节点上,并且对资源的请求能快速路由到对应的节点上.
  2. 相比普通的哈希算法采用简单取模的方式,将缓存服务器进行散列;一致性哈希算法能有效降低服务器个数变化对整体缓存的影响。
  3. MemCache集群,要求存储各种数据均匀的存到集群中的各个节点上,访问这些数据时能快速的路由到集群中对应存放该数据的节点上;
    并且要求增删集群中节点对整个集群的影响很小,不至于有大的动荡造成整体负载的不稳定;
  4. RPC过程中服务提供者做N个节点的集群部署,为了能在服务上维护一些业务状态,希望同一种请求每次都落到同一台服务上。
3.dubbo使用一致性Hash算法的特点
  1. 一致性Hash负载均衡算法,相同参数的请求总是发送到同一个服务提供者(在服务提供者列表不变的前提下)
  2. 当某一台提供者挂掉时,原本发往该提供者的请求,将基于虚拟节点,平摊到其他的提供者,不会引起剧烈变动。
  3. 默认情况下,一致性Hash会使用 160个虚拟节点 构造一致性Hash环,并且只使用对应 方法第一个参数 的Hash值作为
    key去Hash环上获取对应的服务提供者对象(Invoker),改变默认配置方式如下:<dubbo:parameter key="hash.arguments" value="0,1" />
    <dubbo:parameter key="hash.nodes" value="320" />
4.算法重点源码解析(ConsistentHashLoadBalance类
  1. ConcurrentMap<String, ConsistentHashSelector<?>> selectors 用于存储每个 请求url(由dubbo配置中的interface+group+versi
    on+methodName组装而成)与 一致性Hash对象ConsistentHashSelector<T>(由服务提供者列表,相当于服务器列表构造而成)的Map映射(一致性
    Hash对象的构成具体见2)
  2. 构造一致性Hash环时的重要属性:TreeMap<Long, Invoker<T>> virtualInvokers 用于存储一致性Hash对象环上的虚拟节点,每个节点存储
    提供者url的Hash值服务提供者对象(Invoker)的对应关系
  3. 获取服务提供者步骤:1、通过请求url获取对应的一致性Hash对象;2、通过请求参数的Hash值在一致性hash环上面查找对应的虚拟节点,获取服务提
    供者;此处利用了TreeMap.tailMap(key)返回 其键大于或等于 fromKey 的Map集合的特性。
  4. 算法的具体实现以及源码完整注解见ConsistentHashLoadBalance类
二 、最少活跃调用数负载均衡策略(LeastActive LoadBalance)
1. 算法描述
  • 最少活跃调⽤数,相同活跃数(调用数最小且相同)的随机分配,活跃数指调⽤前后计数差。
  • 使慢的提供者收到更少请求,因为越慢的提供者正在处理的服务数会累积变大,使用该算法可以使其分配到较少的请求。
2.算法重点源码解析 LeastActiveLoadBalance类
  1. int active = RpcStatus.getStatus(invoker.getUrl(),invocation.getMethodName()).getActive(); // 活跃数 获取当前服务提供者url+method对应的active数量。 RpcStatus 通过一个ConcurrentMap<String, ConcurrentMap<String, RpcStatus>> METHOD_STATISTICS 记录所有的服务提供者每个服务(用url+mothod 标识)的的RpcStatus,其中包括active(活跃数)、total(处理请求的总数)、failed(请求失败数量)、以及各种情况的服务处理时间。
  2. dubbo是如何记录服务提供者各个服务url的active数量呢?
    • 通过Filter(ActiveLimitFilter(对应消费者)和ExecuteLimitFilter(对应提供者))对active进行更新新操作,当某个provider某个服务被分配到请求,这两个Filter都会在服务提供者处理请求之前将 avtive 属性进行加一操作,并且在请求处理完成或者异常时将avtive属性进行减一操作。
三 、轮询负载均衡策略(RoundRobin LoadBalance)
1. 算法描述
  • 轮循,按公约后的权重设置轮循⽐率。
  • 存在慢的提供者累积请求的问题,⽐如:第⼆台机器很慢,但没挂,当请求调到第⼆台时就卡在那,久⽽久之,所
    有请求都卡在调到第⼆台上。
四、随机负载均衡策略(Random LoadBalance)
1. 算法描述
  • 随机,按权重设置随机概率。
  • 在⼀个截⾯上碰撞的概率⾼,但调⽤量越⼤分布越均匀,⽽且按概率使⽤权重后也⽐较均匀,有利于动态调整提供
    者权重。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值