一探究竟 | eBay流量管理之Hot LB流量平衡全自动化之路

文摘   2022-12-09 11:18  




Hot LB项目组成员包括Victor Yang, Toddy Sun, Leona Zhang, Chenjie Cai, Woody Wang, Yuting Cao, 和Ling Peng。正是大家的精诚合作,才有了这些成绩。



引子


eBay用户的HTTP请求,经过公网的传输之后,是如何被eBay收入并处理的呢?


其实这些请求会先到达CDN,然后被eBay的负载均衡系统(Load Balancer,以下简称LB)收进来,做初步的流量业务处理,比如拒绝不合法的请求,插入HTTP头部等等。之后,LB把请求转发给服务器集群,进行应用层面的处理。


(点击可查看大图)


为了服务eBay这个量级的业务需求,我们必然需要非常多的LB来完成这项工作。而流量分布的变化,自然也影响着这些LB的负载状况,从而产生了hot LB问题

hot LB问题,是指LB的负载超限后引发的一系列问题。比如,在关闭一个数据中心时(演练或者实际需要),另外几个数据中心的LB的负载会随之上升,其中的hot LB则更是可能会跑到100%,对生产环境产生严重影响。


hot LB的解决方法,是把一部分VIP从hot LB迁移到别的LB,实现多个LB之间的负载的平衡分布。这样的迁移操作,又称为rebalancing。

(点击可查看大图)


多年来,hot LB rebalancing都是采用了半自动的方式。概括来说,其过程是:


  • 工程师根据每天的监控,发现hot LB。


  • 工程师根据个人经验,选择hot LB上某个VIP作为迁移对象。


  • 工程师根据个人经验,选择一个destination LB,作为迁移目的地。


  • 工程师发起rebalancing任务,并手工检查流量健康状况,这个过程尤为复杂。


  • 任务完成后,工程师再次检查老的hot LB,确认其降到阈值以下。

(点击可查看大图)


这样的半自动方式,在传统云计算时代(比如基于OpenStack),生产环境变动不那么频繁的时候,还没有成为突出的矛盾。每年约250个rebalancing任务,通过工程师们的努力,还是可以完成的。


然而,进入云原生(cloud native)时代以后,各种资源的变动速度加快,基础架构也发生了重大变化,这些都导致LB负载的波动性急剧变大。于是hot LB问题被推到了前台,成了基础架构团队必须解决的重大课题。


除了云原生,造成hot LB的还有以下几个原因:


  • 业务量的自然增长(Organic growth):业务增长本身带来的流量增长。


  • 新老特性的上线和下线(feature wire-on/wire-off):新功能上线,引来新的流量;功能下线则释放出LB资源。

  • 日趋频繁的代码发布(code rollout):灰度发布需要频繁操作LB,越频繁的操作,对LB的management CPU的负载越大。

  • 不断推进的HTTPS部署(zero trust):这会明显增加LB在TLS加解密上的开销。

  • 越来越多的可用区(Available Zones,简称AZ):这增加了多层LB之间的引用关系,加大了rebalancing的难度。

  • 越来越多的微服务(microservices):这是造成内网流量增长的主要原因之一。

  • 旧型号设备的带宽不够用:一部分LB是旧型号,无法适应线上流量的增长。



对于团队自身来说,精力被牵制在这种重复的事情上,没有余力做创新,就更容易陷入恶性循环。柴要继续砍,刀还要继续磨。除了继续焦虑和脱发,我们真的不能自救了吗


2020年初,主管eBay基础架构部门的副总裁Rami提出:


  • hot LB的问题的解决,应该用全自动的方式完成,没有例外


  • hot LB相关生态系统内的组件的效率问题,也要一并解决


  • 在当年的购物季来临之前,hot LB全自动项目必须完成


美国的购物季就是从感恩节开始到圣诞节结束这段时间。所以事实上,为了赢得充足的调整和改进的缓冲时间,第一个版本必须在9月底之前交付。


于是,开工。



了解rebalancing


首先,让我们看一下rebalancing具体是怎么实现的


eBay大多数应用的LB遵循了两层的设计。前面一层是Web tier,实现高效的多活数据中心的转发和自动容灾;后面一层是App tier,直接对接后端的服务集群。这两层的rebalancing做法略有不同。


下图是web tier实现rebalancing的方法。当DC3的web tier hot的时候,我们在DC3创建一个新的web tier,加入到GTM(即GSLB)的gpool,逐步调节两者之间的比例来迁移流量,最终只保留新的web tier。


(点击可查看大图)

注:这里用红色表示hot LB,绿色表示新的cool LB。


app tier实现rebalancing的方法跟前面web tier的迁移类似,区别是新的app tier加入到上一层的web tier。也是通过新老VIP之间的比例实现平滑导流,最终只保留新的app tier。


(点击可查看大图)



规划落实


前面说过,这个项目的时间只有7个月。如何在有限的时间内达成全自动的目标呢?除了投入了关键“兵力”,我们还需要合适的战略和战术。我们决定:“以终为始”


战略原则:根据立好的总目标,拆解出阶段性目标。我们不看条件,只根据最终目标反向推理,从而确定阶段性目标


战术原则:根据现有的条件,反推出做哪些事,这些事做到什么程度,来达成阶段性目标。要结合具体情况即现有条件,落到实处。


有了这两个原则,我们感觉多了几分底气。不过,现实依然骨感。运维自动化领域里有一个广为人知的事实(窘境):容易自动化的,早已经自动化了;现在还没自动化的,一般是不太容易自动化的。


具体到hot LB rebalancing项目,之前没能做成全自动化,最关键的几个挑战是:


  • 如何自动完成流量迁移中的健康检查:这里的困难依然是对工程师经验的依赖,没有自动化的健康检查系统,我们只好人工做健康检查。


  • 如何自动选择合适的做迁移的VIP:这里的困难是没有一个数学模型能够反映流量跟LB CPU的对应关系,我们只好凭借工程师的个人经验做选择。


  • 如何自动选择合适的destination LB:这里的困难是没有统一的rebalancing统筹机制,多个任务经常会选中同一个LB,致使其也变hot。


(点击可查看大图)


这三大“拦路虎”该如何搞定呢?让我们来逐一回顾一下。


挑战一:如何做好流量的健康检查?


我们把这个流量健康检查的组件称为traffic verification API。它的作用,就是要回答“迁移中的流量是健康的吗”这个问题。


思考


首先需要定义清楚,什么样的流量是“健康”的?我们认为,流量健康的本质是以下几个方面:


  • 该来的都来了吗?看看防火墙规则是否都完备。


  • 该回的都回了吗?看看服务端日志是否都正常。


  • 回复的都是正确的吗?也还是看服务端日志。


  • 流量特征发生变化了吗?看看进出报文数据量的比值。


  • 流量分布符合我们的设置值吗?看看监控系统采集到的数据。


  • 访问这个VIP的客户端集群正常吗?看看客户端的健康状况。


  • 生产环境整体有什么异动吗?看看SRE的相关接口。


上面的每一条都可以写很多,限于篇幅,我们就只挑第4条进行展开。这个流量特征,具体来说,其实就是下面这个非常简单的算式:


流量特征 = 请求的字节数 / 响应的字节数

(Pattern = ReqBytes/ResBytes)


为什么说这样一个特别简单直接的数据,可以反映出流量的健康状况呢?


我们发现,同一个应用,在经过一定时间(比如数小时)的流量累积之后,它的请求字节数和响应字节数的比值会维持在一个相对稳定的范围。这是因为,确定的应用场景所面对的客户请求,是相对稳定的。自然地,这种相对的稳定也就会体现在进出报文数据量比值的稳定上。从网络层(IP层)的简单数据就可以间接地推测应用层的大体状况,也是团队的心得之一。


我们看一个反例:假如一个VIP有问题,本该回复HTTP 200和响应数据的,却回复了HTTP 503错误。我们知道,HTTP503携带的数据量一般是比较少的,通常比HTTP200要小。于是,请求字节数/响应字节数这个值将发生明显的变化,如下图所示。


(点击可查看大图)


由于ReqBytes/ResBytes的比值发生了显著的变化(由10变为了1),我们可以判定:这个新VIP是有问题的。


流量特征相关的代码逻辑确定后,其他几条流量规则也陆续完工,很快我们的traffic verification API初具雏形。


正当我们集成好各种指标,进行dry-run(测试任务)的时候,却遇到了一个之前没料到的问题:新VIP刚被启用1%流量的时候,其各项数据指标的波动明显超过后续的几个阶段(10%、20%等)。traffic verification API频频返回Failure,全自动任务完全跑不起来。


按照原先的计划,我们认为,波动幅度超过20%就算异常。而实际情况是,在1%流量阶段,流量特征的波动幅度却远超20%,造成频繁的“假阳性”。这种情况又该如何处理呢?


(点击可查看大图)


如上图所示,1%阶段的曲线上下抖动幅度很大。而到了10%以及后续的阶段,抖动幅度就明显减小了很多。


我们分析后发现,问题的本质其实是样本不够。1%流量阶段,新VIP也没收到多少请求。在这样比较少的样本下计算出来的“流量特征”,本身就不稳定。比如同样的5分钟之内:


老VIP上收到1000次请求,ReqBytes/ResBytes为10;


新VIP上收到10次请求,其中某次响应的数据量较大,使得分母也变大了,于是ReqBytes/ResBytes为1。


一次非常规尺寸的HTTP响应(或者请求)就极大地影响了流量特征。


既然问题在于样本不够,那就加大样本数量。我们延长了1%阶段的维持时间,让新VIP能够有机会收集到足够多的样本,从而“冲淡”非常规数据点对整体的影响。


可以参考下图。假设老VIP的rps是90,新VIP的rps是5,那么新VIP的90分钟的样本数(5*90),就等于老VIP的5分钟的样本数(90*5)了。在同样的样本数下,我们就可以完成“公正”的比较了。


(点击可查看大图)


这样调整之后,traffic verification的误报率果然大幅降低。


方案


当然,最终我们采用的方案比刚刚讲的内容要复杂很多,包括:


  • 同个应用在多个VIP间的流量分布:主要是确保新老VIP上的实际流量,符合配置值。这个检查,对于发现非标准访问的情形具有很大意义。比如,按eBay的标准,所有的客户端必须通过GTM去访问。但是少数情况下,某些客户端非标配置了Region specific的VIP,这部分流量就不会按照GTM上的配置来变化。而traffic verification API就能把这种情况暴露出来,起到监督审计的效果。接下来的工作,就是联系相关团队进行整改了。


(点击可查看大图)


  • 流量特征的一致性:也就是前面介绍的ReqBytes/ResBytes比值指标。traffic verification API会对新老VIP的流量特征进行检查和比较,相差超过20%就会告警。这对于发现网络不可达问题也很有意义。比如,如果LB访问不到下一级节点,那么LB可能会给客户端返回大量的HTTP 503,其流量特征将发生显著变化,也就可以被traffic verification API捕捉到。

(点击可查看大图)


  • HTTP返回码:由于大部分流量协议都是HTTP类型的,所以我们可以根据HTTP返回码进行聚合统计,比较新老VIP之间的差别。比如,老VIP上HTTP 200的占比是80%,新VIP应该也是在80%上下。如果差异特别大,比如在60%以下,那很有可能是出问题了,会被健康检查机制自动报告出来,由工程师进行进一步排查和处理。


这个功能在后端服务器发生重大变化(比如从VM迁移到k8s pod)时,更加有意义。因为应用环境的变化,很有可能会对应用层产生干扰,出现无法预料的情况。而对HTTP返回码做监测,则可以很好地发现这种状况,如下图所示:


(点击可查看大图)


  • 客户端应用的健康状况eBay对每个应用pool的健康状况本身有细致的监控,比如一个pool上是否HTTP 500上升了,或者具体的某个应用层错误是否有突增(spike)等等。我们借助了SRE团队提供的异常检测API,在其定位到应用侧的异常趋势跟rebalancing任务有强相关性时,traffic verification API也会抛出错误。


(点击可查看大图)


  • 站点上整体健康状况:不排除有些情况下,rebalancing会因为我们不知道的原因而对生产环境造成影响。所以,我们还需要有一个“兜底”的手段,也就是这里的“站点整体健康状况”检查。我们集成了SRE的相关API接口,一旦生产环境有关键故障发生,traffic verification API就也会抛出错误,让rebalancing任务停下来。实际上在这种时候,继续把rebalancing任务执行下去的风险是相当高的,所以也必须暂停。

    最终的traffic verification API体系设计如下:


(点击可查看大图)


挑战二:如何选择合适的source VIP做迁移?


思考


对于LB这种网络类系统来说,带宽(bandwidth)和CPU是两大类资源开销。所谓的“hot LB”问题所关切的资源对象具体是指什么呢?

在10G LB时代是带宽

在40G LB时代,CPU赶在带宽前面成为新的瓶颈。


这个变化也给我们带来了一个新的难题:我们怎么知道某个VIP迁移后,原有LB上能降低多少CPU开销呢?令人沮丧的是,即使LB厂商也没有这样的数学模型。


在半自动化时代,我们的做法是


  • 人工选一个qps最高(或者bps最高)的VIP,启动迁移。


  • 等迁移完之后,复查原先LB的CPU情况。


  • 如果还超出阈值,则重复步骤1和步骤2。


为什么需要做第3步的复查呢?原因是缺乏模型,我们无法知道这个VIP迁移后,对CPU下降的实际效果如何。简单来说,就是“迁一个VIP试试,看看效果”。


所以我们必须要有这样的模型。假设这么一个情况:

某一台hot LB目前CPU峰值是80%,而目标CPU峰值为65%。其上有100个VIP,如果我们根据数学模型和qps、bps监控数值,计算出对应消耗的CPU资源:

VIP1: 8% CPU

VIP2: 7% CPU

VIP3: 3% CPU

VIP4: 2% CPU


由于我们的目标是迁走至少15%的CPU开销,那么由于VIP1和VIP2的CPU开销正好是15%(8%+7%),我们的全自动化就可以选择这两个VIP进行迁移。


我们相信,流量特征(rps, IN bps, OUT bps)确定的VIP,其对应的CPU开销值应该也是可以确定的(至少能缩小到某一个精度区间之内)。从原理上说,VIP的流量,本质上是数据包在LB的网卡、L4处理(TCP)、L6处理(TLS)、L7(HTTP)处理上的开销。我们逐一分析:


  • rps的因素:rps恒定的情况下,CPU跟bps成正比。


  • bps的因素:bps恒定的情况下,CPU跟包量(pps)成正比。


  • TLS的因素:https跟http相比,因为多了TLS加解密环节,所以会消耗更多CPU。


  • 设备型号的因素:同样流量特征的VIP,其CPU开销在新型号LB上小,在旧型号上大。


如果有这么一个数学模型,输入值包括:qps, bps, protocol, hardware model,输出值是CPU开销,那么这个“如何选择合适的VIP做迁移”的问题,就能答上一大半了。另外一小半主要跟业务特点相关。


方案


我们做了两件事情来获得这样的数学模型。


首先是样本数据的采集。我们在测试LB上配置了一些有代表性的VIP,然后对这些VIP发起压测。当CPU运行到一定值的时候,我们记下当时的CPU使用率、VIP的rps、IN bps、OUT bps这几种数值。


然后是数据建模。利用python的numpy库,对前面的样本数据进行函数拟合,得到相应的函数曲线。


有了模型,就可以计算了。对已经建好的数学模型输入线上的实际数据(VIP的rps、IN bps、OUT bps等数值),我们就能得到对应的LB CPU的开销值了。


(点击可查看大图)


上图中,横坐标为阶数,纵坐标为误差级别。显而易见,阶数越高,误差越小。一阶的误差很大,而二阶误差大幅下降。从“性价比”的角度,我们选择了二阶拟合函数。

(点击可查看大图)


经过dry-run阶段的测试和调整,这个模型给出的CPU预计值还是相对准确的,也是够用的。跟过去“毫无数据可以参考”、完全靠“迁一下试试”的时代相比,现在基于数学模型的做法,不仅避免了重复迁移或者反复迁移,也避免了这种做法带来的风险。


\ | /


挑战三:如何选择合适的destination LB?


思考


跟前面两个挑战相比,“如何选择合适的destination LB”就相对容易一些。大体上,我们只要做到以下几点:


  • destination LB跟source LB(也就是hot LB)是同一种类型


  • 多个rebalancing任务需被统筹规划,合理分配


  • 完成rebalancing后的预期使用率应低于阈值


不过由于现实环境的复杂性,我们还需要考虑一个重要的问题:如果我们迁移的是ATB pool(也就是支付等最关键的功能),会不会因为rebalancing而把原先分布在多个LB的ATB pool,都集中到同一个destination LB上呢?那样的话,这个LB岂不是会成为“鸡蛋都放在一个篮子里”的那个篮子吗?


注:ATB是eBay的可用性指标,全称是Availability To Business,这也是技术团队最关注的指标。ATB pool就是最关键的应用。


这也体现了eBay运维工作的特点:除了技术以外,业务的特点也需要被充分地考虑到系统设计里。因为系统最终是为业务服务的,不能少了“量身定制”的部分。


我们设计了一张ATB pool的数据表,destination LB的选择以及其他一些逻辑,会避开这些ATB pool,去选择其他非ATB pool做rebalancing。因为eBay的应用非常多,就hot LB的着眼点来说,关心的是LB负载是否降回安全线内,只要选择迁移的pool可以起到这个效果,就是符合需求的。


方案


我们最终选用的Destination LB的自动化选择机制是这样的:


(点击可查看大图)





方案落定


基于以上的准备工作,全自动化方案需要的各个环节都已经打通了。让我们来看一下最终采用的整体方案。


(点击可查看大图)


图中浅蓝色的组件是半自动化时代就已经具备的基础架构能力,绿色的组件是全自动化项目需要完成的部分。在这些绿色的组件都到位后,我们终于可以把最初版本的全自动系统上线,然后开始在有人看护的情况下进行dry-run,不断收集问题。


不出意外地,我们又“收获”了几个新的挑战


新挑战一:如何确保web tier的流量分配跟GTM是严格匹配的?


在文章开头,我们介绍过流量迁移的两种方式,虽然本质上都是通过“在上一级调整比例”来实现流量的迁移,但web tier跟app tier相比还有一个区别:web tier的流量分配的实际效果,常常离我们的配置值有较大的差距。这又是为什么呢?


思考


web tier的流量调度,是使用了eBay的GTM。GTM本质上是一种智能DNS,这种流量管控就是基于DNS的原理来实现的。由此,它也必然受到DNS本身机制,特别是其缓存机制的限制。我们来看一下典型的eBay内部应用实例的域名解析路径:


(点击可查看大图)


eBay的典型技术栈是java,那么一般来说,我们的应用会遇到以下几种名称解析方面的cache:

1. JVM本身有cache机制(比如60秒,不遵循DNS TTL)


2. JVM所在的主机的本地cache(遵循DNS TTL)


3. 本地的解析服务器DNS resolver的cache(遵循DNS TTL)


4. 权威服务器(在这里就是GTM)的配置修改生效的时间


如果说从客户端到服务端是一个链条,那么上面这些环节其实是松动的,都好似一个个random()函数一样,不同程度上增加了随机性,累加起来就给最终结果(也就是实际生效的流量分布状况)带来了较大的干扰。


但是,这些cache机制又不是那么容易修改的。比如JVM的60秒cache机制,要改动的话就要经过充分的应用测试和全面的框架升级。这条路既不容易走通,也未必是最佳方案。


能不能调整DNS TTL呢?可以预见,越小的TTL值,意味着越大的查询压力。不过有时候事情就是这么奇妙,我们担心的事情其实未必会发生。当我们“史无前例地”在rebalancing期间把TTL调整为0的时候,DNS和GTM的CPU使用率只有小幅的增长,完全在安全范围之内。于是,通过调整TTL为0,Host和DNS resolver的cache(也就是上面的第2和第3条)带来的影响也被降到了最低。


分析完JVM和DNS的TTL,我们来到了最后一个环节,即GTM。我们发现,GTM经常不按我们希望的比例返回结果,这也是导致web tier在迁移中流量分配不准的原因之一。


为了验证解析结果是否准确,我们用dig命令对GTM进行很多次的解析。结果却发现,当解析次数相对少(几百次)时,解析结果中新老IP出现次数之比,确实跟GTM设置值差异较大。


类似下面这样:GTM上对新老VIP的实际权重值是10:90,但解析结果却是1:33(也经常是别的比值)。


for i in {1..100};do dig +noall +short abc.ebay.com;done | sort | uniq -c
33  209.100.100.100 (old VIP)
1 209.100.100.101 (new VIP)
33  209.100.100.102
33  209.100.100.103



进而发现,如果加大解析次数(几千次)时,解析结果就跟GTM设置值很接近了,比如下面这样:


for i in {1..3000};do dig +noall +short abc.ebay.com;done | sort | uniq -c

900 209.100.100.100 (old VIP)

100 209.100.100.101 (new VIP)

999 209.100.100.102

1001 209.100.100.103


经过反复思考,我们发现问题出在我们之前只关注了“比值”,却没有关注“原始值”。比如,我们直观上觉得,90:10跟9:1是一样的,不都是九比一吗?然而在GTM层面,两者却有很大的不同,因为GTM是严格按照原始值来返回解析的


还是上面的例子。old VIP和new VIP的权重值分别是90和10,那么GTM会对前90次解析都返回old VIP,只有后面的第91次到第100次解析才返回new VIP!而改为9:1后,前9次返回old VIP,第10次就能返回new VIP了,这样就可以尽快让流量按我们期望的样子进行分布。可以参考下图。


(点击可查看大图)


造成流量没有按预期分布的本质原因是解析生效滞后。现在搞定了DNS解析,是不是问题就搞定了呢?其实不是。还有一个因素也产生了重要影响,它就是TCP长连接。也就是说,造成解析生效滞后的原因其实有两个:


1.DNS缓存

2.长连接


不过相比之下,长连接这个问题更容易解决:我们只要把长连接断开就可以了。当然,话说的轻巧,我们又无法去修改客户端的代码,如何让客户端放弃这些长连接?


通过探索,我们发现可以在不改动一行应用代码的前提下,只利用协议规范就可以实现这个需求。eBay的应用多数基于HTTP协议,它正好有一个特性可以控制长短连接,也就是“Connection: Close”头部当服务端的HTTP响应中包含这个头部时,按照HTTP规范,客户端就应该把这条TCP连接断开。客户端再发起新请求时,就必须要新建一条TCP连接了。而新建连接,一般都需要重新做一次DNS解析(应用程序缓存解析结果的情况并不普遍)。于是,GTM上的ratio配置,就会在这次解析的结果中得以体现了。


方案


要插入“Connection: Close”头部并不复杂,我们只需要在LB上设置相应的rewrite policy即可。如下图所示,LB在HTTP响应报文中插入这个头部,就相当于告诉客户端:你可以关闭连接了。


(点击可查看大图)


下图展示了我们应用了两种对策(DNS TTL=0和LB rewrite policy)后,web tier流量从很不规则变成很规则很平滑的过程。


(点击可查看大图)


而另外一个问题,即长连接导致老VIP上流量始终不容易停止的问题,也通过LB rewrite policy给解决了。

(点击可查看大图)



新挑战二:如何确保全自动任务的成功率?


全自动化项目的评价标准和成败,如果说只有一个,那就是成功率。成功率低,则意味着我们的工程师仍然要花不少时间去重试、排查、修复。成功率高,当然就意味着我们的效率高。


思考


不难想到,提高成功率,需要从两个方向入手:


  • 提升hot LB自动化系统内部任务的成功率


  • 提升外部依赖服务的成功率


内部任务的成功率在我们的掌握之内,但外部依赖的成功率的提升却有很多不确定性。最大的困难在于,这些服务都是不同的团队在维护,这势必带来了跨团队工作优先级不一致的问题。这怎么办呢?


我们很快决定,直接采用重试策略。用这种简单直接的方法,尽可能地“消化”外部API的失败率。我们做个简单的估算。假设一个外部API的成功率为80%,而我们对这个API的调用做2次重试,那么成功率就上升到100%-20%*20%*20%=99.2%了。


每一个hot LB rebalancing任务,平均需要对外部API进行30次左右的调用,那么30个99.2%相乘,我们可以得到一个理论上的成功率:78.58%


方案


9月底要“上台表演”,那我们就要提前在台下把功练起来。为了抓到每一个cornercase,我们大量的进行dry-run。在9月上线之前,我们累计了200多个任务,相当于之前一年在线上真实发生的rebalancing任务的数量。dry-run做的越多,上线后的可靠性越高。所以,这个投资必须做,也值得做。


我们还做了dashboard来持续监控任务成功率和失败原因。以2020年Q4为例,这3个月完成的全自动化任务成功率(完全无需手工介入)达到89.2%。成功率本身有随时间而波动的情况,在3个月这个时间长度上能有这个表现,说明重试策略起到了应有的效果。


(点击可查看大图)



新挑战三:如何确保全自动化不引发意外


思考


做自动化不怕,怕的是全自动化。因为半自动化流程中,总有人在守护,会令人安心很多。比如根据现场情况,灵活做选择和应对,让rebalancing的运行始终在人的掌控之内。但是全自动化以后,我们时常会信心不足,最担心的其实就是生怕全自动化“自作主张”,引发意外事故。


那是不是一定就不能全自动化呢?如果我们对系统设置一些绝对不能逾越的“禁区”,那么这种担忧是不是就大为减轻了?这可以称为“底线思维”--不求最优的操作,但不该做的一定不做。


方案


Hot LB全自动化也用到了底线思维。我们只要做到以下几点,hot LB全自动化对生产环境的影响将降到最低:


  • 不碰最关键的应用:也就是前面提到的设置禁止迁移的黑名单。


  • 不迁移特别大或者小的应用:用source VIP选择的机制,过滤掉15% CPU以上和1% CPU以下的VIP。


  • 锁机制:利用全局锁,防止多种任务同时运行,避免造成流量混乱和配置不一致。


  • 不迁移非标应用:设置precheck,过滤掉模型不完整的VIP。


  • 集成SRE的关键API:检查change stop API和global business alerts,如有异常则立即停止操作。


  • 限制整体任务数量:防止意外自动创建大量任务及其引发的事故。


效能产出


在陆续搞定了前面说的众多问题之后,hot LB全自动化终于在2020年9月上旬正式上线。截止2022年11月25日,在这2年零2个月的时间内,已经完成rebalancing任务3800个。按半自动时代每个任务需要2.5小时的人力来折算,相当于节省了60个人月,全自动化的效能(efficiency)显著!


从任务量来看,全自动化每年完成约1800个任务。跟半自动化时代每年250个任务相比,产能增加到原来的7.2这还是在人力投入大幅减少的情况下完成的。


通过全自动实现效能的数量级提升,我们达成了最初的目标。


(点击可查看大图)



LB间自动平衡


这是hot LB rebalancing的最主要功能,我们直接看实际效果。下图中不同颜色的线各自代表了一个LB设备,有七个波峰和波谷,代表了七天的流量状况。很明显,第五天开始,橙色线的LB的CPU使用率有所上升,在第六天明显高出其他曲线,说明其负载显著增加。随后,全自动化很快发挥了作用(VIP被迁移到了其他LB)。这条橙色线又快速向大部队靠近,在两天内回归到与其他LB同样的水平。


(点击可查看大图)


这是另外一个例子。在上线全自动化之前,我们只能做到把很hot的LB变得不那么hot,而多个LB之间的利用率还是有比较大的差异,这不利于充分利用LB资源。而在下图中,全自动化上线后,这些不同颜色的曲线在9月28日到10月22日之间,相互间的差异不断收敛。到10月25日的时候,这些曲线已经十分靠近了。


(点击可查看大图)


新LB自动ramp up


以前,新LB投入生产环境后,它们主要会通过两种方式得到负载:


  • 半自动的hot LB rebalancing,工程师创建任务,把VIP迁到这台新LB。


  • 云平台的provisioning会在创建新应用的时候,优先使用新LB。


有了全自动化后,这项工作变得很简单了。工作负载会被自动迁移到这个新LB上,使得AZ内多个LB的负载更趋均衡。我们只要让系统“自觉地”去干活就好了,工程师要做的就是每天看一下趋势图,确认一切是否在正常运行。如果有什么异常再针对性处理。


下图中,新的LB上线后,不断接收到新的VIP,流量也不断上升,最终会跟其他LB“会合”。


(点击可查看大图)


Traffic verification能力


在项目推进过程中,我们趟过或深或浅的溪流暗坑,把它们解决,算是为后来的项目铺平道路。比如以下这些:


  • 从零开始打造了traffic verification系统,使得后续的new AZ ramp up、pool decommission、AZ decommission等云平台常见任务的全自动化成为可能。


  • 根本上解决了之前通过GTM进行流量调度不够精确的问题。


  • 解决了TCP长连接引起的流量不均问题。


实际上,就在过去的一年里,我们又完成了大量的流量迁移工作,包括公网流量向SLB的迁移、新AZ的ramp up、新的k8s cluster的ramp up、pool到pool的迁移等等。有赖于traffic verification能力的支撑,我们才能用较低的成本,完成了数千个重要的迁移任务。


人员的提升


虽然放在这节的最后,但是这个收获,甚至比hot LB全自动化本身还更加的重要。当西游记的师徒四人抵达西天时,他们不仅收获的是西天取经的成功,更重要是他们每一个人修炼成佛。


我们团队的成员能力也历经了不少“磨难”,也打过了妖魔鬼怪(不是吗?我们经常会说“这个问题太妖了!”)。学到了以前不会的本领,做了以前没能做成的事。更为重要的是,我们在项目推进的过程中,看到这些原先模糊的目标变得清晰,原先不可能的任务变得可能,于是我们的自信心也更强了。


而这样的团队,在面对eBay的更高的自动化流量管理要求,以及从硬件LB到软件LB这种根本性演进的过程中,是有信心去完成一个又一个类似hot LB全自动化乃至更有挑战的任务的。


任重道远


降低hot LB rebalancing对transaction time的影响


Hot LB全自动化上线两年,完成了3800个任务。令人欣慰的是,即使达到了这个数量级,依然保持了对ATB影响为的纪录。


当然,还是有一些次要问题。比如有一个问题就比较典型:做web tier rebalancing可能会导致应用的transaction time显著增加对于时间敏感型的应用来说,这带来了两个副作用


  • 客户端一侧的timeout可能会超时,造成这些客户端应用的报错显著增加。

  • 因为服务端transaction time增加,终端客户的体验会明显受到影响。


为什么会导致transaction time增加呢?


之前提到过,rebalancing的时候,GTM的mode从topology改成了ratio。这样的话,原先客户端是直接跟本地数据中心内的服务端通信的,而在rebalancing过程中,却有一定比例的请求是跟远端数据中心通信的。大家知道,跨数据中心的往返时间(Round Trip Time)会显著增加,每多跑一次往返,transaction time就可能增加十多毫秒。如果一次事务需要跑10个来回,那累计就是100多毫秒了,很可能已经超出了客户端能容忍的上限。




(点击可查看大图)


对于这个问题,目前的短期方案,是把这些时间敏感型应用加入到黑名单,防止其被下一次自动化rebalancing任务选中,转而用其他VIP来完成hot LB rebalancing。


长期方案,是改变web tier rebalancing的具体做法,改为下面这种迁移方式:


  • 把原先共享的单个gpool拆分为为每个数据中心独立创建的gpool。


  • 把新VIP加入到这个数据中心对应的gpool,并调整两个VIP间的权重比值。


  • 迁移完成后,依然恢复为共享的单个gpool。



(点击可查看大图)


这样的话,客户端在rebalancing过程中,始终拿到的是本数据中心的服务端IP,也就不会增加transaction time了。


问题修复的自动化


目前,对于全自动化任务失败的情况,是需要人工介入排查和修复的。这部分工作依然有效能可以挖掘。通过汇总分类,找共性规律,我们也可以逐步把修复工作自动化。


比如,对于脏数据修复问题,只要确定了修复SOP,就可以做成自动化:系统先检查失败原因,如果发现是脏数据导致,则自动执行脏数据清理,然后自动重试该rebalancing任务。


对于依赖其他团队的修复场景,就让工具自动开出对应的ticket。在其他团队完成修复工作,ticket关闭后,reblancing任务探测到ticket closure事件,进而自动重试,直至任务完成。


对于上面这两种情况,都尽量降低工程师手工介入的可能性。


(点击可查看大图)


Traffic verification API的准确率提升


目前我们对traffic verification AP的设计是相对保守的,也就是“即使误报,也不要漏报”。当然,这跟我们的业务场景有密切的关系:生产环境的ATB永远是第一要务,为了确保我们不会遗漏任何一条漏网之鱼,我们愿意为此承担多付出的成本。


从产品打磨的角度来看,肯定还需要继续推进traffic verification API的准确性。比如F1 Score这样的指标,是我们继续打磨的方向。我们应该做到在不漏报的前提下,尽量减少误报,把这个基础能力打磨地更加精确。



结语


这算是一个小小的里程碑,过去的已经做到,将来的更需赶赴。现在正值足球世界杯,我想我们的团队也是如此:


SLB(软件负载均衡)的推进工作就好比前场进攻,而hot LB全自动化就像球队中的后卫和守门员,确保后方(HLB)无忧。减轻了后场压力,前场的队员就可以更加集中精力,奋勇争先,最终夺取期待的胜利。


据说足球可能是我国发明的。这里也引用一句我们古代先哲的名言。荀子曰:“岁不寒无以知松柏,事不难无以知君子”。我想这可以是我们工作中的座右铭。在遇到困难的时候,不妨想一想这句话,相信我们会充满力量。与大家共勉。



END



eBay技术荟
eBay技术荟,与你分享最卓越的技术,最前沿的讯息,最多元的文化。
 最新文章