LBS检索容灾架构研究
2017-02-06符颖
符颖
摘要:文章结合LBS检索场景提出了一个稳定性容灾架构,通过过载保护、容灾环境、负载调度、分级发布等几部分相互配合,为在线检索服务提供了一个离线、在线相互配合的沙盒环境。该容灾架构能在任一个检索服务容量不足时快速地做出响应并将流量引导到安全环境下,保证对用户的影响降到最低,为服务的快速发布提供更多的保障。
关键词:容灾系统;过载保护;容灾cache;负载均衡;分级发布
随着移动互联网技术的不断发展,互联网开发模式采用持续迭代的方式来持续驱动服务的不断升级,并采用分级/灰度发布的方式实现在线迭代产品特性。互联网开发模式在快速改变着互联网研发生态的同时也引入了更多的稳定性风险,而服务的持续稳定是至关重要的,引入更快的迭代开发可能带来服务质量的下降,降低稳定性风险是研究互联网开发模式的重点。本文结合LBS检索业务场景,引入容灾体系架构,为快速迭代开发的业务构建稳定性的容灾环境,解决服务稳定性等问题。并设计一种主动容灾系统,其结合影响在线服务稳定性的若干因素,使其一旦发生异常时尽可能减少对用户的影响。
1在线服务稳定性综述
1.1影响在线服务稳定性的若干因素
影响在线服务稳定性的服务级因素因服务变更带来更大的稳定性风险。服务级的故障包括3个方面,其中用户请求包括突发流量和异常流量,突发流量可能导致服务上限被打破,异常流量可能导致整个服务的崩溃。变更包括服务变更、程序升级、基础数据的实时更新等。系统因素可以定义为服务所在的宿主节点的网络等突发故障或被争抢带来服务异常表现的一些因素。这类问题的触发本身是不可抗力的,但可以通过服务级的调度快速发现并隔离这些异常节点。
1.2主动容灾系统设计
主动容灾系统设计的主要目标是通过实时诊断监测可能的异常行为并立即进行补救处理,将对用户的影响降到最低甚至无影响。整体架构如图1所示。
整体架构包括4个部分:过载保护主要通过活跃线程状态指标快速判定服务当前是否处于过载状态,一旦过载就会立即拒绝无法及时处理的请求并向上汇报过载状态,主要通过检测活跃线程的状态趋势对服务状态作出可能的判断。容灾环境提供了保证服务稳定输出的在线环境,它由容灾cache和延迟环境2个部分组成。负载调度是面向服务的顶层节点进行调度,通过对顶层节点作过载判断或异常隔离来对顶层节点进行实时流量调度与负载均衡,当项层节点容量不足或不可用的时候,会实时将流量引到容灾系统。分级发布主要包括服务和数据的发布,通过分级发布实现数据或服务的灰度上线。
2在线稳定性系统设计
2.1过载保护
容量和性能对于在线服务是非常重要的,一般情况下通过扩容或性能优化不断地提升服务容量,满足更多的用户访问需求,通过不断的优化性保证用户的访问体验。对于在线服务而言,服务不可用是灾难性的。常规的容灾手段多数属于事后容灾,因此如何通过服务行为的变化快速诊断出可能的系统异常十分重要。
从容量的角度来讲,可以分为2个方面:一是极端情况下的服务宕机,会导致拒绝及服务容量的突然下降,服务宕机通过心跳或连接状态等都能比较快地发现;一种则是服务异常或流量突增导致系统临时容量不足,服务宕机进一步规约宕机也可认为是容量不足。
容量不足不等于系统完全不可用,需要极力规避服务容量不足时的雪崩效应以保证容量不足时的最大化输出,但处理不当就会导致整个系统的瘫痪,在这种情况下,一个稳定、可靠的拥塞预判检测机制就显得尤为重要。常见的拥塞判定方式包括:通过队列状态判断和根据QPS判断。
以上2个指标在系统的负载状态上都有一定缺陷。对于检索服务而言,磁盘读写、网络I/O消耗相对比较低,基于此观测每个线程的任务调度状态,如图2所示,其中绿色块表示被调度的任务。
结合图2,正常情况下在一个时间切片下活跃任务数比较小,在CPU利用率较低的时候工作线程大部分时段空闲,在线程数换I/0的模型下任务活跃代表占用了CPU时间,因为使用I/0消耗在总时间中的比例等比例放大工作线程个数,因此本文使用工作线程活跃状态表征系统负载。
在线程数换I/0模型下,工作线程数的设置一般会结合计算、I0的消耗去设定,如果在计算密集型服务下一般和CPU核数保持一致就可以,在I/0消耗的服务下可以根据I/0消耗占比调大工作线程数,使用I/0换计算。在检索线程模型下,设置合理的工作线程数代表了服务满载时的计算能力,因此当前服务CPU利用率的计算方法如下:
其中C代表线程计数,分子为活跃线程计数,分母为总的工作线程数,P则为CPU利用率。
对于在线服务来说,为保证服务的稳定高性能输出、多机房互备的资源储备,CPU利用率一般不希望超过40%,在这种情况下应当结合服务的计算、I/0消耗的比例,所能承载的最大活跃线程数也相应地确定。
活跃线程数指标是基于cPU利用率提出的,但磁盘、I/O出现性能问题的时候也同样会在活跃线程数上有一定表现。一般情况下总的工作线程数需提前计算,磁盘、I/0故障时CPU利用率不会明显变化,但性能会下降,活跃线程数也会快速膨胀,当活跃线程超过一定限度的时候同样可以被认定为过载。
一般情况下系统容量不足的时候会快速影响工作线程数,但活跃线程数的变化会有一个膨胀的过程,通过捕获到这个过程并快速处理,在系统实际过载前将无法处理的流量及时丢弃,直到活跃线程数稳定恢复到合理的范围,同时在流量丢弃的过程中不断地向上通报服务过载。
基于活跃线程数的过载保护机制如图3所示,为防止活跃线程数抖动对过载判断造成影响,本文过载判断设计了3个阶段:过载发现、过载模式和过载退场。
LBs检索系统由多个模块组成,采用的是相似的网络/线程模型,每个服务节点只对自己负责,同时接收下游节点服务的状态汇报,当前节点接收到下游服务的状态汇报状态时,会根据下游节点是否是关键节点向上主动汇报自己是否可用,形成一个逐级向上传递的汇报链。对于检索服务接入的第一个服务节点,称之为顶层节点。负载调度将检索服务与其他外部服务隔离开来。通过服务自身的过载及可用性判断形成了完整的过载判断,下游业务节点的状态通过处理并逐级上报后最终汇总到顶层节点下,顶层节点进一步将过载状态汇报给负载调度服务,完成检索服务状态的最终汇报。
2.2负载调度
在容灾系统的设计中,检索服务顶层节点以下的所有业务模块出现了影响整体容量的问题时,容灾系统应该都能检测出来并给出合理的处理。在这种情况下,容灾系统的设计需有一个负载调度用来隔离业务系统和外部接入,并在检测到顶层节点异常时及时触发容灾调度。为保证容灾系统的稳定工作,负载调度层需高度稳定,对其进行升级改造的频率是非常低的,所以将其设计为一个独立的服务。
ATR是负载调度服务,其主要作用是对下游节点进行状态管理,并根据节点状态进行负载均衡和流量分发。通过下游项层节点的主动汇报及ATR向下对顶层节点的主动探测来获取下游服务的状态。它的核心功能包括4个部分:过载检测、异常隔离、负载调度和ATR异常隔离队列,其中ATR异常隔离队列包括过载队列、异常队列、不可用队列和离线队列。ATR服务独立一层完成对检索服务的调度与稳定性隔离,下游服务异常时能够非常灵敏地将流量迁移到容灾环境中。
2.3容灾环境
前节中主要介绍了过载保护和负载调度,负载调度会将检索服务无法处理的流量引导到容灾环境中。容灾环境包括容灾cache和延迟环境。
在LBS检索场景下,结果状态由于和位置相关,结果级cache的命中率是极低的,由于容灾本身就是一种降级手段,在实际签名设计中考虑了位置的泛化,保留了核心请求参数对用户query作签名训练容灾cache,以泛需求检索[美食]为例,用户可能在相聚几十米的2个地方搜美食,结果是不一样的。在容灾降级场景下,其检索结果可以一样,对用户不会有明显的感知,本文采用加权投票的方式确定在一个geo区块内的cache结果选择,如图4所示。
对于检索服务而言,请求query分布有高中低频之分,高中频query连续2天都会有一定概率的重复出现,但一些低频query可能1年也出现不了几次,而容灾cache是基于历史日志训练的,对于命中率不能得到绝对的保证,在实际测试中,LBS检索下的cache命中率大概78%。
为保证长尾query的召回,在容灾环境中增加了延迟环境,所谓延迟环境是2天以前的线上环境的镜像,其数据和服务都是静止的,且经历过了至少2天线上流量的验证,可以认为是稳定的,长尾流量会被容灾环境进一步导到延迟环境做进一步的召回。
这样,通过容灾cache和延迟环境的相互配合提供了100%的检索容灾服务。为防止容灾服务对新版本客户端的影响,每一次发版测试阶段都会例行使用新版本客户端对容灾环境进行一次逆向验证。这种100%容灾是相对的,是建立在假定容灾环境和线上环境不会同时故障的情况下的,所以容灾环境的稳定性是必须实时保障的。
2.4分级发布
分级发布包括服务变更和数据变更的分级发布2种形式。通过分级发布,可以有效地控制因发布带来的稳定性、效果风险,通过只影响少量用户的快速验证,规避更大的影响,一旦发布出现问题就可以快速回滚。
发布阶段对稳定性的影响主要包括响应时间变差、结果不稳定、服务宕机或服务无法启动等,对效果的影响主要是检索结果质量变差。服务无法正常启动这类问题比较容易规避,而大部分问题往往都是在提供服务之后触发的。在正常提供服务阶段,处理流程命中了脏数据或局部分支导致内存被写乱都可能导致比较严重的稳定性问题,基于此,分级发布必然需要伴生在线测试来保证分级的效果。在线测试语料的选择要尽可能全面地覆盖业务场景、逻辑分支。另外,在线测试触发的时间点的选择也要尽可能地保证程序&数据分支己大部分被预热。
为防止在一些极端的场景下服务全部崩溃导致所有服务完全不可用,在线测试的时间点需要尽可能选择大于一次崩溃自动拉起的时间周期,这样即便有大面积崩溃也始终能保证大部分服务还可以使用,提供尽力而为的服务。
3结语
本文创造性地使用活跃线程数判定服务的过载状态,大大简化了过载判断的复杂度,减少了额外的风险。通过过载保护/负载调度/容灾环境构建了一个稳健的在线容灾系统,创新性地对容灾作了一个系统级的抽象,在其他的复杂计算的业务场景下也具有比较好的借鉴价值。
通过对复杂的业务线如检索提供容灾系统是很有意义的,在容灾系统的保护下对线上变更能更加从容,能比较有效地规避流量的突然增加、服务崩溃、服务性能突然变差对用户的影响。容灾系统上线后,检索服务还没有出现过因服务稳定性导致的服务拒绝。服务宕机导致服务大面积不可用这种情况的触发概率本身就很低,1年最多也就两三次,但一旦发生对用户的影响就会是极端恶劣的,一旦触发它的作用是巨大的,为此在日常的维护中需要绝对保证容灾环境的实时可用,避免容灾环境和线上服务同时不可用的惨况。