gig:自带负载均衡和降级功能的高可用RPC解决方案

本文涉及的产品
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
推荐全链路深度定制开发平台,高级版 1个月
OpenSearch LLM智能问答版免费试用套餐,存储1GB首月+计算资源100CU
简介: gig基于对latency的负反馈控制,实现了坏节点屏蔽、服务预热、异构集群负载均衡、自动降级等功能,大大提高了阿里搜索线上服务的稳定性。

在线查询系统中,业务逻辑将服务划分为树状结构,每个节点通过水平扩展增加自身服务能力,最终形成下图所示拓扑结构:
net
当一次查询从某一入口进入系统后,自上而下查询各个服务,每个服务又有多个节点可供选择,最简单的负载均衡策略是轮询或者一致性hash,各个节点接相同流量,但是这种策略下如果集群中出现了坏节点,则会导致部分用户查询无结果或者超时,严重时导致故障。

复杂一些的系统通过服务发现做坏节点检测,例如阿里的cm2和vipserver。以cm2为例,cm2会通过http心跳探测检查下挂节点的健康度,如果一个节点能够响应cm2的心跳探测,则认为是健康节点,cm2会将该节点发布给在线系统查询;节点异常时,心跳探测失败,cm2通知在线系统该节点需要删除,该节点流量跌0,从而避免坏节点干扰流量,如下图所示:
probe
通过心跳检测发现坏节点主要有一下两个问题:

  1. 心跳检测与实际查询的网络通路是不同的,心跳检测成功说明名字服务与目标服务之间的网络正常,但线上系统经常出现某条网络通路延迟高或者不通的情况,外部心跳检测解决不了这类问题。
  2. 外部心跳检测无法发现服务自身的业务问题,或者说外部探测只能屏蔽部分进程、系统层面的问题(进程core掉、系统crash等)。例如搜索场景中,某个上层服务本身是健康的,但是他的下挂服务无结果率升高,这时候外部探测发现上层服务是健康的,流量还是会导向这个有问题的子系统,这常见于灰度发布、按机房发布等场景中。

以上问题的原因实际上是一致的:在线系统决策能力弱,完全依靠外部系统辅助决策查询路径。为了解决这些问题,我们开发了gig。

gig(Graph IrriGator)的核心思想是在线实时决策流量流向,不再局限于外部系统探测这种隔靴搔痒的方式,而是作为一个高可用的RPC lib嵌入到在线应用中,代理应用对底层服务的访问,实时统计每个节点的延迟和错误率,屏蔽高延迟节点、高错误率节点,在下游节点延迟上升到无法接受之前主动限流,让流量流向此刻此节点看到的健康路径上去。

从上图的角度来看,外部探测的方式是面向节点的,即每一个节点有一个健康度,而gig是面向边的,每一条边都有一个健康度。显然,边的个数要远大于节点个数,对系统状态的刻画也更加全面,同时,嵌入到在线系统有一个天然的优势:gig可以感知业务层面的错误,并能够据此屏蔽服务异常集群。

1 gig原理

gig的核心功能之一是解决包含网络异常在内的坏节点问题,而不同的系统对异常的定义不同,gig选择了所有在线系统都有的一个核心指标"查询延迟"作为节点好坏的评判标准,节点队列堵塞、网络超时、操作系统负载高等异常情况均能在latency上反应出来。同样,系统负载也能从latency上体现,因而gig的降级(限流)策略和负载均衡策略也是基于latency的。

如果将在线树状系统想象成一个大的水利灌溉系统(gig名字的由来),灌溉者的功能是将水导向系统中阻力最小的部分,既不能让入口水流堵塞,也不能让干旱发生,到gig这里,水即是流量,阻力则可以近似认为是latency,阻塞是系统吞吐量下跌,干旱则是负载不均衡。所以gig会统计上图中每一条边的平均latency,并据此导流,更进一步,gig还通过控制流量高低来控制每一条边的latency。

1.1 基于PID控制器的latency负反馈控制

在线绝大多数场景下,查询latency与流量呈正相关,即流量越大,latency越高,类似下图:
latency
流量控制的目的是为了稳定每一个节点的latency,各个节点的latency差异控制在合理范围内,对于高latency的节点应该予以屏蔽。为了稳定各个节点的latency,我们设计了如下图所示的负反馈控制器:
feedback
图中的PID控制器实际上只使用了I(Integral)部分,即一个带抗饱和功能的积分器,整体是一个过阻尼系统,这样设计的原因是线上各个系统的Latency-qps关系变化很大,积分本身虽然相应速度慢,但由于在线系统的响应速度快(流量升高时latency会瞬间上升),latency达到预期值后积分器瞬间停止积分,不会超调导致下游节点CPU被打满。
系统稳定后,限流阀从入口流量中分得固定比例的流量给该下游节点,同时,下游节点的平均latency能够被控制到与Input Latency一致。gig将上述控制器应用到所有下游节点,最后剩下的问题就是latency的给定值(Input Latency)如何设置。
有两种方式:用户指定和系统自动推导。用户指定实际上比较困难,多数时候应用的latency是随流量和业务变化的,提前指定几乎是不可能的。
gig采用的是系统自动推导方式,推导方式也很简单:取所有节点的平均latency的最小值作为所有节点的Input Latency。这样做符合流控和负载均衡的初衷,流量总是倾向于向低延迟节点流动。最终形成如下图所示结构:
system
整个系统由入口流量驱动,系统能够保持各个节点的latency分布在一个较小的区间内,这个区间之外的节点流量跌0。

1.2 降级功能

有了平均latency后降级功能也很容易实现,gig以平均latency作为系统负载的指标,允许用户设定系统运行的最高latency(实际上是两个值,一个是开始降级的beginDegradeLatency,一个是100%降级的fullDegradeLatency),当系统所有节点的平均latency最小值超出beginDegradeLatency后,gig将根据超出部分占区间[beginDegradeLatency, fullDegradeLatency]的比例限流,直到完全限流。所以应用的latency是不可能超过fullDegradeLatency的。

2 适用场景

实现了对latency的精准控制后,许多场景的问题便迎刃而解:

2.1 部分节点网络超时

节点网络超时时,该节点的latency变高,控制器将该节点的流量下调,如果是网络自身问题导致超时,则流量调整为0后latency仍然不能恢复,系统保持该节点不接流,达到屏蔽该节点的功能。网络恢复时,gig探测发现节点延迟下降,该节点流量自动恢复。关于gig探测机制,请参考文末gig用户文档。

2.2 部分节点服务能力下降

节点的服务能力受系统负载或者其他应用干扰,该节点因latency上升而流量下跌,如果节点服务能力跌0,则流量跌0,如果节点服务能力减半,则流量减半后系统稳定,最终实现"多大能力接多大流量"的效果。

2.3 新加节点需要预热

许多服务新启动后需要预热,如具有jit功能应用(java、tensorflow xla)、磁盘io类应用等,这些类型的应用系统服务能力是随着接流时长而增加的,服务刚启动时,新节点latency高,流量跌0进而触发gig探测,节点latency逐渐下降,满足用户设定倍数时,流量自动恢复。

2.4 异构集群

CPU和GPU异构计算集群中,基于不同硬件的节点可以提供相同服务,但服务能力存在差异,gig的latency均衡机制能够均衡两个集群的流量比例,将两者的latency控制在一定差异以内,避免流量分配不合理造成单一集群负载过高而超时。
对于主动降级场景,latency-qps变化曲线不再是正相关,latency控制变为正反馈而失效,gig内部设计了专有错误码避免这种情况的发生。

3 gig针对多列应用的优化

大数据场景下,单机很难存放所有数据,因而很多应用对数据分列,形成多列多副本的拓扑结构,我们称为多行多列应用。查询时,应用逻辑要求查询一个完整行,即每一列都查一次。gig中将这种类型的应用抽象为多个列,每个列提供同质的服务,列内部各个机器之间做上述流控操作,于此同时,gig还针对多列应用的特点,做了三个优化:提前终止(early terminate,简称et)、重试(retry)、缺列降级。

3.1 early terminate

et是指在某一列未返回结果时,丢弃该列的结果提前返回,应用层拿到的数据会少一部分,这对于搜索等场景是可以接受的,拿到部分结果要优于整个query超时。

3.2 retry

retry是指当某些列的结果未返回时,gig会重查该列的另一个replica,如果另一个replica及时返回,则查询结果仍然是完整的。
et和retry的目的是为了防止单机抖动时造成query超时或失败,其核心假设是数据均匀分布,各个列处理同一个query的时间是相近的,一台机器是否异常可以通过与另一列比较得到。例如,如果第一列用了10ms返回,那么第二列应该很可能在5-15ms内返回,如果第二列用了50ms仍未返回,那这一列有大概率是出现了瞬时抖动,此时gig会根据用户配置采取retry或者et操作,又或者是两者同时启用。

3.3 缺列降级

在多列的情况下,gig主动限流不再是直接丢掉整个query,而是丢掉query中某些列的查询,这样能够最大限度保证服务质量。例如,一个10列应用,如果触发了10%降级,则有10%的query缺失1列的查询结果。随着降级程度的增加,缺列的query比例会增加,缺少的列也会增加,直到整query限流。
et和retry的详细作用机制及配置方法参考gig用户文档,缺列降级只要多列用户配置了降级就会自动启用。
HA3使用了et和retry功能后,在单台searcher core掉的情况下,能够做到前端用户无感知。

4 gig组网:多级级联系统

gig本身的设计是针对一个服务调用另一个服务的,但是gig同样能够组成如下图所示的级联系统:
multi.png
考虑到中间层的部分gig节点可能会因为自身负载等原因触发gig降级,且降级后因latency并无大变化而持续接流,这样集群中就会一直存在一个降级节点,影响服务质量,因而gig专门定义了降级相关的错误码,上层gig收到该错误码后会降低该节点的流量。
级联以后,除图中红色节点以外,剩余节点发生异常时均可以被屏蔽。

5 生产流量copy

在系统新版本上线、压测或者性能优化时,往往希望能够获得与生产系统完全一致的流量,包括流量大小和组成成分,gig支持将生产流量copy到一个完全独立的集群,copy功能会增加在线系统的网络带宽,但copy集群的结果不会服务在线流量,copy集群自身挂掉也不会干扰在线系统的运行。

6 多协议支持

gig现阶段支持三种协议:arpc(阿里内部rpc协议)、http、自定义tcp,用户可以根据自身应用特点选择。

7 双十一应用情况

今年双十一期间,搜索内部上线gig的服务包括:主搜索和tmall搜索后端HA3、RankService、SP、Igraph和DII等多个搜索业务引擎,gig峰值调用超过千万QPS。部分应用使用或触发了预热、降级等相关功能,其中RankService集群还使用了gig的预热功能和异构(CPU和GPU)均衡功能,结构上HA3和SP引擎构成了两级gig级联系统。

8 总结与展望

gig的存在提高了搜索线上应用的鲁棒性,显著降低了服务质量对外部环境的依赖,后续我们会持续优化gig的流控策略,包括改进latency的统计、添加错误率统计和对java应用的支持等,同时最近service mesh异常火热,gig的功能很多与service mesh的理念相吻合,后续gig也会考虑往云和微服务场景发力。

欢迎对gig原理感兴趣的同学联系我们,大家一起探讨。同时也欢迎对超大规模实时数据处理、检索和计算服务感兴趣的同学加入我们团队:https://job.alibaba.com/zhaopin/position_detail.htm?positionId=42997

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
负载均衡
Pgpool-II实现高可用+读写分离+负载均衡(七)---- recovery_1st_stage分析
recovery_1st_stage是Pgpool online recovery的第一阶段,位于PG_DATA目录下,主要功能就是使用pg_basebackup恢复(recovery)从节点。
|
15天前
|
监控 测试技术
slb测试会话保持功能
slb测试会话保持功能
27 6
|
5月前
|
负载均衡 Java API
Feign 进行rpc 调用时使用ribbon负载均衡源码解析
Feign 进行rpc 调用时使用ribbon负载均衡源码解析
79 11
|
4月前
|
负载均衡 Cloud Native 容灾
阿里云负载均衡SLB价格_ALB、NLB和CLB区别_负载均衡功能和使用场景说明
阿里云负载均衡SLB分为应用型ALB、网络型NLB及传统型CLB。ALB与NLB仅支持按量付费,而CLB则提供包年包月和按量付费选项。ALB专长于7层HTTP/HTTPS/QUIC协议处理,支持丰富的内容路由功能;NLB聚焦于4层TCP/UDP/TCPSSL协议,擅长处理大规模并发连接。两者均基于NFV技术,支持自动弹性伸缩,并与云原生环境如ACK/SAE/K8S深度集成。此外,SLB提供多协议支持、多级容灾、安全防护等功能,确保服务的高可用性和安全性。具体收费方面,ALB的基础版实例费为0.049元/小时起,NLB实例费限时免费,两者还需支付性能容量单位LCU费及公网网络费(仅公网实例)
|
5月前
|
负载均衡 监控 Kubernetes
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
|
5月前
|
负载均衡 NoSQL 应用服务中间件
搭建高可用及负载均衡的Redis
【7月更文挑战第10天】
178 1
|
5月前
|
负载均衡 安全 Cloud Native
云上负载均衡:构建高可用、高性能的网络应用架构
与云原生技术深度融合:随着云原生技术的普及和发展未来的云上负载均衡将更加紧密地与云原生技术相结合。例如与Kubernetes等容器编排平台集成实现自动化的服务发现和路由管理;与Serverless架构结合提供无缝的流量接入和请求处理能力。 安全性能提升:面对日益严峻的网络安全威胁云上负载均衡将更加注重安全性能的提升。通过引入加密传输、访问控制、DDoS防护等安全措施确保网络流量的安全性和隐私性;同时还将建立完善的安全监控和应急响应机制以应对各种安全事件和突发事件。 支持多协议和多场景:未来的云上负载均衡将支持更多种类的网络协议和应用场景以满足不同用户和业务的需求。例如支持HTTP/2、
267 0
|
5月前
|
负载均衡 算法 Java
实现高可用和可扩展的负载均衡系统的Java方法
实现高可用和可扩展的负载均衡系统的Java方法
|
6月前
|
XML 负载均衡 Java
Spring Boot 中实现负载均衡:概念、功能与实现
【6月更文挑战第28天】在分布式系统中,负载均衡(Load Balancing)是指将工作负载和流量分配到多个服务器或服务实例上,以提高系统可用性和响应速度。负载均衡器可以是硬件设备,也可以是软件解决方案。
295 0
|
6月前
|
负载均衡 应用服务中间件 开发工具
技术笔记:nginx和keeplive实现负载均衡高可用
技术笔记:nginx和keeplive实现负载均衡高可用