Robin负载均衡策略存在问题及CSE解决方案

举报
liubao68 发表于 2018/08/27 14:51:45 2018/08/27
【摘要】 本文描述了CSE在使用Ribon组件期间发现的问题,以及CSE是如何解决这些问题以满足自身业务开发需要的。

Robin

Robin设计了几个核心接口:IRuleILoadBalancerServerListFilterIPingServerListServer。开发者在使用的时候,需要组合使用这些接口。Robin提供了大量的接口实现,在使用这些实现或者自定义实现的时候,存在非常多的问题需要考虑:

1.       每一个实现类依赖的其他接口的功能是不确定的,不能够随意组合。比如:ServerListFilter只会被DynamicServerListLoadBalancer使用,而不会被ILoadBalancer的其他实现类使用;IRule的不同实现,依赖的ILoadBalancer接口不同,RoundRobinRule会调用getAllServerList,并且会判断返回的Server是否alive,而RandomRule则不会使用这些接口,这种情况会给实现ILoadBalancer的开发人员带来大量的困扰,他们必须对每一个可能的IRule实现进行测试,以保证提供给用户的功能说明是可靠的。这种情况带来的另外问题,就是限制了运维人员在运行时动态的调整负载均衡策略。使用Robin组件,更加适用于开发阶段确定好各个实现,而不进行修改。

2.       在使用ServerListFilter的时候,不能够基于每次请求的参数进行实例过滤。这样类似灰度发布等功能无法通过它实现。因为ServerListFilter会通过ILoadBalancer获取当前请求参数,而ILoadBalancer则被大量的请求共用。业务必须通过ThreadLocal来保存请求参数,以防止并发问题。初次使用这种机制的业务基本都会忽略这个问题,必须通过大量并发测试才可能发现,很多时候会将问题遗漏到生产环境。

3.       在需要动态调整IRule的场景,部分IRule的实现可能会导致内存泄露。比如WeightedResponseTimeRule。这个规则在初始化的时候,会启动Timer线程计算权重,并且每次更新ILoadBalancer的时候(调用setLoadBalancer方法),会重新初始化,如果并发控制不当,则会导致频繁创建线程造成OOM。这个问题需要在进行大量并发和持续运行的情况下才能够发现。

 

总结:Robin定义了很灵活的接口,在实现单一场景的时候,可以满足非常多场景的需求。但是在动态调整策略、自由组合策略以及定制开发过程中都存在大量的陷阱,需要开发人员非常谨慎使用,有些陷阱需要进行大量并发和长时间运行才能够发现。

 

CSE对负载均衡算法的改进

CSE结合自身对负载均衡的理解,对负载均衡处理流程进行了改进。下面是流程图:

image.png

 

1.       DiscoveryFilter主要管理实例进行分组、缓存。详细流程参考:https://docs.servicecomb.io/java-chassis/zh_CN/references-handlers/loadbalance.html

2.       对每一个微服务分配一个LoadBalancer实例。

3.       ServerListFilerExtRuleExt均对RobinServerListFilterIRule进行了改进。参数增加了Invocation,这样可以支持基于接口参数的路由选择。对于ServerListFilterIRule的扩展,都只需要实现接口,并不需要依赖大量的LoadBalancer的接口,这样就避免了业务在实现这些接口的时候,需要考虑组合的一致性,减少业务犯错误的风险。

4.       整改以后,业务不能在随意配置和使用IRuleServerListFilter的实现。需要使用系统缺省的配置参数:RoundRobinRandomSessionStickinessWeightedResponse等,这些字符串表达和实现方式独立。业务也可以通过扩展ExtensionFactory实现自己的RuleExtServerListFilterExt

 

基于响应时间权重问题

经过上述整改,CSE重新实现了WeightedResponseTimeRule,新实现的算法没有采用定时器和新线程,可以避免频繁替换Rule和并发场景下可能导致的内存泄露等问题。这个算法存在如下需要注意的问题:

 

1.       “权重响应时间并不是一个严格意义上的反比关系。比如时延为20ms40ms,并不意味着实例选择的概率是2:1。目前计算权重响应时间的算法为:

T = SUM(L1,L2,…,Ln)

(L1:L2:…:Ln) = (T-L1:T-L2:…:T-Ln)=(W1:W2:…:Wn)

“权重算法是一个伪随机算法,实例的分布符合上述的公式,但是每次选中的实例是不可预期的。 另外,如果所有实例的响应时间均小于10ms,那么权重算法等同于RoundRobin算法。

2.       在实例数为100的情况下,基于响应时间权重算法比RoundRobin算法慢100倍。但是不用担心,这个是对实例列表遍历一遍的时间,在业务处理时间为10ms的情况下,只占用业务1/1000的时间。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。