原文:提升20%!京东广告模型系统负载均衡揭秘

背景

  1. 集群内负载不均衡(异质化节点),整体资源利用率低;
  2. 单节点过载容易触发集群整体扩容;
  3. 节点偶发硬件(CPU、网卡、内存等)异常,影响业务服务整体可用率;
  4. 大促等分布多变的线上流量容易导致集群服务稳定性问题;

服务可用率+资源利用率 联合LB策略

  将集群所有节点分为:“负反馈列表(refuse list)”和“正反馈列表(accept list)”,前者减少分流比例,后者增加分流比例,通过均衡度决定; 计算服务可用率

  1. 统计当前周期内集群所有节点处理请求的成功数和失败数,以此计算出单个服务节点的平均可用率;
  2. 通过单节点的平均可用率,计算出集群的平均可用率;
  3. 基于各个节点的平均可用率集群平均可用率的差异,计算出各服务节点的均衡度;如满足均衡目标,则计算CPU的利用率,否则选择下一个节点进入计算的新周期;

    注:文章没说如何判断满足均衡目标,猜测是可用率落在一个中间范围时即为满足,过低则采用减少分流比例策略;

服务可用率主动防护

  1. 选择可用率高于集群可用率的节点;
  2. 将这部分节点各自的请求RPC状态,维护在双端队列的固定窗口内(即请求的成功与否),并实时更新集群平均可用率;
  3. 通过周期性统计集群历史平均成功率,判断其变化趋势,若向下则触发防护降级,向上则逐渐恢复降级防护;

资源利用率渐进式收敛

  1. 初始化所有节点为 refuse list,将 ratio(节点的分流策略的调整比例) 设置为0;
  2. 收集各节点周期性反馈的CPU利用率 load_cur,计算出当前集群整体的CPU利用率,进而得出CPU利用率均衡目标的期望取值 load_ref;
  3. 根据算式1、2得出策略,3、4得出调整比例;
   (1)diff_pos = (load_cur - load_ref)/load_cur;
   (2)diff_neg = (load_cur - load_ref)/load_ref;
   (3)ratio_new_pos = ratio_old + (1 - ratio_old) * diff_pos;
   (4)ratio_new_neg = ratio_old + (1 - diff_neg);
   

收敛域+权重衰减

  1. 收敛时若使用如上单一基准点,会导致缓存命中率下降超10%,故为 load_ref 引入一个误差范围 [-𝛥ref, 𝛥ref];
  2. 定期衰减分流权重,弱化对一致性哈希的影响;

注:误差范围应该指 load_ref 的值没偏差超过 𝛥ref 则视为CPU负载不变;

:这里需要注意两个很重要的背景元素:服务节点是异质化的使用了有界一致性哈希,异质化通俗而言就是节点的配置不尽相同,而有界一致性哈希简单来说是面向请求负载做的LB,它应该默认为同质化节点,这两搭配起来就会出现如原文所提及的缓存命中率下降;

  即JD自己做的LB是根据服务可用性和资源利用率分配流量,有界一致性哈希又根据请求的数量,将多的请求分配给其他的节点上,例如:超高配置的服务器,JD期望其负担足够多的流量,将大部分流量发给这个节点,但是有界一致性哈希发现当前节点收到的请求数超过了上限,就将这部分请求转发给其他节点,此时就与JD预期不符了,缓存命中率也因此下降;