今天会重点跟大家交流我们SRE团队转型的背景和实施的路径,以及分享我们SRE体系的框架和思路,也会提及个人的一些思考。整个框架思路我们并不是一开始就设计出来的,而是面临着诸多的问题,围绕着解决这些问题一步一步演变过来的。
一、云原生运维转型之道
1、业务背景
如果大家有玩过游戏的话,对这个界面应该不陌生。我们团队主要负责腾讯内部游戏营销活动的运维支撑,在线营销活动除了为玩家提升游戏体验以外,也为游戏项目组在拉新、活跃,甚至是购买道具,都提供相关的营销活动、运营事件等商业化的支持。
2、微服务架构
这是我们的一个技术架构。从这个技术架构里我们可以看出,云原生已经变成一个大趋势了,我们团队95%以上都实现了微服务化。微服务化改变了开发的交付模式,同时也给运维带来了很大的变化,我个人的感受是挑战大于变化。以下6点是我认为现阶段我们面临的最大的挑战:
1)微服务调用链错综复杂,难于理解
尤其是一些大型活动,需要多个团队协同开发,会涉及到几百个微服务化的相互调用,整个微服务拓扑非常庞大,理解框架的难度加大。
2)追踪、指标、日志数据上报标准不一
每个团队都自建了不少监控平台或方案,这也是由于一些历史遗留原因导致。
3)无法快速定位服务问题以及根因
4)很难在上线前发现服务性能瓶颈点
5)无法判断节点间强弱依赖关系
6)新上线业务容量评估无法精准计算
业务上线时我们无法判断应该给予多大的服务容量,通常产品运营策划为了稳妥起见报得虚高,导致运营成本也会被同等拉高。
3、环境的改变
1)资源→资产
2)单体→微服务
3)管理→治理
我认为管理是一维的,治理是多维多元的,模式上发生了很大的改革。
4)事件驱动→流水线
5)DO分离→DO融合
以前开发和运维互不干涉,因为有“墙”的保护,也不需要给彼此背锅,在云原生的背景下,我们要求开发和运维要尽可能地融合,也是遵循了DevOps的思想。
6)业务运维→SRE
4、触发转型
我这里给出了一个转型的路径,个人判断总共会经历三个阶段:
1)第一个阶段:CloudOps(云端运维)
云端运维实际上与传统运维没有太大区别,只是把传统运维搬到云上,也负责云端的资产的采购、环境的部署,以及日常的运营跟运维,同时也会关注成本,比如FinOps就是要关注云端的成本。
2)第二个阶段:SRE
在SRE里会保留两种职能:
一是资深运维,最专业的和能力较强的运维职能会被留下来。
二是工具开发,很大一部分运维做转型时,具备一定开发能力的运维会转至SRE工具研发的职能上来。
3)第三个阶段:ServiceOps(运维服务化)
5、目标设定
1)具备服务全链路质量覆盖,定义可量化的SLI与SLO,不能出现任何一个盲点。
2)提升 MTBF(平均故障时间间隔)、降低 MTTR(故障平均修复时间)
3)DevOps升级至DevSecOps,关注云成本(FinOps)
4)具备多云多级的资产编排与治理的能力
一是能够提升效率;
5)具备一定的故障预警、根因分析、问题定位能力
通过智能化的水平提升我们质量方面能力的要求。
提炼中心思想就是云端一切皆可编排,加上我们“三位一体”的可靠性保障体系,这两个方向构成了我们第一期的整体目标。
6、SRE 8 准则
有了目标之后,我们还需要一些指导的原则,告诉我们应该怎么做。这里我也提炼总结出了8点,我们内部叫SRE 8 准则,今天我会重点把核心三点(蓝色框)提出来讲,其它更多准则说明可以扫描右下角的二维码查看。
二、SRE工具链建设思路
1、SRE体系全景
1)事件编排
事件编排的最底层要求是多云支持,因为我们的业务是跨云的,很多业务部署在北美、东南亚,所以我们要求跨云支持编排。
资产编排要求我们能够跨云实现资产的交付和自动化。
容器编排主要是k8s workflow这套机制。
作业编排就是任务编排,针对某个容器、虚拟机或云主机进行一系列功能性操作。
2)MTBF
即平均故障时间间隔,如何提升MTBF?
针对MTBF,我们希望是越长越好,要达到这个目标,以往我们在业务上线之前,这部分前置工作做得很少,通常是等发生问题后才被动地去做定位,所以我们尽可能地把很多能力前置,根据当前我们面临的实际情况,我们认为现阶段混沌实验&全链路压测是首要建设的能力。
3)MTTR
即故障平均修复时间,如何降低MTTR?
2、底层组织逻辑
接下来讲一讲我们实现这些能力的底层逻辑。
可观测性+全链路压测,能够做资源的精准评估。
可观测性+混沌实验,能够做强弱依赖分析。
全链路压测可以作为混沌实验压测的原子。
因此可观测性、混沌实验和全链路压测三者并不是割裂和独立存在的,而是一个整体,它们之间可以相互发生关系,能够产生一些我们意想不到的应用场景,还有很多有意思的点等待着我们去挖掘。
三、SRE工具链建设实践
1、可观测性实践
接下来我们讲的第一个应用是可观测性,举一个很简单的例子,就是我们运维经常碰到处理故障的一个典型过程。通常我们收到告警,第一步肯定是要去看Dashboard里是哪个曲线和图表出现了明显的异常,然后找出某个时间段异常发生的具体表现,是否有周期性,是哪个指标发生了异常,再切换到下一步链路追踪,分解出这个时间段,某个接口和方法是否延迟拉高了或报错了,通过追踪的方式定位。最后一步则是通过日志分析导致这个函数方法出现异常的根因,定位出来后即可解决这个问题。作为一个普通运维人员,经常按这个套路去定位与解决某个问题,在整个过程当中用到了指标、日志和追踪三个能力,实际上这三个能力就构成了可观测性的三大支柱。
指标:提供服务性能、业务及运营等指标,用于异常告警及可视化报表。
追踪:分布式链路跟踪,记录请求跟踪路径,用于定位到具体服务或方法。
日志:服务日志,提供精确全面的系统记录,用于最终定位问题根源。
很多团队将这三个能力分开建设,比如指标通常是搭建一个Prometheus采集指标,日志则搭建一些日志采取的组件,到ELK里进行检索,追踪则用Skywalking或Jaeger之类的工具搭建,再检索整条链路拓扑等。但是可观测性要求将这三者融合,即通过一定的符号、特定的ID,把这三种能力串联起来变成一个整体,这是可观测性追求的目标。
1)系统架构
2)平台能力
接下来是我们的一些平台能力,有基础能力,也有我们认为比较满意的一些高级能力。
综合管控治理
ONE-SDK
我们把指标、追踪、日志这三者集成到某个SDK里做上报。目前Opentelemetry的官网里也只是定了规范,还没有完全地实现三者能力的集成上报,局部的开发语言SDK可能已经支持了,比如Golang,更多的还是处于内部联调和测试的阶段。
提升采集ROI
我们会开启采集的管控,当出现极端情况时,我们只采集有价值的数据,比如只采集异常的数据,其它的统统不采,因为产生异常的数据可能占比不到1%,量是很小的。
3)综合治理
我们的综合治理分为采样治理和运营治理。
①采样治理
头部采样:在入口开启采样,只采样自定义的比例,如2%或10%。
尾部采样:数据会先全量上报,通过缓冲池缓存数据,再异常处理,过滤出有异常的数据后入库。
数据冷热分离:考虑到后端高昂的存储成本,我们做了分级(三级),比较热的数据存放在ES里,超过一周的数据周期我们采用Clickhouse作为二级存储,存储一个月以上的数据我们存放到离线数仓中,那么成本就越来越低。
②运营治理
更多是一些数据采集干预方面的手段,比如熔断、降级、限速和染色。
染色即为打特定的标签,定义染色数据上报规则。比如我只关注某个玩家的登陆,那么把玩家的ID打进去,它只采集该玩家的整个生命周期产生的日志,其它统统不采。
Receivers:负责接收不同格式的观测数据,包括Zipkin、Jaeger、OpenCensus 以及Opentelemetry格式。
Processors:负责实施处理逻辑,如打包、过滤、修饰、采样等等。
Exporters:负责将处理后的观测数据按指定的格式重新输出到后端服务中。
Extensions:以旁路的模式来作为Collector本身健康心跳探测等。
4)异常检测
当我们采集大量的数据之后检测出异常点,此时需要定义告警,很多情况下会出现如指标毛刺等带有故障特征但实际上却不是故障的情况,为了减少误告,我们结合AIOps的技术做了一些探索,目前也取得了一定成效,具体的思路如下:
我们采集最新几分钟的Trace与Metric的数据,通过训练好的模型去推理异常权重,识别出的异常Trace再通过告警发出,由此可以看出我们的特征模型非常重要,那么如何确保这个模型的准确性?有一个方案可供大家借鉴,我们分为两个阶段来实施:
第一阶段是测试阶段,结合压测与混沌能力,在源头做流量压测及混沌实验,我们通过模拟CPU爆满、流量异常或丢包等等已知的故障原子,再结合压测的手段,观察服务表现出来的各类指标数据,这就是我们想要的特征,通过平台自动化给特征打标签,可以释放大量人力参与此类工作。
但是再完备的测试环境也无法模拟线上所有问题,比如一些未知的问题我们历史上从未碰到过。所以会在第二阶段(即将上线),我们会去采集现网真实的数据做验证,不断地扩充跟修正特征模型,使模型越来越精准,但是生产环境时则不可避免地需要依赖人工去打标签。
我们采用的是Matrix Profile的算法,在此之前我们也盘点了行业内十几个针对Trace的异常检测算法,从推理速度、准确性和参数调整的变异性等维度进行选型,我们发现Matrix Profile这个算法是最接近我们需求的。Matrix Profile 的值表示子序列间的距离,距离越小的表示序列相似度高,而距离越大表示越异常,异常则对接我们的告警,我们当前这套的准确性能够达到大约83%。
2、混沌工程实践
混沌实验不少企业都已经在引入并积极建设,更多是通过模拟真实现网的故障注入,发现服务是否存在异常或弱点,但我个人觉得它的好处不仅限于此,对于SRE而言,它的价值在于一句古话说的:平时多流汗,战时少流血。我们平时模拟了大量的故障案例,在真正面临故障时则能够坦然面对,心里不会慌,包括在预防、发现、响应、定位方面都给我们积累了大量的经验,使我们能够快速处理和解决问题,我认为混沌的意义应该在于此。
1)平台架构
这是我们的整体架构,这部分我们跟社区合作的比较多,比如PingCAP的Chaos Mesh,我们也参与了共建,所以很多原子是开放的,平台能力也很成熟,基本上用于做一些能力的封装,比如上面的编排、演练、模板,官方也带了一个简单的管理端,如果要求不高可以直接用。
2)平台能力
这是我们的平台能力,分为基础和高级。我们平时做得最多的是红蓝对抗,红蓝对抗就是通过攻防不断验证可靠性是否达到要求,达不到则持续修改迭代,发布过后再进入下一轮攻防,还是比较有趣的,同时可以做一些依赖分析等能力。
我认为服务强弱依赖分析是很有价值的,可以轻松感知如A调B服务,B出现问题对A是否造成影响,我们分为三步来实施:
首先,基于可观测性技术,追踪到服务间的上下游依赖关系。
然后,对下游服务注入故障,如丢包、超时、响应慢等。
最后,观察主调方的稳态指标,如QPS、延时是否受影响,如果受影响则存在强弱依赖关系,从而要求开发进行改造,比如在主调方做一些访问DB的缓存等策略,达到要求后才能够上线。
3、全链路压测实践
最后一个是全链路压测,我认为它的意义主要是两点:
一是能够发现上线之后的性能瓶颈点,因为导致性能瓶颈的因素很多,如环境、参数配置不当、数据库、网络等,逐个排查成本过高,可以通过压测发现。
二是重大节点的运营保障,容量与负载没有线性关系,无法精准判断容量够不够,压测一下便知道。
1)平台架构
2)平台能力
3)服务压测链路拓扑
接下来我想讲全链路压测其中的一个应用,即服务压测链路拓扑。我们在源头施压,平台能够完整地呈现整个观测链路,展示微服务间的调用关系链,同时能够实时计算出每一层微服务黄金指标,即A调用B的耗时、QPS、延迟、放大倍数等都能计算出来。
4、总结
最后总结SRE实践里的几个过程。我们从立项到结项,通过技术与文化两个层面落地。
1)立项:我们会组建一个FT的临时团队,团队里有运维、开发、测试、产品等,运维也会参加技术方案的讨论,同时定制可观测性上报的规范。
2)开发:开发需要落实运维制定的规范,做好指标埋点的上报,同时SRE会参与技术架构的评审。
3)测试:我们会在这个阶段大量地做混沌实验和全链路压测。
4)上线:更多关注SLI、SLO等指标和它的错误预算,以及OnCall的机制是否完备,提前准备好故障预案。
5)结项:对整个项目从立项到下线整个过程中,做得好的和不足的点进行复盘和总结,沉淀的经验以便复制到下一个项目当中,同时我们会不断完善整个SRE工具链的全景图。
Q&A
Q:如何在全量采集和采样采集之间找到平衡?
A:全量采集和采样采集没有好坏之分,与业务场景有关。实际上我们也有一个项目要求必须要全量,因为对账要求全部都要采样。但除了这种以外,基本上都是按一定的比例去做的,一方面可能与业务要去谈适合的采样比例值,因为我们无法判断是5%还是10%,是没有标准的,可能前期我们在与研发做项目评审时,实际上这个比例已经谈下来了。另一方面我们在入口做全量,后端做尾部的情况占的比例也比较高,大约是40%,就是入口都放过来,但是真正到后端不会全部数据落地,只落地1%或不到。我认为尾部采样才是有价值的,因为它只过滤有异常的、错误的或断链的等,捕捉到这个标签并把它存下来,那么数据量就很小。但是另外一种情况是项目刚上线时或不同类型的活动和项目,要求要拿到其特征,那么就相当于要求前期要全量,后期关注成本再慢慢压下来,所以我们分不同的阶段和诉求做不同的策略。
如果字段的最大可能长度超过255字节,那么长度值可能…
只能说作者太用心了,优秀
感谢详解
一般干个7-8年(即30岁左右),能做到年入40w-50w;有…
230721