阿里十年总结:超大规模资源和成本管理的前世今生
背景
资源和成本管理一直都是SRE工作的重点之一,笔者在阿里巴巴工作十年,始终没有离开资源和成本管理这个领域。今天阿里集团已经有了成本中心(HCRM)的最佳实践,可以覆盖几乎所有硬件资源相关的管理。笔者十分有幸,从最初的蛮荒时代,一边被裹挟一边自己探索,参与其中,并有幸在当前成本中心工作。
资源管理经历的历史阶段
第一阶段,关注池化率。也就是可管理性。只有放入统一调度的资源才是可以被自动管理的资源,放到excel或者CMDB中的资源只能算弱管理。这对于从非调度器过度到调度器管理的团队十分重要,如果有一个传统软件团队生成引入了k8s,并且效果如何如何好。这个时候我们应该谨慎的追问:池化比例有多少。
第二阶段,关注分配率。分配率指的是已经池化过的资源,日常被分配出去的比例。这个比例包含两个因素:第一个是分配能力,第二个是应用是不是够多。影响分配率的具体技术因素可能包括:应用的规格、申请资源稀缺程度、碎片率等。分配率这个指标在池化率不高的情况下没必要追求极致。
第三阶段,关注利用率。利用率指的是分配出去之后的资源,具体使用情况如何。从MAX到AVG再到Effective,盘点清楚机器之后,我们有机会在全局看清楚和提升利用率了。
第四个阶段,关注全局成本。全局成本指的是:计算成本+存储成本+网络成本+其他成本。第四个阶段可以和第三个阶段并行,这里放在第四阶段主要是从宏观角度考虑。不过从经验上看,一般都是把计算资源利用率管理到一定程度(avg 30%)才能有能力管理好所有云产品的全局成本。迁移上云之后,随着管理手段的丰富,让我们看到了除了cpu之后更多的成本构成,这些成本数量巨大,是房间里的大象。
最后,我们再尝试回到业务视角。在研发团队眼中,成本并不是全部。研发团队有时候不得不在迭代效率、资源成本、稳定性之间做出取舍。我们在最后讨论下三者之间的关系。
资源管理模型
Total:成本角度,所有付费买的资源,不管这个资源被使用与否。
Pooling:管理角度,所有可以被管理到的资源,狭义上可以理解为所有调度器管理的资源。非调度器管理,人通过CMDB管理的阶段也可以算作Pooling,不过这个是非常弱的管理,PR值很难统计,即使有统计,也很难验证正确性。
Allocate:在Pooling资源中被实际分配给业务使用的资源。这里仅仅是分配,使用情况如何是不看的。
Used:Allocate出去的资源中,实际业务使用的资源。例如CPU中指的是cpu-used,storage中指的是实际存储用量。
Effective Used:在Used资源中,考虑池化、混部等影响,有效的资源使用。例如cpu-used这个指标,同样的容器,宿主机上的负载不同会导致相同流量下,cpu-used不一样[2]。Effective Used也可以理解为归一化的cpu-used。
Pooling Ratio=Pooling/Total(PR):池化率,主要考察的是资源管理水平,不是说没有池化的资源就一定无法使用,而是池化的资源在调度效率和自动化水平上都不再依赖某个SRE的管理水平。整体上这个值要超过95%才算是一个管理水平比较高的资源板块。
Allocate Ratio=Allocate/Pooling(AR):分配率,已经池化的机器会有很多原因无法分配出去。例如:内存碎片、异构需求无法匹配、规格太大无法匹配,这些因素都会影响分配率。一般在高峰期做到95%以上的在线分配率是比较合理的。
Used Ratio=Used/Allocate(UR):利用率,有很多资源都有利用率,比如cpu、mem、disk、net、gpu等。主要看服务器是以那种资源为主要资源。在线计算集群一般是cpu-uesd,如果是存储集群可能就是disk-used。而且利用率还需要区分是MAX还是AVG。
Effective Used Ratio=Effective Used/Allocate(EUR):有效利用率,在一些特殊的情况下需要考虑。比如在计算集群中,cpu-used就是一个可以挑战的指标,考虑池化、混部的影响之后对used进行归一化后的有效利用率。这个指标的计算标准业界还有争议,不过问题确实是存在的。
Effective Used over Total Ratio=Effective Used/Total(EUTR):全局有效利用率,这个指标代表着整个公司的资源管理的总体水平,是一个CTO视角的指标。它受太多因素影响,包括上面提到的PR、AR、UR、EUR,从公式上推到EUTR=PR*AR*UR*EUR。如果对于EUR还没考虑那么取EUR=1,这种情况我们不单独定义了,就是我们常说的集群/资源池的混部利用率。从模型的定义来看,我们可以得到如下简单的结论:
1>=PR>=AR>=UR>=ERU
EUTR=PR*AR*UR*EUR
第一步:提高池化率
能运行就行
管理软件:excel
资源规模:千台物理机(仅统计搜索广告)
成本意识:没有成本意识,只要不出稳定性问题即可
核心问题:线上化管理诉求
小结:这是一个草莽的时代,这是一个草创的阶段,所谓资源和成本管理,基本就是没有管理。
方便管理
管理软件:CMDB。CMDB开始承担主要的资源管理责任,在集团内部主要是armory系统。armory的核心是应用分组。机器资源按照不同的应用,放在不同的应用分组中。由此展开,中间件、监控系统、cicd发布系统、应用管理、资源管理都围绕着“应用分组”展开。通过应用分组内的ip变化,来体现业务的资源变化。
资源规模:超过五千台(仅统计搜索广告)。这个时期已经有了多个地域部署的需求了。几个资源消耗大户逐步形成各自的管理体系。几个资源大户分别是:ODPS/Hadoop为代表的计算平台、搜索广告、交易导购、数据库。
成本意识:这个阶段大家谈到资源和成本,仅仅指的是服务器资源。而且几个资源大户都是各自为战,有可能有相互解借调的情况,但是仅限大促等紧急情况。对于业务团队来说,成本是无法统计的。
核心问题:部署服务,管理机器的效率极低,长期有呆滞的机器停留在各个角落。
小结:这个阶段核心解决了管理复杂度的问题。通过使用CMDB的应用分组能力,把应用、中间件、资源关联到了一起。PR仍然无法统计,仍然可以看做是0。从cpu max统计来看,日常还是低于10%,不过ODPS为代表的计算平台已经比较高了,那里主要跑的是批量job。
方便扩缩容
管理软件:K8S/ASI/Hippo/Sigma。调度器在这个阶段中起到核心的作用。从2015年开始在集团内部的搜索引擎率先上线使用,到后来Sgima和ASI上线,并最终在最后统一到ASI(兼容K8S协议)。调度器的广泛使用让资源管理来到一个新台阶。服务器节点具备了自动上下线的能力,解决了CMDB阶段呆滞的问题。同时业务的扩缩容能力得到极大提升。CMDB阶段必须依赖有经验的SRE扩容新节点,到了调度器阶段具备了根据目标描述扩容新节点的能力。除了效率上的提升,资源呆滞率下降,节点自愈速度显著提升。
资源规模:超过万台(仅统计搜索广告)
成本意识:这个阶段仍然是业务蓬勃发展阶段,AI技术逐渐落地,2015年第一次上线AI宝贝推荐代替传统意义的运营选品。这隐含了巨大的资源投入。虽然在预算阶段开始讨论成本,但是还停留在单机TCO上,没有整体的成本意识,最终还是为业务让路。
核心问题:池化率比较高之后,资源分配率开始被关注了。
在PR提升过程中,有几个关键点。
容器化不能自动解决PR问题:这是技术准备。容器化只是解决了单实例部署的环境问题,必须配备对应的调度器。这个调度器需要具备如下的能力:可以屏蔽底层的计算(至少是计算)资源,提供坏节点感知和通知能力;应用有中心控制可以响应底层的通知,并具备自动迁移的能力。不管是有数据的搜索引擎,还是无数据的普通java应用,都必须解决这些问题。
提供平滑的迁移方案[4]:这解决头部应用。要和原来的部署方案平滑迁移,降低应用管理员的成本,能做到无感知最好。不过根据具体经验,应用池化的过程,一定是需要应用管理员参与的。
解决顽固的应用:这解决长尾应用。永远都无法忽视顽固的应用,可能是因为应用管理员排期问题,可能是因为应用由于不断地交接已经找不到管理员,疑惑是纯粹的对新的技术方案不信任。如果出现这种状况,一方面要勇于承担责任,勇于下线和接手无主的应用,另一方面在资源上限制其扩容和发展。
利用文化因素:不用想一蹴而就,PR从30%提升到95%花了接近3年的时间。SRE需要在一切可能得场合,宣讲池化的目标和优势,并需要技术leader的长期坚持投入。如果技术leader口是心非,你有两个方法应对:一个是说服他,一个是等他离开团队。这依赖于你的具体判断。
小结:随着管理节点的增加和业务复杂度的增加,用调度器解决管理复杂度势在必行。在业务从单独管理,改到调度器管理,需要基础设施团队提供非常好的管理工具,单纯的容器化并不能解决问题。需要长期的技术投入和文化坚持,才能达到比较高的池化比例。
本章总结
第二步:提高分配率
业务资源申请规格多样化:不同业务场景所需的计算、存储资源不同,因此单一集群里会存在大量标准型,内存型,存储型等类型应用,而机器资源均为标准型,二者规格不一致;
业务申请资源不合理:业务申请资源没有参照体系,经常出现资源申请与实际使用相差过大,并且没有事中事后纠正机制,造成严重的资源浪费与成本提升;
调度器从实时性能角度考虑无法做到调度完全最优,业务发布迭代,弹性扩缩等时刻破坏着集群的规整度;
离线训练类任务对资源可用性、调度时效性带来了全新的更高要求;
异构机型的引入,AI场景模型越来越大造成单一维度资源严重失衡;
尽量使用通用资源
硬件迭代:cpu从Skylake升级到Cascadelake,再到Icelake以及之后的SPR,每一代再工艺和单核性能上都有提升。GPU从T4到V100再到A100,工艺和性能也在变化。对应的网络也从10Gbps,到25Gbps,再到现在最新的100Gbps。总会有应用需要对硬件做出约束,所以tags在硬件迭代层面就是无法避免的。不要试图去根据硬件规格划分独立的集群,一般的node过保时间是4年,每年都有硬件的更新迭代,如果根据硬件规格划分集群,集群数量将会是指数型的增长,最终到无法维护的程度。
文化因素:有人的地方就不可避免的有文化因素,池化的过程一般持续3年的时间,期间会涉及到各种谈判与妥协。这些妥协中不可避免就会出现短时间独占协议。承认他,同时相信资源管理水平的提升会让大家放心的接受资源管理的方案。
不必要的node tags:其他因为各种原因导致的tags应该尽快清理掉,监控他们的存在。
不必要的应用 tags:应用在启动的资源描述中,可能会包含非常苛刻的资源限制,比如cpu主频大小、cpu规格、机房。这种资源限制越多,就约难以申请成功,也会导致后面讨论的碎片整理越难以执行。至于应用提出需要node性能完全一致,以便每个容器的负载一致,其实解决方案有很多,典型的方案就是rpc调用的负载均衡,我们不在这里展开了。总之,应用要求所有node完全一致是一个妄念,也是可以被解决的。
资源碎片整理
整体方案
存量碎片整理
堆叠优先:这其实有个反复的过程,最开始是追求负载均衡优先的,但是发现这会引起分配速度和分配率的下降。堆叠优先的策略就是一旦有机器分配了容器,就想办法把这个节点的所有资源用满。“凡是有的加倍给他,凡是没有的连他所有也夺过来”。空出的整节点会让未来的分配产生更快,也更加少的产生碎片。
有限步骤:迁移步骤如果完全追求最优(实际这是个装箱问题,找不到最优)有可能发生过长的搬迁链条。我们在实际生产中根据优雅上下线的时间消耗,将迁移链长度控制在5步。
循环迭代:碎片整理不需要一步到位,上面提到了有限步骤,这无法直接到达比较好的状态。通过不断地循环迭代,来应对有限步骤的问题,和应用启停的新碎片问题
增量碎片整理
和存量碎片整理相对应的是增量碎片整理,指的是新启动时为了给新应用尽快找到合适的节点启动起来而进行的碎片整理。增量碎片整理的核心是快速启动应用,所以不能进行长时间的离线计算,也不能规划多跳的复杂迁移方案。具体来说可能需要注意以下策略上的选择。
速度优先:堆叠整理出整机不再是首要考虑的目标,哪怕是产生了更碎的碎片,为了即使整理出局部解也是在所不惜的。
单跳步骤:一般情况下,启动都是要求分钟以内的,所以都会选择一跳的迁移方案。
循环迭代:循环迭代的原则仍然有效,不过这个循环的周期要非常短。不断地去扫描集群中等待分配资源的队列,及时形成迁移方案。
容器规格整理
尊重真实情况:一个反例是,为了提升分配率,强制将所有的应用划分成几个规格,不管应用真实的需求是不是匹配,也必须选择这几个容器规格的一种。这只能带来表面的繁荣,背后就是对于资源的浪费了。一个典型的例子,比如应用最小部署是4个容器,每个容器只需要1core+1G就可以,但是因为没有规定这么小的容器规格,他只能选择4core+8G的规格。还有一类案例是,经过压测后容器规格30core+50G可以满足最小规格的要求,但是只有32core+64G的可选,那么他只能选择浪费资源的规格。
应用画像:比较合理的办法是,应用初始化时,推荐一个规格。等应用启动上线后,不断地对应用的运行过程进行监控,获取运行数据后,离线计算出每个应用更加合理的规格。我们把这个过程称作reshape。需要注意的是,进行reshape还有一种更加困难,但是也更加有效的方法:simulation traffic daily run。每天用影子流量压测影子应用,来得到应用最合适的规格,而且随着应用和流量的变化一直变化。这个高阶的要求,不用特别追求。
本章总结
第三步:提高CPU利用率
CPU峰值利用率
业务代码优化
这是一个宽泛的说法,具体优化方案要根据业务最对代码的分析结果再采取措施,比如异步化改造。但是一般也有公认的利用率友好的限制条件。
应用容器CPU利用率可以跑到60%以上,而不会有明显的超时
超出标称的服务能力后,不会发生雪崩。在绝大部分条件下都能服务好标称服务能力内的请求
对于硬件资源的使用比较均匀,不存在明显的短板。比如网络已经打满了,但是容器cpu却只跑到20%,这个时候应该调整规格,均匀的使用硬件资源
VPA
VPA解决什么问题。低利用率应用降低日常资源浪费;短暂的突发流量自适应扩容。某大型业务线全站90%以上在线JAVA应用的CPU日均利用率低于15%, 内存日均利用率低于50%。但是因为需要异地或者同城容灾的需要,又至少部署6个甚至更多的容器。
VPA第一阶段:应用画像。应用画像是离线采集每个应用的Allocate和Used数据,计算出更加适合的部署方案(包含pod与pod之间的share CPU的最优方案)。
VPA第二阶段:CPU share。linux内核提供cpu.shares、cfs_period_us和cfs_quota_us三个参数, 通过控制cfs_quota_us/cfs_period_us比值, 可以精确调整容器的cpu分配量。比如一个4核容器,通过将其规格画像为requests.cpu=2, limits.cpu(最大cpu使用核数)=12, 同时在底层cgroup将cfs_quota_us设置为1200000不变,保证业务的资源与其他CPU share的业务共享12核,如图3-1。
VPA与CPU峰值利用率的关系。可能大家会有疑问,VPA并不能直接提高整个集群的CPU峰值利用率呀,为什么要把VPA机制放到提升CPU峰值利用率的范围内讲呢。这其实是个误解,从绝对值上说VPA确实无法直接提升整个资源池的利用率,但是VPA其实一种软降配。软降配能够空余出更多的核来,这样可以用不变的资源池大小,来跑更多的在线业务。从这个视角上来看,他是能够提高CPU峰值利用率的。我们用图3-2 CPU share2 更加直观。虽然App1~App3的CPU Shared Pool从12核下降到8核,但是相比原来CPU Set时每个App最多使用4核还是提高了上限的。同时经过CPU Share之后,可以多调度一个App5进来跑。只要App5不是空转,就能够提高在线CPU峰值利用率了。
HPA
HPA解决什么问题。HPA就如同他的定义一样,是进行自动扩缩容用的,它实际上是一个高效的负反馈系统[6]。如果应用负载高了,就自动扩容,如果应用负载低了就自动缩容。在提高CPU峰值利用率方面我们只讨论自动缩容的方面。
HPA快扩慢缩。在缩容过程中,生产上曾经做过多次尝试,社区也很难达成一致。目前k8s上默认的参数是扩容3分钟、缩容5分钟。但是实践中,我们会遇到很多问题,例如一个应用是有数据的,它的启动需要至少10分钟,这个时候我们缩容简单,但是扩容的时间代价很高,所以缩容要十分谨慎。还有类似外卖业务,在中午下班时间左右会有一个突发的高峰,本身持续的时间短,留给调度的反应时间也很短,使用默认的5分钟缩容会遇到严重的超载问题,应用管理员宁愿永远都不缩容了。实际上,我们在生产中采用的是默认24小时的观察窗口,也可以根据具体的应用进行调整。
脏数据。包括数据延迟、数据为空、数据错误。这个问题似乎很少在各种文章中被提及,实际上是个非常重要的问题。虽然只在上面的图3-3中简单描绘了原理,但是Metrics在收集生产容器的数据过程中,链路是非常长的。在整个Metrics负反馈的过程中,可能会发生数据采集错误、数据传输延迟、数据丢失等问题。这时候进行快速的扩容可能风险不是很高,但是进行快速的缩容就有极高的风险了。在实践中,上面提到的三种问题都发生过严重的生产故障。所以,必须对脏数据进行严格检测,一旦检测出来,兜底最简单也非常有效的策略就是:什么都不做。
文化因素
直接的指令:直接下单给团队CPU峰值利用率的目标。实际上有很多研发团队就是这样做的,需要注意的是,这必须有配套的系统保驾护航(比如HPA),而不仅仅是一次运动,否则有效期很短。我有非常尊敬的研发团队管理者,每年都会给团队设定一个技术优化的目标,这是非常少见且难于执行的。
成本激励:更加普遍的情况是,被激励。一般可以使用的激励手段就是成本激励,可以给参与CPU share或者CPU峰值利用率已经做的非常好的团队予以资源降价、少收费等策略。
小结:在线应用的CPU峰值利用率决定了一个资源池“应该”多大。我们通过提高每一个在线应用的CPU峰值利用率,来达成整个资源池的CPU峰值利用率。具体的方案可能包括:提升代码质量、VPA、HPA和善用文化因素。
CPU均值利用率
前提:隔离技术
内存带宽[8]:单独说说,内存带宽是当前混部离线任务呈现出作业多样性,除了常见的计算密集型、io密集型任务之外,AI场景下也出现了以深度学习为代表的计算访存密集型任务,其典型特征是cpu使用率高,访存带宽则非常高。单个AI训练worker实测最大使用带宽可达75GBps,这已经基本达到了skyLake和CascadeLake这两代CPU的设计极限了,会严重影响其他在线业务的性能。一个实测案例是当机器处于轻负载时,整机ipc一般为1左右,而当内存延时达到400+ns时,整机IPC则下降到0.6~0.7左右,下降有40%之多。单纯的使用iceLake就可以大幅缓解离线混部的相互影响。
技术方案:离线混部
区分优先级。线上一般分为几类业务:在线业务、离线业务、基础组件。他们分别有不同的优先级,体现在内核参数上就是cpu.bvt_warp_ns分别对应着在线=N+1,离线=N-1,基础组件=N。当某个CPU调度队列中有多个Runable状态时,优先调度cpu.bvt_warp_ns数字高的。
绑核机制。整个CPU的cgroup分几个大组。在线大组可以绑定所有的核,用cpuset.cpus来设置在线每个进程的具体绑核。离线大组也可以绑定所有的核,用cpuset.cpus来设置在线每个进程的具体绑核。基础组件大组内所有的进程绑定所有的核。
在线压制离线。根据上面的绑核机制可以推导出,一个CPU可能同时被多个进程绑定,当有不同优先级的多个进程处于Runable状态[9],时间片分配会根据cpu.shares的数值来分配时间片比例,把在线进程调度起来运行。cpu.shares的离线的数值是m,那么在线的数值可以是1000*m,这样看起来的效果就是一旦有在线进程处于Runable队列,会马上抢占CPU。看起来的结果就是在线忙时,离线跑的少;在线闲时,离线跑的多。在线随时可以压制离线的CPU。
在线抢占离线。CPU可以被在线和离线重复绑定,并根据压制策略来共享。但是MEM是无法共享的,有在线任务要分配到某个节点上,而节点上的MEM等资源不够时,会将离线进程杀掉。在线将会对离线进行最激进的抢占。
快照与恢复。很多离线训练的任务,是有中间状态的,如果不对中间状态做保存,一旦被杀掉就需要从头开始跑。这种情况是无法接受的,所以混部的离线任务都需要具备快照与恢复能力,能够从断点处重新开始运行。
大规模的条件:单机利用率精确控制
利用率压制:单机利用率压制是大规模实施混部的条件,如果无法做到会遇到在线业务严重的反弹。在内核中已经提供了cpu.cfs_period_us和cpu.cfs_quota_us两个参数来控制离线cgroup下可以跑的最多的核数。生产上最高可以控制单机利用率到70%,离线cpu.cfs_quota_us值需要根据在线跑的水位动态来设置,以便保证单机利用率始终保持在接近70%的水平。如果有非常敏感的在线业务,可以需要根据某种规则调整单机利用率的压制策略。
小结:通过在线业务与离线业务的混部,是提高整个资源池CPU均值的核心技术方案。Linux隔离技术的成熟,让混部技术得以在大规模范围内实施。当前阿里巴巴核心集群CPU日均利用率已经达到55%以上(表3-2所示),离线任务相对于之前独立集群,几乎免费使用着500万核以上的CPU资源,极大的节省了成本。
CPU有效利用率
起因超线程:芯片厂商为了造出更好的CPU使得应用运行更快,研发出一种称之为Simultaneous Multi-Threading(SMT)的技术, 这种技术使得CPU core(译作:CPU物理核)可以同时执行来自多个线程的指令, 看起来一个CPU core被虚拟成多个,然后每个虚拟的Core都可以执行指令。Intel在x86 CPU上的实现称之为HT(Hyper-Threading), 一个物理Core虚拟成两个硬件超线程(HT)。
超线程的问题:超线程出来的逻辑CPU有共享的硬件,也有独立的硬件。共享的硬件如果产生非常大的竞争就会导致CPU Used虚高。独立的部分包括:比如RAX,RBX等通用寄存器以及一些控制寄存器,如EFLAGS,GDTR等,这些寄存器没有在两个硬件超线程之间共享的。还有Local APIC,用于接收硬件中断,每个硬件超线程有自己独有的一份;共享的部分包括:Execution Engine和Bus Interface, 这些CPU部件在硬件超线程之间共享,硬件超线程除了共享Execution Engine和Bus Interface之外还共享了L1 Cache, L2 Cache. Core与Core之间共享了LLC Cache。我们可以很明显的看到CPI在不同机器上的差异,以及同一台机器上不同时刻的差异,引起这些差异的很大原因就是HT之间相互刷Cache导致Cache Miss上升,进而导致CPI上升,CPU Used会无效提高。
更合理的CPU公式:抱歉,虽然有效CPU利用率已经被各大数据中心注意到,但是截止到现在,也无法给出一个大家公认的公式,目前仍然处于协商不一致的阶段。我们一般有两种思路进行有效CPU的计算,一种是通过内核中更改统计方法,一种是根据已经采集到的PMU的信息进行重新计算矫正,我这方面也刚开始了解,本文仅仅提出这个问题让大家关注,可能几年之后才能逐步有共识。
小结:CPU有效利用率是因为超线程等因素引起的,表现为容器相同的负载输入,会因为宿主机其他负载而导致表现出的CPU利用率不一致。目前CPU有效利用率还没有统一的计算公式,业界一般有操作系统新增计数器和外部已经采集到的指标矫正两种思路。
本章总结
第四步:在云上控制资源成本
云上资源成本构成
超大规模云原生用户如何管理资源
清晰全面的账单
云产品的生命周期管理
HCRM领域模型[11]:虽然实现模型很复杂,不过我们去掉细节其实包含如下几个核心模型。分别是:预算-->需求-->交付-->额度-->用量-->账单。我们下面分别介绍着几个核心领域。
预算:预算是资源管理的起点。最开始的预算,都是excel表格汇总,每年负责预算的项目组出一个表格模板,然后大家按照模板录入,不同的云产品有不同的表格。可以想象的出来,当云产品多了后,表格和其版本漫天飞,根本无法管理。预算管理第一步就是将各种云产品的预算入口收到一个系统中,系统中使用快照的方式有统一大版本,这样众多业务团队就可以在一个平台上进行工作和讨论。
Down2Top:这是一种预算模式,是天然的从excel表格过度来的模式。其思路就是每个业务团队,甚至是每个开发自行填报每项云产品的用量,历史信息只是用来做辅助参考。这种模式的好处是,尊重每个业务团队的自身特点,可以允许各种“特殊”的考虑。在实际运行中也会遇到很多的问题,最突出的问题就是“填报反复”问题,实际上并不是填报多少就审批多少,业务的总裁还是对自己的业务和成本有一个基本的判断,当超出时就会要求降低预算。但是降低谁,保留谁就变成了一个拉扯的过程,这个过程一般要反复至少3次,导致一线开发非常反感,浪费大家时间。
Top2Down:与Down2Top相对应的就是Top2Down模式。在烈火烹油的时代,预算并没有那么谨慎和严格,所以Down2Top模式一直能够运行。但是进入平稳发展期后,成本对于每个业务团队都变得异常重要。对于预算的管理就逐渐趋向于自顶向下管理。首先业务大团队确定一个金额上限,HCRM会根据上限初始化每个云产品预算(包括预算对应的量的信息)金额。然后每个子团队都可以进行云产品的预算调整,但是整个调整过程是不能超出上限的。这种方式能够严格限制成本,所以逐渐成为主流被接受的模式。副产品是,一线研发不在需要反复录入预算的环节,全部由HCRM承载。
需求:需求这个概念并不是一开始就有的,是在运行过程中,逐渐从“预算”中剥离出来独立的。之所以做这样的剥离,是因为支持业务灵活调整的需求。从我们上面介绍的预算概念可以推到出,如果仅仅有预算卡死,业务的变化将无法支持,如果允许预算随便的修改,那么参照标准会丢失掉。所以为了支持在年初预算基础上,灵活的调整,把“需求”独立出来,需求的初始化版本和预算是相等的,但是在预算结束后,仍然允许业务团队调整,这时候就变成了需求的调整,预算变成了一个历史对比快照。
需求调整原则:只要预算金额没有超出,可以调高某款云产品的需求。需求调整后可以获得更高的交付额度,也就是开出更多的资源。如果预算金额已经用满,这时候再想调高某款产品的需求,有两种方式。一种方式是追加预算,这需要业务团队财务和总裁的批准,是比较严肃的。另一种方式是先调低其他产品的需求,空出来的金额就可以用于调高另一款产品。
需求调整对库存的影响:调整需求对于供应链团队是有备货依赖的,一般要求调整需求提前1个月,这样可以给云厂商供应链团队时间去备货。
交付:交付是成本管理系统的一个内部概念,并不会暴露给业务团队。需求滚动调整后,会形成采购,采购和需求可能并不是一一对应的关系,或者称为不是直接翻译的关系。具体可能跟很多因素有关,多个业务团队的需求,合并之后形成汇总需求,例如新增20万核。
L1库存:L1库存就是集群内部的未分配资源,也就是1-AR的资源,这部分资源往往可以有一个超卖比例,管理员根据具体情况,可以少采购一部分资源,并分时满足业务的需求。
L2库存:L2库存就是集群外部,但是仍然输入已经交付,在集群管理员手中的资源。例如,不同资源池之间相互的调配。
L3库存:L3库存是云厂商供应链团队已经采购但是仍然在仓库中的资源,这些资源一般是不会暴露给云用户的,如果有良好的合作关系可以协商这部分资源的供应周期。
直接采购:如果L1-L3都无法命中,那就必须走直接采购了,这个周期可能很长,如果是一些异构计算的资源如GPU,可能交付周期高达数月之久。
额度:额度管理是个非常大的话题,也是目前还处于建设阶段的一个能力。很多云产品都是后付费的,不具备按量控制额度的能力,只能是欠费停机。这对于管理员控制成本非常不利。这篇文章不展开讨论额度管理问题,只提供一个大概的思路。对于能控制计算类产品,需要将用户额度和集群额度分离,集群额度是没有任何超卖概念的,但是用户额度可以根据不同的场景进行超卖。
计量:计量信息是账单核对与成本优化的基础,很遗憾我们现在仍然处于在初级阶段,2022年的三个核心能力之一就是提升计量的能力,将业务团队需要的计量字段清洗出来透出给用户。需要单独说几句的就是计量的实时性,一个月出一次账是非常难于优化成本的,我们一般要求云产品的计量周期到一天,做的好的产品可以做到小时级别。另外,计量的历史数据会反馈到下一年的预算预测中。
账单:账单是计量的金额展示,除了计量信息外,还需要账单公式、计费项单价、折扣等信息的参与。
优化:成本优化并不是成本管理必须的环节,优化可以线下协商方案,甚至完全由数据驱动业务方自己负责。但是作为一个成本管理平台,它有更加丰富的数据。一些优化方案可以固定下来,供很多业务方开启使用,让协作成本更低。典型的如文件存储的失效时间建议,冷存储建议等,都可以做成统一方案。
小结:对于大型的云用户来说,云产商提供的控制台能力目前还不能满足成本管理的需求,需要自己管理云产品的生命周期。典型的过程包括:预算-->需求-->交付-->额度-->用量-->账单。把账算清楚,是成本管理系统的天然责任,这一责任因为云产品的众多和分账的复杂性,极难做好,只能慢慢打磨。
FinOps应该做什么
本章总结
超越成本视角
稳定性不可能三角
稳定性是可以通过努力获得的么,为什么有时候觉得做得很好的半年,故障却频繁 我们要不要限制变更,来获取稳定性么 水位跑的高了,是不是稳定性就没有提升的空间
稳定性:故障或者超出系统预期的波动,我们绝大部分稳定性问题的定义都是治标波动(pv/qps/超时率/无结果率/排队时间)超出设定的阈值。集团将故障的影响面+时间,进一步归一化成“故障分”。
资源使用效率:我们这里狭义的限制为cpu/mem/disk等的水位或者使用百分比。也可以从另外角度定义为系统离崩溃的距离,使用效率越高,离崩溃的点越近,我们定义为崩溃距离=1/资源使用效率
迭代速度:不进行任何变更速度为0,按照业务系统自身最高的设计能力做变更为100%的效率(有同学对这句话提出了质疑,我也在考虑如何更好的定义迭代速度,比如需求提出到上线完成的总时间的倒数)。如果不是大的技术架构升级,我们认为一段时间内某个业务系统的迭代最高速度是不变的。
追求稳定性高+资源使用效率高:在资源使用效率高时,对应的崩溃距离就很小。系统可以承受的波动就很小,这时频繁的变更会引入更多的不确定性和波动,偶发的问题就能产生业务上的超时等故障。所以系统使用效率越高,如果还想要追求稳定的情况下,应该降低系统迭代的速度。
追求稳定性高+迭代速度:在迭代速度非常高时,会引入更多的不确定性和波动。如果这时候还要追求很高的稳定性,那么必须给引入的波动留有足够的空间,也就是崩溃距离一定要大,资源使用效率一定不能太高。
追求资源使用率高+迭代速度高:在迭代速度非常高时,会引入更多的不确定性和波动。同时我们还要求资源使用效率高,也就是崩溃距离很小,那么产生稳定性问题的概率必然会上升。
新业务,快速发展期:迭代速度显然是最重要的,三角的另外两端,最多只能选择一个,甚至一个都不选。
中型业务,快速发展期:迭代速度可能仍然是最重要的,稳定性可能是另外一个选择,这时候资源使用效率可能就没那么重要了。
中型业务,平稳发展期:资源使用效率和稳定性的重要性逐渐提升,迭代效率开始让位。
巨型业务,快速发展期:迭代速度和稳定性如果是一个选择,水位要求不能太高了。
巨型业务,平稳发展期:稳定性和水位如果是一个选择,那迭代效率就会逐渐下降。
本章总结
全文总结
引用
[1]TOM KRAZIT,2018,《Dropbox 通过自建基础技术设施在两年内省了差不多 7500 万美元》
[2]李成栋,2017,《ACPU -- 走出CPU利用率误区,重新思考成本问题》
[3]赵熠(川生),2011,与川生师兄的聊天
[4]张敏(七炎),2017,《自动化运维平台Drogo介绍》
[5]杜海斌(双歧),2019,《smaug碎片整理方案》
[6]张敏(七炎),2018,《阿里巴巴搜索无状态服务的秒级弹性调度》
[7]叶良(潇客),2018,《混部解密》
[8]黄城(潇洛),2021,《ASI混部设计》
[9]黄城(潇洛),2022,与潇洛的聊天
[10]张瓅玶(谷朴)、徐国耀(祜休),2022,《业界数据中心利用率调研》
[11]梁啟成(啟成),2021,《资源预算管理的三年实践》
[12]卢占一(十力),2019,《稳定性不可能三角》
参与有奖!GTS云巧乘风者征文大赛
10月10日前投稿GTS云巧乘风者征文活动,获得38元天猫超市卡!(数量有限)文章内容不限于云巧,只要运用了【组装式应用的理念】就可以投稿!更有机会获得888元猫超卡和天猫精灵Sound~
云巧及组装式应用理念是什么?云巧是“组装式应用”理念的落地,助力大家提升交付速度,提高交付质量,降低用工成本。
点击阅读原文查看详情。
微信扫码关注该文公众号作者